REDIS6.0源码阅读(二)REDIS-SERVER启动主流程之initServerConfig
在redis-server的初始化过程中,会从参数(redis.conf文件中读取用户的配置信息),还包含有一些诸如设置时区参数、设置内存溢出的回调函数等,比较重要的是initServerConfig,initServerConfig主要包含有一些基础参数的读取和配置,如:
- updateCachedTime(1);//存储一个unix的全局变量,用来存储时间,调用起来要比调用time方法快
- getRandomHexChars(server.runid,CONFIG_RUN_ID_SIZE);//设置服务器运行的ID
- server.runid[CONFIG_RUN_ID_SIZE] = '\0';//为运行ID后面加换行
- changeReplicationId();//用一个新生成的随机的ID替代当前server的实例的ID
- //以及一些最基本的参数
同时通过populateCommandTable();方法设置一些最基础的命令行,如我们常用的set、get命令等。源码中写道:初始化的时候要初始一部分命令码及其对应的回调,当然可以通过redis.conf来修改命令码的内容,亦即我们可以通过修改redis.conf文件来实现对命令行的重命名操作。
可以看出命令行的设置是依赖于结构体redisCommandTable的,通过阅读我们可以发现该结构体其实为命令码及其对应的命令处理函数的一一对应关系,下面示例代码以set命令和setCommand方法对应关系做一个说明:
struct redisCommand redisCommandTable[] = {
......
/* Note that we can't flag set as fast, since it may perform an
* implicit DEL of a large key. */
{"set",setCommand,-3,
"write use-memory @string",
0,NULL,1,1,1,0,0,0}
......
}
而处理命令对应的处理函数却藏在结构体redisCommand中:
struct redisCommand {
char *name;//命令的名字,如set
redisCommandProc *proc;//命令执行的函数,如setCommand
int arity;//参数的个数
char *sflags; //字符串的标志位
uint64_t flags; //真实的标志位
/* Use a function to determine keys arguments in a command line.
* Used for Redis Cluster redirect. */
//下面的内容涉及到集群部署之后,命令对应的方法如何路由的问题,后面阅读到集群相关内容后会补充
redisGetKeysProc *getkeys_proc;//当开启集群的时候,需要根据key值来确认路由到哪个server
/* What keys should be loaded in background when calling this command? */
int firstkey; //第一个key值
int lastkey; //最后一个key值
int keystep; //从第一个key值到最后一个key值所走的步数
long long microseconds, calls;
int id;//此ID比较关键,为redis 6.0版本之后新增的功能,即ACL子系统对不同用户所拥有的命令行权限的控制
};
介绍完上面两个比较关键的结构体后,我们仍旧以set及其对应的setCommand方法为例,在populateCommandTable()方法中,我们会根据redisCommandTable表中的内容一个个进行初始化,当初始化到set的时候,我们gdb调试跟踪到其内容如下:

即所有的命令都是通过类似的形式来进行其对应的命令处理函数的设定,命令对应的命令处理函数,在server.h文件中可以查询到,大部分都是顾名思义的:
......
void setCommand(client *c);
.....
当我们redis-server启动之后,redis-cli通过set命令执行的时候,其堆栈调用流程如下:

当我们redis-server启动之后,redis-cli通过set命令执行的时候,其堆栈调用流程如下:
我们通过代码跟踪到call这个回调,可以看到从client传过来的命令的名字为set,此时根据已经设定好的set对应setCommand,即下一步的执行为setCommand:

小结:本文主要介绍initServerConfig初始化配置信息的一些内容,着重描述了populateCommandTable()方法在初始化命令及其对应的命令处理函数之间的初始化,并通过set命令及setCommand方法的调用来说明这个过程,当然,内容中涉及到ACL子系统相关的内容暂未做介绍,setCommand的对应调用流程也未作具体说明,后面相关内容都会继续补充。
posted on 2020-11-03 22:21 FightForFuture_FFF 阅读(211) 评论(0) 收藏 举报
浙公网安备 33010602011771号