redis-线程模型
文件事件处理器
- redis基于reactor模式开发了自己的网络事件处理器:文件事件处理器
- 文件事件处理器使用I/O多路复用来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器
- 当被监听的套接字准备好执行连接应答、读取、写入、关闭等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会套用套接字之前关联好的事件处理器来处理这些事件
- 文件事件处理器以单线程方式运行,但通过使用I/O多路复用程序来监听多个套接字,文件事件处理器既实现了高性能的网络通信模型,又可以很好的与redis服务器中其他同样以单线程方式运行的模块进行对接,这保持了redis内部单线程设计的简单性
组成
文件事件处理器的组成部分:
- 多个socket
- IO多路复用程序:持续监听消息
- socket队列
- 文件事件分配器:因为它是单线程的,而redis基于它工作,所以说redis是单线程的
- 事件处理器:由连接应答处理器(将事件与命令请求处理器关联)、请求命令处理器(执行客户端命令)、命令回复处理器(接触时间和处理器的关联)组成
流程
- 客户端请求redis的server socket并建立连接,此时server socket生成AE_READABLE事件,IO多路复用程序监听到server socket产生的事件,并将该事件压入socket队列
- 文件时间分配器从socket队列中拉取事件交给连接应答处理器,处理器同时生成一个与客户端通信的socket01,并将socket01的AE_READABLE事件与命令请求处理器关联
- 此时客户端发送一个命令请求,redis的scoket01接收到AE_READABLE事件,IO多路复用程序监听到事件,将事件压入socket队列,文件分配器取到事件,由于socket已经和命令请求处理器关联,所以命令请求处理器开始执行命令,完毕后会将redis的scoket01的AE_WAITABLE事件关联到命令回复处理器
- 如果此时客户端准备好了接收返回结果了,向redis中的socket01发起询问请求,那么redis中的socket01会产生一个AE_WRITABLE事件,同样压入socket队列中,事件分配器找到相关联的命令回复处理器,由命令回复处理器对socket01输入本次操作的一个结果,birok,之后解除socket01的AE_WRITABLE事件与命令回复处理器的关联
多路复用IO
Linux下的select、poll、epoll就是干这个的。
将用户的socket对应的fd注册daoepoll,然后epoll帮你监听哪些socket上有消息到达,这样就避免了大量的无用操作。
此时的socket应该采用非阻塞模式。这样,整个过程只有在调用select、poll、epoll这些调用的时候才会阻塞,收发客户消息是不会阻塞的,整个进程或者线程就被充分利用起来了,就就是事件驱动,所谓的reactor模式。