Redis中的事件机制

Redis服务器是一个事件驱动程序,服务器需要处理两类事件:文件事件和时间事件。文件事件主要指客户端向服务器发送命令,如连接命令,读命令以及写命令等。时间事件指的是定时执行的任务,如serverCron函数。
一.文件事件
Redis基于Reactor模式开发了自己的网络时间处理器,称为文件事件处理器。文件事件处理器使用I/O多路复用程序同时监听多个套接字,并根据套接字目前执行的任务为套接字关联不同的事件处理器。
虽然文件事件处理器以单线程方式运行,但通过I/O多路复用程序监听多个套接字的方式,文件事件处理器可以实现高性能的网络通信模型。
文件事件处理器由四部分组成,分别是套接字,I/O多路复用程序,文件事件分派器,以及事件处理器。
Redis中的事件机制
每当一个套接字准备好执行连接应答,写入,读取,关闭等操作时,就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。
I/O多路复用程序负责监听多个套接字,并向文件事件分派器传送那些产生了事件的套接字。
尽管多个文件事件可能会并发地出现,但I/O多路复用程序总是会将所有产生事件的套接字都放到一个队列里面,然后通过这个队列,以有序,同步,每次一个套接字的方式向文件事件分派器传送套接字。当上一个套接字产生的事件被吹完毕之后,I/O多路复用程序才会继续向文件事件分派器传送下一个套接字。
二.时间事件
Redis的时间事件分为两类:定时事件和周期性时间。定时事件指程序在指定时间之后执行一次,执行完定时事件就删除了。而周期性事件是程序每隔指定时间就执行一次。
一个时间事件主要由以下三个属性组成:id,服务器为每个时间事件创建的全局唯一ID;when,记录时间事件的到达时间;timeProc,时间事件处理器,一个函数。当时间事件到达时,服务器会调用相应处理器来处理事件。
服务器将所有时间事件都放在一个无序链表中,每当时间事件执行器运行时,就会遍历整个链表,查找所有已到达的时间事件,调用相应的时间处理器。
时间事件的处理大概包括以下几步:
1.遍历链表中的所有时间事件
2.检查时间事件的when是否<=当前时间戳,判断时间事件是否到达
3.执行已到达的时间事件,并取得处理器返回值
4.根据返回值判断是定时事件还是周期事件,如果是定时事件,从链表中删除时间,如果是周期性事件,则更新时间的when属性
三.事件的调度与执行
服务器同时存在文件事件和时间事件两种事件,所以服务器必须对两种事件进行调度,何时处理文件事件,何时处理时间事件。
服务器会循环处理所有事件,首先会获取最近到达的时间事件,然后阻塞等待处理文件事件,最大阻塞时间为最近到达的时间事件,等到最近时间事件已到达的时候,就会处理时间事件。服务器对文件事件和时间事件的处理都是同步,有序,原子的,不会中断时间处理也不会对时间进行抢占,因此服务器处理时间都会尽可能地减少程序阻塞的时间。因为时间事件在文件事件之后执行,并且事件之间不会出现抢占,所以时间事件的实际处理时间通常会比设定的到达时间晚一点。
参考内容:Redis设计与实现-黄健宏