为什么Redis是单线程却仍能有10w/秒的吞吐量?
- 内存操作:Redis大部分操作都在内存中完成,并且采用了高效的数据结构,因此Redis的性能瓶颈可能是机器的内存或者带宽,而非CPU,既然CPU不是瓶颈,自然就采用单线程解决方案了。
- 避免多线程竞争:省去了多线程切换带来的性能开销,且不会导致死锁问题。
- I/O多路复用机制:使用select/epoll机制。在操作系统内核中同时监听所有socket事件的发生。
Redis哪些地方使用了多线程?
Redis单线程指的是:
- 接收客户端请求
- 解析请求
- 进行数据读写等操作
- 返回数据给客户端
但Redis程序并不是单线程,Redis在启动时会启动后台线程(BIO模型)
- 2.6版本后,启动两个后台线程,分别处理关闭文件和AOF刷盘
- 4.0版本后,新增一个后台线程,用来异步释放Redis内存,也就是lazyfree线程。例如执行unlink line/flushdb async等命令,会将这些删除操作交给后台线程来执行,好处是不会导致Redis主线程卡顿。我们应该使用unlink命令来异步删除大Key,因为del在主线程中执行,删除大Key是会导致阻塞。
- 总而言之,多线程体现在后台线程中,如关闭文件、AOF刷盘、释放内存等耗时任务都是通过后台线程来处理的,后台线程相当于消费者,生产者将耗时任务丢到任务队列中即可,消费者则不断轮询该队列处理任务。

- 6.0版本后,Redis采用了多个I/O线程来处理网络请求,因为随着网络硬件的性能提升,Redis的性能瓶颈可能会出现在网络I/O(连接建立、请求读取、写入)上。但多线程仅仅用于网络I/O,执行命令依然使用单线程进行。
- 网络I/O多线程:只针对发送响应数据(write client socket),并不会以多线程的方式处理读请求(read client socket),除非在配置文件中更改。
单线程网络模型的缺陷:
- 无法利用多核CPU的性能。
- 业务处理时,整个进程时无法处理其他socket事件的,若业务(包括网络I/O)耗时较长就会导致阻塞。