网络模型篇
# 单线程模型
Redis基于Reactor模式开发的事件处理模型,对应Redis中是其文件事件处理器;
单线程指的是「接收客户端请求->解析请求 ->进行数据读写等操作->发送数据给客户端」这个过程是由一个线程(主线程)来完成的;
文件事件处理器:
- IO多路复用程序监听多个socket(客户端连接);
- 文件事件分派器:将 socket 关联到相应的事件处理器;
- 事件处理器:
- 连接应答处理器(底层使用系统调用 accept 接受来自客户端的新连接);
- 命令请求处理器(解析并执行客户端的请求命令);
- 命令回复处理器(当一次事件循环之后写出缓冲区中还有数据残留,则这个处理器会被注册绑定到相应的连接上,等连接触发写就绪事件时,它会将写出缓冲区剩余的数据回写到客户端);
为什么使用单线程?
- 单线程编程容易并且更容易维护;
- Redis 的大部分操作都在内存中完成,并且采用了高效的数据结构,因此 Redis 瓶颈可能是机器的内存或者网络带宽,而并非 CPU,既然 CPU 不是瓶颈,那么自然就采用单线程的解决方案了;
- 多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能( Redis 不仅仅提供了简单的 key-value 数据结构,还有 list、set 和 hash 等等其他丰富的数据结构,而不同的数据结构对同步访问的加锁粒度又不尽相同,可能会导致在操作数据过程中带来很多加锁解锁的开销,增加程序复杂度的同时还会降低性能);
# 单线程怎么监听大量客户端连接?
通过IO多路复用来监听来自客户端的大量的连接;
# Redis6.0之后引入多线程?
默认关闭;
单线程:CPU 通常不会成为性能瓶颈,瓶颈往往是内存和网络,因此单线程足够了;
多线程:Redis 的网络 I/O 瓶颈已经越来越明显;
Redis 的多线程只是在网络数据的读写这类耗时操作上使用了,执行命令仍然是单线程顺序执行,没有线程安全问题。
网络IO优化方案:
- 零拷贝
- 利用多核优势