Redis事件驱动模型
事件分类
- 文件事件:socket操作的抽象,如redis服务器与客户端或其他服务器的通信事件
- 时间事件:redis定时事件及周期事件,包括备份、服务器状态检查等
文件事件处理器
基于Reactor模式实现网络通信
采用Reactor模式实现网络通信的包括java nio, netty,redis等。
redis文件事件处理器
- socket队列
- io多路复用程序:一个线程,用于监听socket队列中的socket事件。监听到事件后,将事件以有序、每次一个地顺序发送给事件分发器
- 事件分发器:根据事件关联的处理器,将事件交给处理器执行
- 事件处理器:
- 连接应答处理器:处理socket连接
- 命令请求处理器:处理客户端请求,并执行
- 命令回复处理器:将命令回复发送给客户端
redis文件事件处理流程
def processFileEvents():
1. 注册(serverSocket, ae_acceptable, 连接应答handler)
2. 获取就绪socket事件
socketEvents = select();
3. 将事件分发给任务处理器
for socketEvent in socketEvents:
if socketEvent is ae_acceptable:
// 创建客户端socket,并初始化客户端状态
clientSocket = requestHandler.handle(socketEvent);
注册(clientSocket, ae_readable, 命令请求handler);
elif socketEvent is ae_readable:
// 读取、解析客户端命令并执行,将命令回复保存到客户端数据结构中?
String commandRes = 命令请求handler.handle(socketEvent);
注册(clientSocket, ae_writable, 命令回复handler);
elif socketEvent is ae_writable:
// 将命令回复写入clientSocket
命令回复handler.handle(clientSocket);
取消关联(clientSocket, ae_writable, 命令回复handler);
时间事件处理器
- redis将时间事件放到无序链表中,每当一个事件发生时,将事件插入链表开头
- 处理器遍历链表,取出时间已到达的事件,调用事件处理器
redis事件调度模型
def processEvents():
// 通过最近的时间事件计算poll操作阻塞的时长
timeval = getTimevalByNearestTimer();
aeApiPoll(timeval);
processFileEvents();
processTimeEvents();
- redis通过最近的时间事件计算poll操作阻塞的时长的好处:
- 防止长时间阻塞时间事件
- 避免服务器频繁轮询时间事件
redis事件处理模型的特点
- 对所有事件的处理都是同步、有序、原子性、非抢占的
- 为了防止处理耗时长的事件导致其他事件饿死,需要尽可能地减少事件处理阻塞时间,在有需要的时候主动让出执行权,或将耗时操作放到子进程中异步执行。
Reactor网络通信模型
- reactor概念
- 与proactor区别
- http://xmuzyq.iteye.com/blog/783218
- https://blog.csdn.net/caiwenfeng_for_23/article/details/8458299
reactor使用场景分析
- reactor优点
- reactor缺点