redis的线程模型
Redis基于Reactor模式开发了文件事件处理器,文件事件处理器包含了4个部分:多个socket,io多路复用程序,文件事件分派器,事件处理器。事件处理器又分为连接应答处理器,命令请求处理器,命令回复处理器,事件处理器是单线程的,但是通过io多路复用可以监听多个socket,实现了高性能的通讯模型。多个socket可能并发不同的事件,但是通过io多路复用程序将不同的事件压入一个队列中,每次从队列中取出一个socket给文件事件分派器。事件分派器把socket给对应的事件处理器,事件处理器处理完成后,io多路服用程序才会将下一个socket从队列中取出给文件事件分派器,文件事件分派器再根据当前socket的事件选择对应的处理器来处理。
客户端与redis的一次通讯流程
- 首先redis服务端进程初始化的时候,会将server socket的AE_READABLE事件与连接应答处理器关联,这里的server socket是专门用来创建客户端与服务端socket连接的特殊socket。
- 客户端socket01像向redis进程的server socket请求建立连接,此时server socket会产生AE_READABLE事件,io多路复用程序监听到事件后会将该socket压入队列中,文件事件分派器从队列中拿到这个socket后交给连接应答处理器,连接应答处理器会建立一个能与该客户端通信的socket,并将该socket的AE_READABLE事件与命令请求处理器关联。
- 假设此时客户端发送了一条 set key value 的请求,此时socket01会产生AE_READABLE事件,io多路复用程序将socket01压入队列,文件事件分派器拿到socket01产生的AE_READABLE事件,由于前面已经将socket01的AE_READABLE事件与命令请求处理器关联,因此文件事件分派器将事件交给命令请求处理器来处理,命令请求处理器读取 socket01 的 key value 并在自己内存中完成 key value 的设置。操作完成后,它会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联。
- 如果此时客户端准备好接收返回结果了,此时socket01会产生AE_WRITABLE事件,同样压入队列,文件事件分派器找到相关的命令回复处理器,由命令回复处理器对socket01写入本次操作的结果,之后解除socket01的AE_WRITABLE事件与命令回复处理器的关联。
为什么单线程的redis效率高
- 由于文件事件处理器是单线程的所以说redis是单线程的
- redis是纯内存操作
- 核心是非阻塞的io多路复用程序
- 单线程避免了多线程频繁的上下文切换问题