redis.conf之save配置项解读

35 篇文章 1 订阅

配置示例:

save 900 1

save 300 10

save 60 3600

 

配置解读:

1) “save 900 1”表示如果900内至少1个key发生变化(新增、修改和删除),则重写rdb文件;

2) “save 300 10”表示如果每300内至少10个key发生变化(新增、修改和删除),则重写rdb文件;

3) “save 60 3600”表示如果每60内至少10000个key发生变化(新增、修改和删除),则重写rdb文件。

 

作用:

控制什么时候生成rdb文件(快照,也可叫Checkpoint,即检查点)。

 

进程启动的时候,会将每一行save读进到类型为struct saveparam的数组中。这个没有排序,依在redis.conf中的先后顺序。在检查时,只要满足就不会再检查下一条规则。

 

配置策略:

如果同时开启了aof,则可考虑将save的参数调大一点,以减少写rdb带来的压力。实际上如果开启了aof,redis在启动时只会读取aof文件,而不会读取rdb文件:

// Function called at startup to load RDB or AOF file in memory.

void loadDataFromDisk(void) {    

    if (server.aof_state == AOF_ON) {      

        // 允许空的aof文件,

        // 如果读取aof文件出错,则调用exit(1)直接退出进程

        if (loadAppendOnlyFile(server.aof_filename) == C_OK)

            serverLog(LL_NOTICE,"DB loaded from append only file: %.3f seconds",(float)(ustime()-start)/1000000);

    } else {

         if (rdbLoad(server.rdb_filename,&rsi) == C_OK) {

    }

}

 

// #define AOF_OFF 0             /* AOF is off */

// #define AOF_ON 1              /* AOF is on */

void loadServerConfigFromString(char *config) {

    。。。。。。

    } else if (!strcasecmp(argv[0],"appendonly") && argc == 2) {

        int yes;

        if ((yes = yesnotoi(argv[1])) == -1) {

            err = "argument must be 'yes' or 'no'"; goto loaderr;

        }

         server.aof_state = yes ? AOF_ON : AOF_OFF;

    }

    。。。。。。

}

 

int yesnotoi(char *s) {

    if (!strcasecmp(s,"yes")) return 1;

    else if (!strcasecmp(s,"no")) return 0;

    else return -1;

}

 

调用顺序:

main()/server.c ->

aeMain()/ae.c -> while (!stop) { aeProcessEvents()/ae.c } ->

serverCron()/server.c -> rdbSaveBackground()/server.c

 

注:

aeProcessEvents可看作是个epoll_wait调用,在Linux上实际正是epoll_wait调用,而在Solaris上则是port_getn调用。

 

相关源代码:

int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {

    。。。。。。

    // Check if a background saving or AOF rewrite in progress terminated.

    // 如果已有rdb和aof进程,检查进程是否已退出。

    // 如果已退出,则会善后处理,否则什么也不做,等待下一次循环时再次检查

    if (server.rdb_child_pid != -1 ||

        server.aof_child_pid != -1 ||

         ldbPendingChildren()) {

        int statloc;

        pid_t pid;

        if ((pid = wait3(&statloc,WNOHANG,NULL)) != 0) {

            int exitcode = WEXITSTATUS(statloc);

            。。。。。。

        }

    } else {

        // If there is not a background saving/rewrite

        // in progress check if we have to save/rewrite now.

        // 按在redis.conf中定义的顺序依次遍历每一行配置项

        // 最终是否进行写rdb操作(即生成快照文件),不仅由redis.conf

        // 中的配置项决定,还要看上一次操作的结果和状态。

        for (j = 0; j < server.saveparamslen; j++) {

            struct saveparam *sp = server.saveparams+j;

            // Save if we reached the given amount of changes,

            // the given amount of seconds, and if the latest bgsave was

            // successful or if, in case of an error, at least

            // CONFIG_BGSAVE_RETRY_DELAY seconds already elapsed.

            // CONFIG_BGSAVE_RETRY_DELAY(5): Wait a few secs before trying again.

            if (server.dirty >= sp->changes &&

                server.unixtime-server.lastsave > sp->seconds &&

                (server.unixtime-server.lastbgsave_try>CONFIG_BGSAVE_RETRY_DELAY ||

                 server.lastbgsave_status == C_OK)) {

                serverLog(LL_NOTICE,"%d changes in %d seconds. Saving...",

                    sp->changes, (int)sp->seconds);

                rdbSaveInfo rsi, *rsiptr;

                rsiptr = rdbPopulateSaveInfo(&rsi);

                rdbSaveBackground(server.rdb_filename,rsiptr);

                break; // 遇到一条满足的即结束处理,因为已没有必要判断是否满足下一条配置规则

            }

        }

    }

    。。。。。。     

}

 

// rdb.c

int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {

    。。。。。。

    server.lastbgsave_try = time(NULL);

    。。。。。。

    // 创建写rdb的子进程

    if ((childpid = fork()) == 0) {

        redisSetProcTitle("redis-rdb-bgsave");

        retval = rdbSave(filename,rsi);

    }

    。。。。。。

}

 

