标签:
redis中一个最重要的数据结构是redis_server,会创建一个这个结构的全局变量server,初始化服务器的第一步就是创建一个struct redisServer类型的实例变量server作为服务器的状态,并为结构中的各个属性设置默认值。初始化server变量的工作由redis.c/initServerConfig函数完成,initServerConfig函数中,大部分是对server的属性设置默认值,还有一部分是调用populateCommandTable函数对redis的命令表初始化。全局变量redisCommandTable是redisCommand类型的数组,保存redis支持的所有命令。server.commands是一个dict,保存命令名到redisCommand的映射。populateCommandTable函数会遍历全局redisCommandTable表,把每条命令插入到server.commands中,根据每个命令的属性设置其flags。以下是这个函数的部分代码:
void initServerConfig(void){
//
设置服务器的运行id
getRandomHexChars(server.runid,REDIS_RUN_ID_SIZE);
//
为运行id
加上结尾字符
server.runid[REDIS_RUN_ID_SIZE] = ‘\0‘;
//
设置默认配置文件路径
server.configfile = NULL;
//
设置默认服务器频率
server.hz = REDIS_DEFAULT_HZ;
//
设置服务器的运行架构
server.arch_bits = (sizeof(long) == 8) ? 64 : 32;
//
设置默认服务器端口号
server.port = REDIS_SERVERPORT;
// ...
/* Command table -- we initiialize it here as it is part of the
* initial configuration, since command names may be changed via
* redis.conf using the rename-command directive. */
// 初始化命令表
// 在这里初始化是因为接下来读取 .conf 文件时可能会用到这些命令
server.commands = dictCreate(&commandTableDictType,NULL);
server.orig_commands = dictCreate(&commandTableDictType,NULL);
populateCommandTable();
server.delCommand = lookupCommandByCString("del");
server.multiCommand = lookupCommandByCString("multi");
server.lpushCommand = lookupCommandByCString("lpush");
server.lpopCommand = lookupCommandByCString("lpop");
server.rpopCommand = lookupCommandByCString("rpop");
...
}
以下是initServerConfig函数完成的主要工作:
·设置服务器的运行ID。
·设置服务器的默认运行频率。
·设置服务器的默认配置文件路径。
·设置服务器的运行架构。
·设置服务器的默认端口号。
·设置服务器的默认RDB持久化条件和AOF持久化条件。
·初始化服务器的LRU时钟。
·创建命令表。
在启动服务器时,用户可以通过给定配置参数或者指定配置文件来修改服务器的默认配置。举个例子,如果我们在终端中输入:
$ redis-server --port 10086
那么我们就通过给定配置参数的方式,修改了服务器的运行端口号。另外,如果我们在终端中输入:
$ redis-server redis.conf
那么我们就通过指定配置文件的方式修改了服务器的数据库数量,以及RDB持久化模块的压缩功能。
服务器在用initServerConfig函数初始化完server变量之后,就会开始载入用户给定的配置参数和配置文件,并根据用户设定的配置,对server变量相关属性的值进行修改。
这一部分是在main()函数中实现的,下面是源代码:
// 检查用户是否指定了配置文件,或者配置选项 if (argc >= 2) { int j = 1; /* First option to parse in argv[] */ sds options = sdsempty(); char *configfile = NULL; /* Handle special options --help and --version */ // 处理特殊选项 -h 、-v 和 --test-memory if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) version(); if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) usage(); if (strcmp(argv[1], "--test-memory") == 0) { if (argc == 3) { memtest(atoi(argv[2]),50); exit(0); } else { fprintf(stderr,"Please specify the amount of memory to test in megabytes.\n"); fprintf(stderr,"Example: ./redis-server --test-memory 4096\n\n"); exit(1); } } /* First argument is the config file name? */ // 如果第一个参数(argv[1])不是以 "--" 开头 // 那么它应该是一个配置文件 if (argv[j][0] != ‘-‘ || argv[j][1] != ‘-‘) configfile = argv[j++]; /* All the other options are parsed and conceptually appended to the * configuration file. For instance --port 6380 will generate the * string "port 6380\n" to be parsed after the actual file name * is parsed, if any. */ // 对用户给定的其余选项进行分析,并将分析所得的字符串追加稍后载入的配置文件的内容之后 // 比如 --port 6380 会被分析为 "port 6380\n" while(j != argc) { if (argv[j][0] == ‘-‘ && argv[j][1] == ‘-‘) { /* Option name */ if (sdslen(options)) options = sdscat(options,"\n"); options = sdscat(options,argv[j]+2); options = sdscat(options," "); } else { /* Option argument */ options = sdscatrepr(options,argv[j],strlen(argv[j])); options = sdscat(options," "); } j++; } //getAbsolutePath()函数用于得到一直文件名的绝对路径 if (configfile) server.configfile = getAbsolutePath(configfile); // 重置保存条件 resetServerSaveParams(); // 载入配置文件, options 是前面分析出的给定选项 loadServerConfig(configfile,options); sdsfree(options); // 获取配置文件的绝对路径 if (configfile) server.configfile = getAbsolutePath(configfile); } else { redisLog(REDIS_WARNING, "Warning: no config file specified, using the default config. In order to specify a config file use %s /path/to/%s.conf", argv[0], server.sentinel_mode ? "sentinel" : "redis"); }
其中 loadServerConfig(char *filename,char *option)函数主要用于从给定文件中载入服务器配置。
loadServerConfig:完成的功能很简单,就是将文件内容读到字符串中。并将通过命令行传入的配置项追加到该字符串后。后面loadServerConfig会调用loadServerConfigFromString函数:从字符串中解析出配置项,并设置server的相关属性(可参照源代码)。
此步完成后,server中的简单属性(整数、字符串)基本都设置完成。
标签:
原文地址:http://www.cnblogs.com/lukexwang/p/4709200.html