Redis服务器是一个事件驱动的程序,有以下两类事件:
- 文件事件:Redis服务器通过套接字与客户端或者其他的Redis服务器连接,而文件事件就是服务器套接字操作的抽象。与客户端或者其它服务器通信产生相应的文件事件,服务器通过监听处理这些事件来完成一系列的网络通信操作。
- 时间事件:Redis服务器中的一些操作(如serverCron函数)需要在给定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。
时间处理器结构
文件事件Redis基于Reactor模式开发了自己的网络事件处理器,利用IO多路复用程序来监听套接字,当监听到连接应答、读取、写入、关闭等操作是,就会调用对应关联的事件处理器来处理。
文件事件处理器结构文件处理器结构
Redis的事件框架由:I/O多路复用程序、aeMain主线程、事件分派、事件队列等几个核心元素组成,aeMain主线程一直轮询事件队列中就绪的I/O事件,然后通过事件绑定的处理器来处理业务。
文件事件执行过程事件处理的过程
- 服务器接收到客户端发送的建立连接请求
- 多路复用程序产生AE_READABLE事件发送至事件队列
- 连接应答处理器接收到事件,开始创建socket并将AE_READABLE事件与命令请求处理器关联,连接建立成功,等待接收客户端后续操作
- 服务器接收到客户端发送的命令请求
- 多路复用程序产生AE_READABLE事件,发送至事件队列
- 命令请求处理器接收到事件,并从socket中读取出命令信息并开始执行命令,同时将socket的AE_WRITABLE事件与命令回复处理器关联
- 多路复用程序产生AE_WRITABLE事件,并发送至事件队列
- 命令回复处理器接收到事件,开始向socket输出本地操作的执行结果给客户端,将socket的AE_WRITABLE事件与命令回复处理器解除关联
Redis的时间事件分为两种,定时事件:让一个函数在指定的时间之后执行一次;周期性任务:让一个函数每间隔指定时间执行一次;时间事件是基于serverCron函数实现,该函数主要对服务器自身资源和状态检查和调整,确保服务器的长期、稳定运行,具体工作详见本文中事件的调度执行。
事件的调度执行事件的调度执行过程
- apiPoll函数阻塞并等待文件事件产生,该方法避免了服务器对时间事件进行频繁的轮询,该函数有阻塞过期,时间到达立即返回
- 文件事件的到达是随机的,随着文件事件的执行,时间事件的到达时间开始接近,当时间事件执行时间到达后服务器开始执行时间事件
- 文件事件与时间事件都是同步、有序、原子的执行的,整个过程尽量减少阻塞时间,耗时相对久的函数都会设置run_with_period(最大运行时长),当执行耗时比较久的函数时,Redis会采用子线程或子进程的方式来异步处理,比如持久化操作。
- Redis 6.0对processEvents流程进行了优化,引入多线程模型提升eventLoop 处理效率,详见:Redis多线程处理模型
以上就是Redis事件实现机制的介绍,如果各位还想了解更多,欢迎转发评论 关注,Redis图解系列专栏持续更新中。