Redis11:事件

事件

redis服务器是一个事件驱动程序,服务器需要处理以下两类事件:文件事件和时间事件。

文件事件是服务器对套接字操作的抽象,是服务器和客户端通信产生的操作;时间事件是服务器需要在给定的时间点执行的操作。

文件事件

文件事件处理器有四个组成部分,分别是套接字、I/O多路复用程序、文件事件分派器以及事件处理器:

I/O多路复用程序负责监听多个套接字,并向文件事件分派器传送产生了事件的套接字。在I/O多路复用程序向文件事件分派器传送套接字的过程中,是通过一个队列来完成的,所以尽管可能产生多个并发的文件事件,但是队列总是通过有序的、每次一个套接字的方式传送给文件事件分派器,然后对应的事件处理器处理完毕之后,I/O多路复用程序才会继续向文件事件分派器传送下一个套接字:

事件处理器中比较常用的几种包括:连接应答处理器(服务器初始化时会用到)、命令请求处理器、命令回复处理器。

时间事件

redis的时间事件分为以下两类:定时事件(指定的时间执行一次)和周期性事件(隔一段时间就执行一次)。

一个时间事件由以下三个属性组成:事件事件的全局ID(事件越新ID号越大)、记录了到达时间的毫秒时间戳when、时间处理器timeProc(事件处理时要执行的函数)。

如果时间处理器返回一个整数值,就说明该事件为周期性事件,这个整数值实际上就是周期,此时服务器会根据这个整数值对时间戳进行更新,让这个时间事件在一段时间后再次到达。

服务器将所有时间事件放在一个无序链表中,每当时间事件执行器执行时,它就遍历整个链表查找所有已达到的时间事件并执行响应的事件处理器:

这个链表会按照ID排序,无序指的是它不会按照when来排序,即使redis采用这种方式也不会有性能问题,因为redis服务器正常只有serverCron一个时间事件,在benchmark模式下也只使用两个时间事件,链表几乎退化成了指针。

将一个新的时间事件添加到服务器的函数为aeCreateTimeEvent,它接受一个毫秒数和一个时间处理器,意味着过了一段时间后执行对应的时间处理器。

serverCron函数

它是redis最重要的一个时间事件,它的主要工作包括:

1、更新服务器的各类统计信息

2、清理数据库的过期键值对

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

4、尝试进行AOF和RDB持久化

5、如果服务器是主服务器则会对从服务器进行定期同步

6、如果处于集群模式,它会对集群进行定期同步和连接测试

在redis2.6版本,serverCron函数每秒运行10次,平均每间隔100毫秒运行一次。可以通过修改配置文件中的hz选项来调整这个值。

事件的调度和执行

服务器需要同时对文件事件和时间事件两种事件进行调度,决定何时处理事件。

整个调度的过程可以用下列流程图表示:

redis服务器会计算具体现在最接近的时间事件,然后阻塞一定的时间,在阻塞的过程中如果有文件事件到达则处理该文件事件,处理结束后继续阻塞,直到预计的时间事件到达然后执行该时间事件。阻塞是为了避免服务器对时间事件进行频繁的轮询。

这些事件的处理都是同步、有序、原子地进行的,不会中途中断某事件,也不会对事件进行抢占,服务器会尽可能减少程序的阻塞时间。

有时会出现这样的情况,在预计的时间事件到达之前,会出现一个文件事件,执行这个文件事件稍微花了一些时间,导致时间事件比预计的要晚一些执行,如下面这种情况:

原文地址:https://www.cnblogs.com/yinyunmoyi/p/11523738.html