命令请求的执行过程
客户端发送命令请求
服务器读取命令请求
命令执行器:查找命令实现
命令执行器:执行预备操作
命令执行器:调用命令的实现函数
命令执行器:执行后续工作
将命令回复发送给客户端
客户端接收并打印回复
serverCron函数
更新服务器时间缓存
struct redisServer (
...;
time_t unixtime; // 保存了秒级精度的系统当前UNIX事件戳,serverCron函数每100毫秒更新一次
long long mstime; // 保存了毫秒级精度的系统当前UNIX事件戳,serverCron函数每100毫秒更新一次
...;
);
更新LRU时钟
struct redisServer (
...;
unsigned lruclock:22; // 默认每10秒更新一次时钟缓存,用于计算键的空转时长
...;
);
更新服务器每秒执行命令次数
struct redisServer (
...;
long long ops_sec_last_sample_time; // 上一次进行抽样的时间
long long ops_sec_last_sample_ops; // 上一次抽样时,服务器已执行命令的数量
// 数组默认是16的环形数组,数组中每一项记录了一次抽样结果
long long ops_sec_samples[REDIS_OPS_SEC_SAMPLES];
// ops_sec_samples数组的索引,每次抽样后自增1,在值等于16时重置为0,让其构成一个环形数组
int ops_sec_index;
...;
);
更新服务器内存峰值记录
struct redisServer (
...;
size_t stat_peak_memory; // 已使用内存峰值,记录服务器的内存峰值大小
...;
);
处理SIGTERM信号
struct redisServer (
...;
int shutdown_asap; // 关闭服务器的标识,为1时关闭服务器,为0时不做动作
...;
);
管理客户端资源
管理数据库资源
执行被延迟的BGREWRITEAOF
struct redisServer (
...;
int aof_rewrite_scheduled; // 如果值为1,那么表示有BGREWRITEAOF命令被延迟了
...;
);
检查持久化操作的运行状态
struct redisServer (
...;
pid_t rdb_child_pid; // 记录执行BGSAVE命令的子进程ID, 如果没有执行该值为-1
pid_t aof_child_pid; // 记录执行BGREWRITEAOF命令的子进程ID, 如果没有执行该值为-1
...;
);
将AOF缓冲区中的内容写入AOF文件
关闭异步客户端
增加cronloops计数器的值
struct redisServer (
...;
// 函数运行次数,每运行一次serverCron,该属性的值加1
// 作用是复制时实现每次执行serverCron函数N次就执行一次指定代码
int cronloops;
...;
);
总结下来的结构如下:
struct redisServer (
...;
time_t unixtime; // 保存了秒级精度的系统当前UNIX事件戳,serverCron函数每100毫秒更新一次
long long mstime; // 保存了毫秒级精度的系统当前UNIX事件戳,serverCron函数每100毫秒更新一次
unsigned lruclock:22; // 默认每10秒更新一次时钟缓存,用于计算键的空转时长
long long ops_sec_last_sample_time; // 上一次进行抽样的时间
long long ops_sec_last_sample_ops; // 上一次抽样时,服务器已执行命令的数量
// 数组默认是16的环形数组,数组中每一项记录了一次抽样结果
long long ops_sec_samples[REDIS_OPS_SEC_SAMPLES];
// ops_sec_samples数组的索引,每次抽样后自增1,在值等于16时重置为0,让其构成一个环形数组
int ops_sec_index;
size_t stat_peak_memory; // 已使用内存峰值,记录服务器的内存峰值大小
int shutdown_asap; // 关闭服务器的标识,为1时关闭服务器,为0时不做动作
int aof_rewrite_scheduled; // 如果值为1,那么表示有BGREWRITEAOF命令被延迟了
pid_t rdb_child_pid; // 记录执行BGSAVE命令的子进程ID, 如果没有执行该值为-1
pid_t aof_child_pid; // 记录执行BGREWRITEAOF命令的子进程ID, 如果没有执行该值为-1
// 函数运行次数,每运行一次serverCron,该属性的值加1
// 作用是复制时实现每次执行serverCron函数N次就执行一次指定代码
int cronloops;
...;
);
初始化服务器
初始化服务器状态结构
initServerConfig函数操作:
- 设置服务器的运行ID
- 设置服务器的默认运行频率
- 设置服务器的默认配置文件路径
- 设置服务器的运行架构
- 设置服务器的默认端口号
- 设置服务器默认RDB持久化条件和AOF持久化条件
- 初始化服务器的LRU时钟
- 创建命令表
载入配置选项
初始化服务器数据结构
创建的数据结构比如
- 创建server.client链表
- 创建server.db数组
- 创建用于保存频道订阅信息的server.pubsub_channels字典以及用于保存模式订阅信息的server.pubsubtterns链表
- 创建用于执行Lua脚本的Lua环境server.lua
- 创建用于保存慢查询日志的server.slowlog属性
运行initServer函数
- 为服务器设置进程信号处理器
- 创建共享对象
- 打开服务器的监听端口
- 为ServerCron创建时间事件
- 如果AOF持久化功能打开,则打开现有AOF文件,如果不存在,创建一个新的
- 初始化服务器后台I/O模块
还原数据库状态
执行时间循环
参考:
黄键宏老师的《redis设计与实现》,机械工业出版社