redis学习笔记——初始化

初始化服务器状态结构

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中的简单属性(整数、字符串)基本都设置完成。

初始化服务器数据结构

时间: 2024-11-04 13:34:12

redis学习笔记——初始化的相关文章

Redis学习笔记(简单了解与运行)

Redis学习笔记(简单了解与运行) 开源的非关系型数据库 是REmote Dictionary Server(远程字典服务器)的缩写,以字典结构存储数据 允许其他应用通过TCP协议读写字典中的内容. Redis支持存储的键值数据类型 字符串类型 散列类型 列表类型 集合类型 有序集合类型 Redis的特性 通过一个列子看出Mysql和Redis的存储区别 例如: (存储一篇文章,文章包括:标题(title),正文(content),阅读量(views),标签(tags)) 需求: 把数据存储在

Redis学习笔记

Redis学习笔记:Redis是什么?redis是开源BSD许可高级的key-vlue存储系统可以用来存储字符串哈希结构链表.结构.集合,因此常用来提供数据结构服务. redis和memcache相比的独特之处:1.redis可以用来做存储,而memcache是用来做缓存 这个特点主要因为其有"持久化"的功能.2.存储的数据有"结构",对于memcache来说,存储的数据只有1种类型"字符串"而 redis则可以存储字符串.链表.哈希机构.集合.

(转)redis 学习笔记(1)-编译、启动、停止

redis 学习笔记(1)-编译.启动.停止 一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先到这里下载Stable稳定版,目前最新版本是2.8.17 1.2 上传到linux,然后运行以下命令解压 tar xzf redis-2.8.17.tar.gz 1.3 编译 cd redis-2.8.17make 注:make命令需要linux上安装gcc,若机器上未安装gcc,redhat环境下,如

Redis学习笔记4-Redis配置具体解释

在Redis中直接启动redis-server服务时, 採用的是默认的配置文件.採用redis-server   xxx.conf 这种方式能够依照指定的配置文件来执行Redis服务. 依照本Redis学习笔记中Redis的依照方式依照后,Redis的配置文件是/etc/redis/6379.conf.以下是Redis2.8.9的配置文件各项的中文解释. #daemonize no 默认情况下, redis 不是在后台运行的.假设须要在后台运行,把该项的值更改为 yes daemonize ye

Redis学习笔记~目录

redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hashs(哈希类型).这些数据类型都 支持push/pop.add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的.在此基础上,redis支持各种不同方式的排 序.与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更

Redis学习笔记7--Redis管道(pipeline)

redis是一个cs模式的tcp server,使用和http类似的请求响应协议.一个client可以通过一个socket连接发起多个请求命令.每个请求命令发出后client通常会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client.基本的通信过程如下: Client: INCR X Server: 1 Client: INCR X Server: 2 Client: INCR X Server: 3 Client: INCR X Server: 4

Redis学习笔记4-Redis配置详解

原文:  http://blog.csdn.net/mashangyou/article/details/24555191 在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redis学习笔记中Redis的按照方式按照后,Redis的配置文件是/etc/redis/6379.conf.下面是Redis2.8.9的配置文件各项的中文解释. 1 #daemon

Redis学习笔记(增删查)

Redis学习笔记(增删查) 向数据库中添加一个键 SET key value 获取数据库中的key KEYS pattern pattern支持glob风格通配符格式 " ? " 匹配一个字符 " * " 匹配任意字符 " [] " 匹配括号间的任一字符,可以使用" - "符号表示一个范围,例如:a[a-z]c " \x " 匹配字符x,用于转义字符.如需要匹配"?",就需要用 \?

redis学习笔记(12)---server基本流程

server工作流程 当执行./redis-server后,redis数据库的server端就会启动. 然后就会执行redis.c中的main()函数 其中main()函数中的工作可以主要分为以下几个部分: 1.初始化server端的配置信息- - -initServerConfig() 2.解析运行时的命令参数,并根据参数进行处理,eg:./redis-server - -help 3.如果设置了daemonize参数,则将server设为deamon进程- - -daemonize() 4.