理解Redis的反应堆模式
1. Redis的网络模型
为什么要使用Reactor模式呢?
Redis如何实现自己的Reactor模式?
2. Reactor模式的背景
epoll/kqueue将收集到的可读写事件全部放入队列中等待业务线程的处理,此时线程池的工作线程拿到任务进行处理,实际场景中可能有很多种请求类型,工作线程每拿到一种任务就进行相应的处理,处理完成之后继续处理其他类型的任务;
工作线程需要关注各种不同类型的请求,对于不同的请求选择不同的处理方法,因此请求类型的增加会让工作线程复杂度增加,维护起来也变得越来越困难;
3. Reactor模式
Java NIO
Netty
libevent/libuv
Redis
handle 可以理解为读写事件 可以注册到Reactor进行监控
Sync event demultiplexer 可以理解为epoll/kqueue/select等作为IO事件的采集器
Dispatcher 提供注册/删除事件并进行分发,作为事件分发器
Event Handler 事件处理器 完成具体事件的回调 供Dispatcher调用
Concrete Event Handler 具体请求处理函数
4. Redis的Reactor实现
Redis的IO复用的选择
#ifdef HAVE_EVPORT
#include "ae_evport.c"
#else
#ifdef HAVE_EPOLL
#include "ae_epoll.c"
#else
#ifdef HAVE_KQUEUE
#include "ae_kqueue.c"
#else
#include "ae_select.c"
#endif
#endif
#endif
Redis的任务事件队列
Redis事件分派器
AE_READABLE 客户端写数据、关闭连接、新连接到达
AE_WRITEABLE 客户端读数据
特别地,当一个套接字连接同时可读可写时,服务器会优先处理读事件再处理写事件,也就是读优先。
Redis事件处理器
连接应答处理器:实现新连接的建立
命令请求处理器:处理客户端的新命令
命令回复处理器:返回客户端的请求结果
复制处理器:实现主从服务器的数据复制
Redis C/S一次完整的交互
5.参考资料
https://www.cnblogs.com/xudong-bupt/p/9463804.html
https://www.s0nnet.com/archives/deep-understanding-of-reactor-design-patterns
https://cloud.tencent.com/developer/article/1345064
https://tech.meituan.com/2016/11/04/nio.html
往期精彩:
理解Redis持久化
Linux中的各种锁及其基本原理
浅析CPython的全局解释锁GIL
浅谈Linux下Socket选项设置
深入理解IO复用之epoll