配置示例:

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);

}

redis.conf之save配置项解读相关推荐

  1. redis中的save配置项

    redis配置文件中的 save <seconds> <changes> 默认的配置为: save 900 1 save 300 10 save 60 10000 以前在其他博 ...

  2. 2、redis.conf基本配置项说明

    Redis的配置项看起来比较复杂,分析之下,其实可以分为几大类(以redis v2.6.14版本的redis.conf为例):          1) 基本配置项          2) 持久化(Pe ...

  3. 解读redis的配置文件--redis.conf

    打开redis.conf文件 (从上至下) 文章目录 建议用 / 方式查找内容位置,阅读更香 头部 INCLUDES 包含 NETWORK 网络 GENERAL 通用 SNAPSHOTTING 快照( ...

  4. Redis(二) -- redis.conf详解(redis6)

    1. 重要配置: 1.1 大小写不敏感: # Note on units: when memory size is needed, it is possible to specify # it in ...

  5. redis.conf配置文件参数说明

    参数说明 redis.conf 配置项说明如下: 1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no 2. 当Redis以守护进程方式 ...

  6. redis配置文件redis.conf参数说明

    redis配置文件redis.conf参数说明 (2013-01-09 21:20:40)转载▼ 标签: redis配置 redis.conf 配置说明 杂谈 分类: nosql # By defau ...

  7. Redis笔记系列(特别总结篇)——常见配置redis.conf知识点总结

    2019独角兽企业重金招聘Python工程师标准>>> 由于前几篇说的redis配置信息量有点杂,很多是循序渐进把各个点引出的,不太方便我自己和其他小伙伴日后拿出来瞄一眼,所以,本文 ...

  8. redis.conf 常见配置介绍

    参数说明 redis.conf 配置项说明如下: 1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程daemonize no 2. 当Redis以守护进程方式运 ...

  9. Redis常见配置redis.conf

    redis的配置文件.相信学过SSH或SSM的读者都知道,配置文件的使用在当下开发已十分普遍,希望大家要熟悉习惯这 种开发方式,废话不多说,来开始我们今天的内容吧.首先得找到 redis 的配置文件 ...

最新文章

  1. 数据结构7.5_有向无环图及其应用
  2. 百度、阿里、滴滴、新浪的面试心经总结,源码+原理+手写框架
  3. Android Studio GPU/CPU/Network/Memory monitor使用
  4. 淘宝嘉年华5元无门槛红包使用范围 怎么设置淘宝嘉年华5元无门槛红包
  5. 《商用密码应用与安全性评估》第四章 密码应用安全性评估实施要点-小结
  6. 基于SpringBoot+微信小程序的壁纸小程序
  7. 计算机网络hdcp是什么意思,4.HDCP:支持高带宽数字内容保护协议HDCP
  8. 【机器学习笔记之五】用ARIMA模型做需求预测用ARIMA模型做需求预测
  9. openpyxl的基本使用
  10. 像素颜色和颜色向量相加相乘的理解
  11. 挂一漏万——交通相关微信公共账号(V1)
  12. 物理隔离卡,双网通用安装
  13. 【转】各种License介绍
  14. CSS2.1 参考手册
  15. 温老师的论坛,欢迎大家踊跃发言!
  16. 行尸走肉第九季在线观看
  17. PluseSensor传感器调试问题小结
  18. 认识计算机网络教学设计,(完整版)1.1认识计算机网络-教学设计
  19. 如何进行BI工具的选型?2020必看的商业智能工具选型参考
  20. VC10 vcpkgsrv.exe 禁止方法

热门文章

  1. 借用gamma校正的方法来调整图片(灰度)亮度(解决侧光问题)并将其再次保存为RGB图片
  2. 带有默认参数值的构造函数
  3. 大学物理一些公式汇总
  4. 找到右下角弹广告的真凶
  5. 建一栋房子总共分几步?建造者模式告诉你答案~
  6. Redis 实战篇:GEO 助我邂逅附近女神
  7. c mvc mysql_c mvc 连接数据库
  8. Process exited after 8.127 seconds with return value 3221226356,求解决方案!
  9. java.lang.Integer connot be cast to class java.lang.String
  10. windows pyinstaller打包pytorch程序到exe文件