Redis服务器是事件驱动程序,服务器需要处理以下两类事件:

1、文件事件。

Redis服务器通过套接字与客户端或者其他Redis服务器进行连接,而文件事件就是服务器对套接字的抽象。服务器与客户端或其他服务器的通信会产生相应的文件事件,而服务器就是通过监听并处理这些事件来完成网络通信的。

2、时间时间。

Redis服务器中一些操作需要在给定时间点执行,而时间事件就是服务器对这类定时操作的抽象。

文件事件

文件事件处理器采用I/O多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。当被监听的套接字准备好执行连接应答,读取,写入,关闭等操作时,与操作对应的文件事件就会产生,这时文件事件处理器就会根据套接字关联好的事件处理器来处理这些事件。

文件事件处理器的构成

有四个部分:

1、套接字

2、I/O多路复用程序

3、文件事件分派器

4、事件处理器

具体结构如下:

image-20230326145626574

其中,I/O多路复用程序监听多个套接字,并向文件事件分派器传递那些产生事件的套接字。尽管多个文件事件会并发出现,但是I/O多路复用程序总是将所有产生事件的套接字放到一个队列中,然后以有序,同步,每次一个套接字的方式向文件事件分派器传送套接字。

文件事件分派器接受I/O多路复用传过来的套接字,根据套接字产生的事件,传给对应的事件处理器。

I/O多路复用的实现

Redis的I/O多路复用的实现是通过包装select,epoll,evport和kqueue这些I/O多路复用函数库来实现的。

事件的类型

I/O多路复用程序可以监听多个套接字的AE_READABLE和AE_WRITABLE事件。

当套接字变得可读(客户端对套接字执行write或者close操作)或者有新的可应答套接字出现(客户端对套接字执行connect操作),套接字产生AE_READABLE事件。

当套接字变得可写(客户端执行read操作),套接字产生AE_WRITABLE事件。

如果同时产生上面这两种事件,那么会先处理AE_READABLE事件,然后才处理AE_WRITABLE事件。

文件事件的处理器

Redis为文件事件编写了多个处理器,这些处理器分别用于实现不同的网络通信需求。

1、连接应答处理器

当Redis服务器进行初始化的时候,程序会将这个连接应答处理器和服务器套接字的AE_READABLE事件关联起来,当有客户端连接服务器时,套接字就会产生AE_READABLE事件,引发连接应答处理器执行。

2、命令请求处理器

当一个客户端通过连接应答处理器成功连接到服务器后,服务器会将客户端套接字的AE_READABLE事件和命令请求处理器关联起来,当客户端向服务器发送命令请求时,就会产生AE_READABLE事件,引发命令请求处理器执行,并执行相应的套接字读入操作。

3、命令回复处理器

当服务器有命令回复要传送给客户端时,服务器就会将客户端套接字的AE_WRITABLE事件和命令处理器关联起来,当客户端准备好接收服务器传回的命令回复时,就会产生AE_WRITABLE事件,引发相应的套接字写入操作。

image-20230326191604556

时间事件

redis的时间事件分为两种:

1、定时事件:让一段程序在指定的时间之后执行一次。

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

一个时间事件主要由以下三部分组成:

id:服务器为时间事件创建的全局唯一ID(标识号)。

when:记录了时间事件到达时间。

timeProc:时间事件处理器,当时间事件到达时,服务器就会调用相应的处理器来处理事件。

因为存储时间事件的链表并不按照事件排序,所以说每次处理时都需要遍历整个链表,才能找到那些事件需要处理。

参考

《Redis设计与实现》