【Redis学习笔记(十)】之 Redis服务器详解

本文章由公号【开发小鸽】发布!欢迎关注!!!


老规矩–妹妹镇楼:

一. 服务器

(一) 概述

        服务器负责与多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。

(二) 命令请求过程

1. 客户端向服务器发送命令请求

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


2. 读取命令请求

        连接套接字因为客户端的写入变得可读时,服务器将调用命令请求处理器来读取套接字中命令请求,保存到客户端状态的输入缓冲区中;
        对命令请求分析,取出命令名称,参数,个数,保存到argv, argc属性中;
        调用命令执行器,执行客户端指定的命令。


3. 命令执行器

(1) 查找命令实现

        根据命令名称到命令表中查找命令,将找到的命令保存到客户端状态的cmd属性中,每个命令实现结构redisCommand记录了命令的实现信息。


(2) 执行预备操作

        在真正执行命令之前,还需要执行一些预备操作,如检查cmd指针是否为NULL,检查参数个数,检查客户端的身份验证等等。


(3) 调用命令的实现函数

        执行命令的实现函数,需要一个指向客户端状态的指针作为参数,然后会产生相应的命令回复,这些回复会被保存到客户端状态的输出缓冲区中,之后实现函数还会为客户端的套接字关联命令回复处理器,负责将命令回复返回给客户端。


(4) 执行后续工作

        慢查询日志,AOF持久化,如果是主从模式,则将刚刚执行的命令传播到所有的从服务器。在这之后,服务器就可以继续从文件事件处理器中取出并处理下一个命令请求了。


4. 将命令回复发送给客户端

        命令回复会被保存到客户端的输出缓冲区中,并为客户端的套接字关联命令回复处理器,当客户端套接字变为可写状态时,服务器就会执行命令回复处理器,将保存到客户端输出缓冲区中的命令回复发送给客户端,发送完毕,回复处理器会清空输出缓冲区。


5. 客户端接受并打印

        客户端接受到协议格式的命令回复之后,会转换为人类可读格式并打印出来。


(三) serverCron函数

1. 概述

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


2. 更新服务器时间缓存

        Redis服务器中有很多功能需要获取系统的当前时间,但是系统调用比较费时,因此为了减少系统调用的执行次数,服务器状态中的unixtime属性和mstime属性被用作当前时间的缓存。unixtime为秒精度的,mstime为毫秒精度的,serverCron函数默认以100毫秒的频率更新两个属性,所以他们的精确度不高。只用在对于精确度要求不高的功能上,如打印日志,更新服务器的LRU时钟。

3. 更新LRU时钟

        服务器状态中的lruclock属性保存了服务器的LRU时钟,都是服务器时间缓存的一种,默认以10s更新一次,用于计算键的空转时间,因为每个Redis对象都有一个lru属性保存着对象最后一次被命令访问的时间,该对象的空转时间由lruclock减去lru属性即可得到。

4. 管理客户端资源

        对客户端进行检查,如连接超时(很长时间没有互动操作),如输入缓冲区超过了一定大小,则释放客户端当前的输入缓冲区,创建一个新的输入缓冲区。


5. 写入AOF

        如果AOF缓冲区中还有待写入的数据,那么将会被写入到AOF文件中。


(四) 初始化服务器

1. 概述

        一个Redis服务器从启动到接受客户端的命令请求,需要经过初始化和设置过程,如初始化服务器状态,接受用户指定的服务器配置,创建相应的数据结构和网络连接。

2. 初始化服务器状态结构

        创建一个redisServer类型的实例变量server作为服务器的状态,并为结构中的各个属性设置默认值,初始化工作由initServerConfig函数完成,如设置服务器的运行ID,默认配置文件路径,默认端口号,默认RDB和AOF,创建命令表等等,除了命令表,initServerConfig函数没有创建服务器状态的其他数据结构。


3. 载入配置选项

        用户可以通过指定配置文件来修改服务器的默认配置,载入用户的配置参数和配置文件。


4. 初始化服务器数据结构

        初始化服务器状态结构中的其他数据结构,如clients链表,保存连接的客户端状态,db数组,保存服务器的所有数据库,指定lua脚本的LUA环境lua等等。服务器将会调用intiServer函数,为这些数据结构分配内存,还有一些设置操作,如为服务器设置进程信号处理器,创建共享对象,如常用的字符串对象,整数1-10000,打开服务器的监听端口,当initServer函数执行完毕,服务器将用ASCII字符在日志中打印出Redis图标,以及Redis版本信息。


5. 还原数据库状态

        在完成对服务器状态的初始化之后,服务器需要载入RDB文件或者AOF文件,还原数据库状态,优先载入AOF文件,然后是RDB文件,完成之后在日志中打印消耗的时间。


6. 执行事件循环

        初始化最后一步,服务器打印6379端口可用,并开始执行服务器的事件循环,现在服务器可以接受客户端的连接请求了。

猜你喜欢

转载自blog.csdn.net/Mrwxxxx/article/details/114239726