/* Save the DB on disk. Return C_ERR on error, C_OK on success. */

// rdb.c

// rdbSave调用rdbSaveRio将数据写入到rdb文件中

int rdbSave(char *filename, rdbSaveInfo *rsi) {

    。。。。。。

    // 写rdb文件

    if (rdbSaveRio(&rdb,&error,RDB_SAVE_NONE,rsi) == C_ERR) {

        errno = error;

        goto werr;

    }

    。。。。。。

    serverLog(LL_NOTICE,"DB saved on disk");

    server.dirty = 0;

    server.lastsave = time(NULL);

    server.lastbgsave_status = C_OK;

    return C_OK;

}

 

/* Produces a dump of the database in RDB format sending it to the specified

 * Redis I/O channel. On success C_OK is returned, otherwise C_ERR

 * is returned and part of the output, or all the output, can be

 * missing because of I/O errors.

 *

 * When the function returns C_ERR and if 'error' is not NULL, the

 * integer pointed by 'error' is set to the value of errno just after the I/O

 * error. */

int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) {

    for (j = 0; j < server.dbnum; j++) {

        。。。。。。

        // Iterate this DB writing every entry

        while((de = dictNext(di)) != NULL) {

            。。。。。。

            // 将一对对KV写入到rdb文件

            if (rdbSaveKeyValuePair(rdb,&key,o,expire) == -1) goto werr;            

            。。。。。。

        }

    }

    。。。。。。

werr:

    if (error) *error = errno;

    if (di) dictReleaseIterator(di);

    return C_ERR;

}

 

// 以SADD命令为例,所有写操作,均会修改dirty 的值

void saddCommand(client *c) {

    。。。。。。

    for (j = 2; j < c->argc; j++) {

        if (setTypeAdd(set,c->argv[j]->ptr)) added++;

    }

    。。。。。。

    server.dirty += added;

    addReplyLongLong(c,added);

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Redis是一个开源的高性能键值对存储数据库,其配置文件redis.conf包含了Redis的所有配置。下面是redis.conf文件中所有配置详解: 1. bind:指定Redis监听的IP地址,默认为127.0.0.1,表示只能本地访问,如果要让其他主机访问,需要将其设置为0.0.0.0。 2. port:指定Redis监听的端口号,默认为6379。 3. tcp-backlog:指定TCP连接队列的长度,默认为511。 4. timeout:指定Redis客户端连接超时时间,默认为0,表示不限制超时时间。 5. tcp-keepalive:指定Redis是否开启TCP Keepalive功能,默认为0,表示不开启。 6. daemonize:指定Redis是否以守护进程方式运行,默认为no,表示以前台进程方式运行,如果要以守护进程方式运行,需要将其设置为yes。 7. pidfile:指定Redis守护进程的PID文件路径,默认为/var/run/redis.pid。 8. loglevel:指定Redis日志的输出级别,包括debug、verbose、notice、warning,默认为notice。 9. logfile:指定Redis的日志文件路径,默认为stdout,表示将日志输出到标准输出,如果要将日志输出到文件,需要指定日志文件路径。 10. databases:指定Redis支持的数据库数量,默认为16个,可以通过修改该配置增加数据库数量。 11. save:指定Redis进行持久化的策略,每行由三个参数组成,第一个参数是时间间隔(单位为秒),第二个参数是执行该策略的条件(写入的键值对数量),第三个参数是执行该策略的条件(写入的键值对数量),默认不开启持久化。 12. rdbcompression:指定Redis是否开启RDB文件压缩功能,默认为yes,表示开启。 13. dbfilename:指定Redis持久化数据文件的名称,默认为dump.rdb。 14. dir:指定Redis持久化数据文件的存储路径,默认为./。 15. maxclients:指定Redis同时连接的客户端数量,默认为10000,如果要支持更多的客户端连接,需要将其设置为更大的值。 16. maxmemory:指定Redis使用的最大内存量,如果超过该值,Redis会按照一定的策略选择一些键进行删除,默认为0,表示不限制内存使用量。 17. maxmemory-policy:指定Redis内存达到最大限制时的淘汰策略,包括noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random、volatile-ttl,默认为noeviction。 18. appendonly:指定Redis是否开启持久化功能,默认为no,表示不开启持久化功能,如果要开启持久化功能,需要将其设置为yes。 19. appendfilename:指定Redis持久化AOF文件的名称,默认为appendonly.aof。 20. appendfsync:指定Redis持久化AOF文件的同步方式,包括always、everysec、no,默认为everysec。 21. auto-aof-rewrite-percentage:指定Redis自动触发AOF文件重写的比例,默认为100。 22. auto-aof-rewrite-min-size:指定Redis自动触发AOF文件重写的最小文件大小,默认为64MB。 23. lua-time-limit:指定Redis执行Lua脚本的最长时间,默认为5000毫秒。 24. slowlog-log-slower-than:指定Redis慢查询日志的执行时间阈值,默认为10000微秒。 25. slowlog-max-len:指定Redis慢查询日志的最大长度,默认为128。 以上是redis.conf文件中所有配置详解,通过修改这些配置可以对Redis进行定制化配置

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值