1命令请求执行

1.1      发送命令请求

Redis服务器的命令请求来自Redis客户端,当用户在客户端键入一个命令请求,客户端会将这个命令转换成协议格式,然后通过连接到服务器的套接字,将协议格式的命令请求发送给服务器。

1.2      读取命令请求

当客户端与服务器之间连接套接字因为客户端的写入而变得可读的时候,服务器将调用命令请求处理器来执行以下操作:

1)       读取套接字中协议格式的命令请求,并将其保存在客户端状态的输入缓冲区里面。

2)       对输入缓冲区的命令请求进行解析,提取出命令请求中包含的命令参数,以及参数的个数,然后分别将参数和参数个数保存到客户端状态的argv属性和argc属性里面

3)       调用命令执行器,执行客户端指定的命令。

1.3      命令执行

1)       根据客户端的状态的argv[0]参数,在命令表中查找参数所指定的命令,并将找到的命令保存到客户端状态的cmd属性里面。

2)       执行预备操作,确保命令可以正确顺利地执行

3)       调用命令的实现函数

4)       执行后续工作,包括是否添加一条日志、是否需要把执行的命令写入AOF缓冲区等

1.4      命令回复发送给客户端

当命令回复发送完毕之后,回复处理器会清空客户端状态的输出缓冲区,为处理下一个命令请求做好准备。

1.5      客户端接收并打印命令回复

2          serverCron函数

Redis服务器中的serverCron函数默认每隔100毫秒执行一次,这个函数负责管理服务器的资源,并保持服务器自身的良好运转。

2.1      更新服务器时间缓存

Redis服务器中有不少功能需要获取系统的当前时间,而每次获取系统的当前时间都需要执行一次系统调用,为了减少系统调用的执行次数,服务器状态中的unixtime属性和mstime属性被用作当前时间的缓存。

由于serverCron函数默认会以每100毫秒一次的频率更新unixtime属性和mstime属性,所以这两个属性记录的时间精确度并不高:

1)       服务器只会在打印日志、更新服务器的LRU时钟、决定是否执行持久化任务、计算服务器上线时间这类对事件精确度要求不高的功能上。

2)       对于为键设置过期时间、添加慢查询日志这种需要高精度时间的功能来说,服务器还是会再次执行系统调用,从而获得最准确的系统当前时间。

2.2      更新LRU时钟

LRU属性保存了对象最后一次被命令访问的时间。当服务器要计算一个数据库键的空转时间,程序会用服务器的lrulock(保存了服务器的LRU时钟)属性记录的时间减去对象的lru属性记录的时间,得出的计算结果就是这个对象的空转时间。

ServerCron函数默认会以10秒一次的频率更新lrulock属性的值,因为这个时钟不是实时的,所以根据这个属性计算出来的LRU时间实际上只是一个模糊的估算值。

2.3      更新服务器每秒执行命令的次数

ServerCron函数中的trackOperationsPerSecond函数会以每100毫秒一次的频率执行,这个函数的功能以抽样计算的方式,估算并记录服务器在最近一秒钟处理的命令请求数量。

2.4      更新服务器内存峰值记录

2.5      处理SIGTERM信号

2.6 管理客户端资源

ServerCron函数每次执行都会调用clientsCron函数,clientsCron函数会对一定数量的客户端进行以下两种检查:

1)       如果客户端和服务器之间的连接已经超时,那么程序会释放这个客户端

2)       如果客户端在上一次执行命令请求后,输入缓冲区的大小超过了一定的长度,那么程序会释放客户端当前的输入缓冲区,并重现创建一个默认大小的输入缓冲区,从而防止客户端的输入缓冲区耗费太多内存。

2.7      管理数据库资源

 ServerCron函数每次执行都会调用databasesCron函数,这个函数会对服务器中的一部分数据库进行检查,删除其中的过期键。并在需要的时候,对字典进行收缩操作。

2.8 执行被延迟的BGREWRITEAOF

2.9 检查持久化操作的运行状态

2.10 将 AOF缓冲区中的内容写入AOF文件

2.11 关闭异步客户端

2.12 增加cronloops计数器的值

Cronloops属性记录了serverCron函数执行的次数

3      服务器初始化

除了初始化数据结构之外,initServer还进行了一些非常重要的设置操作:

1)       为服务器设置进程信号处理器

2)       创建共享对象,这些对象包含Redis服务器经常用到的一些值

3)       打开服务器的监听端口,并为监听套接字关联连接应答事件处理器,等待服务器正式运行时接受客户端的连接

4)       为serverCron函数创建时间事件,等待服务器正式运行时执行serverCron函数

5)       如果AOF持久化功能已经打开,那么打开现有的AOF文件,如果AOF文件不存在,那么创建并打开一个新的AOF文件,为AOF写入做好准备。

6)       初始化服务器后台I/O模块,为将来的I/O操作做准备。