很多人学 Redis 学到后面,会听到一句话:
Redis 单线程瓶颈很多时候不在执行命令,而在网络 I/O,I/O 会吃掉主线程时间。
然后你脑子里立刻冒出一个大问号:
- “I/O 不是异步的吗?Redis 不是用 epoll 吗?”
- “既然是异步/非阻塞,那主线程不就不会被卡住吗?”
- “那所谓 I/O 吃时间,到底吃在什么地方?read/write 不是一下子就返回吗?”
- “到底是网络慢,还是 CPU 忙?忙在啥?”
这篇文章就用大白话把这事讲透:
Redis 的 I/O 确实是非阻塞+多路复用,但‘非阻塞’不等于‘不耗时间’。主线程不一定被“堵住”,但它会被“忙死”。时间主要花在:系统调用、内存拷贝、协议解析/序列化、连接管理、以及大包写回的反复尝试。
1. 先把“异步”这词掰开:你以为的异步 vs Redis 用的异步
1.1 你以为的“异步”
很多人理解的异步是:
“我发起 I/O 之后就不用管了,等它自己完成,完成了再通知我。期间 CPU 完全不用干活。”
这更像 Windows 的 IOCP、Linux 的 io_uring(某些模式)、或者 DMA + 回调那种“真·异步 I/O”。