七、redis服务器
七、redis服务器
一条命令的执行流程
用户向客户端输入一条redis命令,客户端将命令转换成协议格式,将协议格式的命令请求通过连接到服务器的套接字发送给服务器;
服务器接收到redis客户端发送的协议格式的命令请求后,将其保存在对应客户端状态redisClient结构中的query_buf输入缓冲区中;
服务器分析输入缓冲区中的命令请求,将得到的命令名称、命令参数、命令参数个数保存在redisClient结构中的argv、argc属性中;
调用命令执行器,执行客户端指定的命令:
根据argv数组中的第一个元素,在命令表中找到对应的命令实现函数。命令表是一个字典,字典中的每一个键对应命令的名称,字典中的每一个值都是一个指向redisCommand结构的指针;
执行命令之前的准备事项:
检查cmd指针的值是否为NULL;
检查cmd指向的redisCommand结构中的artiy值是否与argc值相同;
如果服务器开启了maxMemory选项,检查内存占用情况,确保接下的命令能够被顺利执行;
将接下来的执行的命令请求发送给所有监视器;
检查客户端是否通过了身份验证;
调用命令实现函数,执行命令;
执行命令之后的收尾动作:
更新该命令的总消耗时长,总执行次数等信息;
如果服务器开启了慢查询日志功能,慢查询日志模块需要检查是否有必要为刚才执行的命令请求生成一条慢查询日志;
如果服务器开启了AOF持久化功能,AFO持久化模块需要刚才执行的命令追加到AOF缓冲区中;
如果服务器处于复制模式,且以主服务器模式运行,需要将刚才执行的命令发送给所有的从服务器;
serverCron
更新服务器时间缓存unixtime、mstime;
服务器只有在执行输出打印日志、更新lrulock、决定是否执行持久化操作这类对时间精度要求不高的任务时,才会使用到unixtime、mstime;
服务器在执行添加慢查询日志、为键设置过期时间这类对时间精度要求更高的任务时,仍然会再次执行系统调用,获取最精确的时间戳;
更新服务器lruLock;
默认每十秒更新一次,结合对象redisObject结构中的lru属性计算对象的空转时长;结合客户端redisClient结构中的last_instersection_time计算客户端空转时长;
更新服务器最近一秒执行命令次数;
按照一定的算法抽样估算服务器最近一秒执行命令的次数;
更新服务器内存峰值记录;
处理SIGTERM信号;
redis服务器在启动时,为服务器进程SIGTERM信号关联信号处理器sigtermHandler函数,该函数的作用是在接收到服务器发送的SIGTERM信号时,将服务器状态redisServer结构中的shutdown_asap标识设置为1;
serverCron函数每次执行时,都会检查shutdown_asap标识的值;如果为0,不做任何操作;如果为1,立即关闭这个服务器;
管理客户端资源;
serverCron函数执行时,会调用clientsCron函数对连接到服务器的所有客户端进行两项检查:
1.如果服务器与客户端的连接已经超时,则断开与客户端的连接;
2.如果服务器在处理客户端上一个命令请求时生成的输入缓冲区过大,将输入缓冲区释放,并重新创建一个固定大小的空白缓冲区分配给该客户端;
管理数据库资源
serverCron函数执行时,会调用activeExpireCycle函数,该函数的作用是分多次遍历服务器中的各个数据库,按照算法抽取一部分数据库键进行过期检查,将过期键删除;
执行被延迟的BGREWRITEAOF命令;
服务器在执行BGSAVE命令期间,接收到客户端发送的BGREWRITEAOF命令会被阻塞挂起;
检查持久化操作的运行状态;
服务器状态redisServer结构中的rdb_child_pid、aof_child_pid分别表示执行BGSAVE、BGREWRITEAOF命令时生成的子进程id,用于检查BGSAVE命令或BGREWRITEAOF命令是否正在被执行;
如果rdb_child_pid、aof_child_pid中有一个属性的值不为-1,就会执行一次wait3函数,检查子进程是否有信号发送给当前服务器进程;
如果有信号到达,证明新的RDB文件或新的AOF文件已经生成,就需要用新文件代替旧文件;
如果没有信号到达,证明持久化操作尚未完成,则不做任何操作;
如果rdb_child_pid、aof_child_pid的值均为-1,则执行以下三项检查:
检查是否有被延迟的BGREWRITEAOF命令,如果有,触发该命令的执行;
检查save选项所设置的保存条件是否满足,如果满足且没有正在执行持久化操作,则触发BGSAVE命令的执行;
检查AOF重写条件是否满足,如果满足且没有正在执行持久化操作,则触发BGREWRITEAOF命令的执行;
关闭异步客户端;
服务器处理客户端发送的命令请求时生成的输出缓冲区超过硬性限制的大小,或在规定的时间内始终超出软性限制的大小,客户端会被关闭;
将redisServer结构中的aof_buf缓冲区中的内容写入并同步到AOF文件;
更新serverCron函数的执行次数;
初始化redis服务器
初始化服务器状态结构;
载入配置文件;
初始化服务器数据结构;
通过RDB文件或AOF文件还原数据库状态;
执行事件循环;
#redis服务器#redis 文章被收录于专栏
redis20000字笔记(含思维导图版本-大纲版本)
腾讯成长空间 1100人发布
查看12道真题和解析