Redis(高阶篇)01章——单线程 VS 多线程(入门篇)
一、面试题
- redis到底是单线程还是多线程?
- IO多路复用听说过吗?
- redis为什么这么快?
二、Redis为什么选择单线程
(1)是什么

(2)why
2.2.1厘清一个事实我们通常说,Redis是单线程究竟何意


2.2.2请说说演进变化情况?
(1)Redis3.X单线程时代但是性能依旧很快的主要原因?
- 基于内存操作:Redis 的所有数据都存在内存中,因此所有的运算都是内存级别的,所以他的性能比较高
- 数据结构简单:Redis 的数据结构是专门设计的,而这些简单的数据结构的查找和操作的时间大部分复杂度都是 0(1),因此性能比较高
- 多路复用和非阻塞 I/O:Redis使用 I/O多路复用功能来监听多个 socket连接客户端,这样就可以使用一个线程连接来处理多个请求,减少线程切换带来的开销,同时也避免了 I/O 阻塞操作
- 避免上下文切换:因为是单线程模型,因此就避免了不必要的上下文切换和多线程竞争,这就省去了多线程切换带来的时间和性能上的消耗,而且单线程不会导致死锁问题的发生
(2)作者原话,官网证据
- 官网:https://redis.io/docs/getting-started/faq/
- Redis4.0之前一直采用单线程的主要原因有以下三个:
- 使用单线程模型是 Redis 的开发和维护更简单,因为单线程模型方便开发和调试
- 即使使用单线程模型也并发的处理多客户端的请求,主要使用的是IO多路复用和非阻塞IO
- 对于Redis系统来说,主要的性能瓶颈是内存或者网络带宽而并非 CPU
三、既然单线程这么好,为什么逐渐又加入了多线程特性?
(1)单线程也有单线程的苦恼
(2)如何解决
3.2.1使用惰性删除可以有效地避免Redis卡顿的问题



3.2.2案例
3.2.3在Redis 4.0 就引入了多个线程来实现数据的异步惰性删除等功能,但是其处理读写请求的仍然只有一个线程,所以仍然算是狭义上的单线程
四、redis6/7的多线程特性和IO多路复用入门篇
(1)对于Redis主要的性能瓶颈是内存或者网络带宽而并非 CPU
(2)所以Redis的瓶颈可以初步定为:网络IO
4.2.1redis6/7,真正多线程登场


4.2.2主线程和IO线程怎么协作完成请求处理的-精讲版




(3)Unix网络编程中的五种IO模型
4.3.1Blocking IO—阻塞IO
4.3.2NoneBlocking IO—非阻塞IO
4.3.3IO multiplexing—IO 多路复用
(1)Linux世界一切皆是文件
- 文件描述符,简称FD,句柄
- File Descriptor:
(2)首次浅谈IO多路复用,IO多路复用是什么

(3)场景体验,说人话引出epoll
- 场景解析:
- IO多路复用模型,简单明了版理解:
(4)小总结
只使用一个服务端进程可以同时处理多个套接字描述符连接
(5)面试题:redis为什么这么快
4.3.4signal driven IO—信号驱动IO
4.3.5asynchronous IO—异步IO
(4)简单说明
- Redis工作线程是单线程的,但是,整个Redis来说,是多线程的
- 主线程和IO线程怎么协作完成请求处理的-精简版
- 结论:
五、Redis7默认是否开启了多线程?
- 如果你在实际应用中,发现Redis实例的CPU开销不大但吞吐量却没有提升,可以考虑使用Redis7的多线程机制,加速网络处理,进而提升实例的吞吐量
- 在Redis6.0及7后,多线程机制默认是关闭的,如果需要使用多线程功能,需要在redis.conf中完成两个设置
- 总结: