一.结论
因为redis内部用的是文件事件处理器,文件事件处理器是单线程的,所以redis才叫单线程模型。
Redis采用IO多路复用机同时制监听多个socket,将产生事件的socket压入队列中,事件分派器根据socket上的事件类型选择对应的事件处理器进行处理。
二.文件时间处理器
包括以下4部分:
1.多个socket
2.IO多路复用程序
3.文件分派器
4.事件处理器
多个socket可能对并发产生不同的操作,每个操作对应不同的文件事件,IO多路复用程序会监听多个socket,将产生事件的socket压入队列中进行排队,事件分派器每次会从队列中取出一个socket,根据socket事件类型,交给相应的文件事件处理器进行处理。
三.Redis一次处理过程
发送建立连接的请求(创建通信socket)
1.redis服务端初始化时,将server socket的AE_READABLE事件与连接应答处理器关联
2.客户端socket向Redis进程的server socket请求建立连接
3.此时产生一个AE_READABLE的事件
4.多路复用器监听到事件后,将socket压入队列排队
5.文件分派器从队列中取出socket1事件,并交给连接应答器处理,
6.连接应答器会创建一个与客户端通信的socket1,并将socket1的AE_READABLE事件与命令请求处理器建立关联
发送set/get请求
1.客户端发送一次请求 set/get
2.redis中的一个socket会产生一个AE_READABLE事件
3.IO多路复用,将socket压入队列排队
4.此时,事件分派器从队列中获取到socket的AE_READABLE事件,并交给命令请求处理器来处理
5.命令请求处理器读取socket的操作事件并在自己的内存中完成事件
6.操作完成后,会将此socket的AE_WRITABLE事件与命令回复器进行关联
返回结果
1.redis中的socket1产生一个AE_READABLE事件,
2.将socket1压入队列
3.事件分派器将事件交给命令回复器处理
4.返回执行结果
5.解除socket1事件AE_WRITABLE与命令回复器的关联
下图可以帮助理解:(更详细的内容,可以参考《Redis设计与实现》-- 黄健宏 第二部分第12章节内容)
四.Redis6.0版本
6.0版本开始引入多线程版本,随着业务的发展,说明redis的单线程在某些方面已经不具备优势。因为网络读写的系统调用,在redis占用的大部分CPU的时间,所以把网络读写做成多线程的方式会有很大的性能提升,比如keyDB。
Redis多线程部分只是用来处理网络读写,执行操作部分扔是单线程。之所以不用多线程,是因为多线程复杂,并且需要处理控制事务,网络并发等。
参考书籍:
《Redis设计与实现》-- 黄健宏
强烈推荐redis书籍:《Redis设计与实现》-- 黄健宏