Redis 事件(2) -- 时间事件

Redis时间事件分为以下两类: 

1.定时事件:程序在指定时间执行一次。 

2.周期性事件:程序每隔指定时间执行一次。 


时间事件的属性:

1.id:服务器为时间事件创建的全局唯一ID,ID号从小到大递增。

2.when:毫秒精度的unix时间戳,记录时间事件的到达时间。

3.timeProc:时间事件处理器,一个函数。当时间事件到达事,执行此函数。


时间事件的返回值决定了时间事件类型,如返回ae.h/AE_NOMORE,表示事件为定时事件,到达一次后则删除;如返回一个非AE_NOMORE的整数,表示事件为周期性事件,当事件到达之后,服务器会根据返回值更新时间事件的when属性,并以这种方式一直更新下去。当前Redis版本中只有周期性事件,没有使用定时事件。

实现:

服务器将所有时间事件都存放在一个无序列表中,每当时间事件执行器执行时,它就遍历整个链表,找到所有已到达的时间事件并调用相应事件处理器。这里的的无序链表,指的是不按when属性大小排序,其实是按ID排序了,新的时间事件总是插入链表的表头。当前Redis版本中,服务器只使用serverCron一个时间事件,而在benchmark模式下,服务器也只使用2个时间事件,所以使用无序链表来保存时间事情,并不影响性能。


serverCron函数:

此函数定期对Redis服务的资源和状态进行检查和调整,由redis.c/serverCron执行,工作包括:

1.更新服务器各类统计信息,如时间、内存占用、数据库占用等等。

2.清理数据库中的过期键值对。

3.关闭和清理连接失效的客户端。

4.尝试进行AOF和RDB持久化操作。

5.如果当前服务器是主服务器,需要对从服务器进行定期同步。

6.如果出于集群环境,需要对集群进行定期同步和连接测试。


事件调度伪代码:

def aeProcessEvents():

#获取到达时间离当前时间最接近的时间事件

time_event = aeSearchNearestTimer()

#计算最接近的时间事件距离到达还有多少毫秒

remain_ms = time_event.when - unix_ts_now()

#如果事件已到达,那么remain_ms 值可能为负数,置为0

if remain_ms < 0:

remain_ms = 0

#根据remain_ms值,创建timeval结构

timeval = create_timeval_with_ms(remain_ms)

#阻塞并等待文件事件产生,最大阻塞时间由传入的timeval结构决定

#如果remaind_ms值为0,那么aeApiPoll调用之后马上返回,不阻塞

aeApiPoll(timeval)

#处理所有已产生的文件事件

processFileEvents()

#处理所有已到达的时间事件

processTimeEvents()





你可能感兴趣的:(Redis设计与实现学习笔记)