Redis 事件

Redis服务器是一个事件驱动程序,服务器需要处理下面两种事件:
1、文件事件:服务器与客户端的通信会产生相应的文件事件,服务器通过监听并处理这些事件来完成一系列网络通信操作。
2、时间事件:Redis服务器中的一些操作需要在给定的时间点执行,服务器监听时间事件来完成一些定时操作

一、文件事件

Redis基于Reactor模式实现了 文件事件处理器
1、文件事件处理器使用 I/O多路复用程序 同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器
2、当被监听的套接字准备执行accept、read、write、close等操作时,与操作相关的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

文件事件处理器是以单线程方式执行的。

文件事件处理器的结构入如下图所示:
Redis 事件
文件事件是对套接字操作的抽象,各种不同的套接字操作统称为 文件事件
I/O多路复用程序 将所有产生事件的套接字都放到一个 队列 里面,然后通过队列有序、同步地、一次一个套接字的向 分派器 传送套接字。当上一个套接字被处理完毕之后才会传送下一个套接字。

服务器会给不同的套接字关联不同的 事件处理器(服务器中的处理函数),因此服务器得到一个套接字时,服务器就知道该执行什么动作。

I/O多路复用程序的实现

Redis为每个I/O多路复用函数库都实现了相同的API,所以Redis在编译时自动选择系统中性能最高的I/O多路复用函数库作为I/O多路复用程序的底层实现。

I/O多路复用程序可以监听多个套接字的 READABLE 事件和 WRITABLE 事件。
当套接字变为 可读(客户端对套接字执行write和close)
或者有 新的可应答套接字出现(客户端执行connect) 时,套接字产生 READABLE 事件。

服务器可以同时监听套接字的 READABLE 事件和WRITABLE事件,如果一个套接字同时产生了这两种事件,文件事件分派器会优先处理READABLE事件,处理完后再处理WRITABLE事件。
也就是说,如果一个套接字可读又可写,那么服务器会 先读套接字,后写套接字

文件事件处理器

(1)连接应答处理器
Redis程序会将连接应答处理器和套接字的READABLE事件关联起来,当 客户端用了connect函数连接服务器套接字的时候,套接字就会产生READABLE事件,这时候连接应答处理器就会执行并作出应答。Redis客户端与Redis服务器的连接是通过连接应答处理器完成的

(2)命令请求处理器
当Redis客户端和Redis服务器连接之后,服务器就会将客户端套接字的READABLE事件和命令请求处理器关联起来。
当客户端向服务器发送请求的时候(比如发送一个查询指令)时,客户端套接字就会产生READABLE事件,这时命令请求处理器会执行,并执行相应套接字读入操作。
(3)命令回复处理器
当服务器有命令回复需要传送给客户端的时候,服务器会将客户端套接字的WRITABLE事件与命令回复处理器关联起来,当客户端准备好接收来自服务器的回复命令时,就会产生WRITEABLE事件,这时命令回复处理器执行并执行相应的套接字写入操作。

(4)案例:
假设一个Redis服务器正在运行,并且没有任何客户端与其连接,那么这个服务器监听套接字的READABLE事件应该处与监听状态下。
(连接阶段)
如果突然有一个Redis客户端向服务器发起连接(connect),那么监听套接字将产生READABLE事件,该事件会触发 连接应答处理器 执行,它将建立服务器与客户端的连接。
连接建立之后,连接应答处理器还会将客户端套接字的READABLE事件与命令请求处理器关联起来,这样命令请求处理器就能使服务器响应客户端的请求信息了。
(请求阶段)
接下来,如果前面那个Redis客户端向服务器发送了一个查询命令,那么客户端套接字会产生READABLE事件,这时命令请求处理器会执行并读取客户端的命令内容,然后它将内容传给相关函数去执行,这会得到一个结果。
(接收服务器的回复信息)
然后服务器得想办法将结果信息回复给客户端。因此,服务器将客户端套接字的WRITABLE事件和命令回复处理器关联起来,当客户端能够读取回复命令的时候,套接字触发WRITABLE事件,这时命令回复处理器将回复命令写入套接字传送到客户端,这样客户端就收到了回复信息。

事件执行流程

下图是事件处理角度下服务器的运行流程
Redis 事件