redis.conf之save配置项解读
配置示例:
|
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配置项解读的更多相关文章
- 30个redis.conf 配置项说明
redis.conf 配置项说明如下: 1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no 2. 当Redis以守护进程方式运行时,R ...
- redis.conf 配置项说明
redis.conf 配置项说明如下: Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no 当Redis以守护进程方式运行时,Redis ...
- Redis之配置文件redis.conf
解读下 redis.conf 配置文件中常用的配置项,为不显得过于臃长,已选择性删除原配置文件中部分注释. # Redis must be started with the file path as ...
- 4、解析配置文件 redis.conf、Redis持久化RDB、Redis的主从复制
1.Units单位 配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bit 对大小写不敏感 2.INCLUDES包含 和我们的Struts2配置文件类似,可以通过includes包 ...
- redis配置文件redis.conf说明
redis.conf 配置项说明如下:1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no2. 当Redis以守护进程方式运行时, ...
- redis学习之三配置文件redis.conf 的含义
摘自http://www.runoob.com/redis/redis-conf.html 安装redis之后的第一件事,我就开始配置密码,结果总是不生效,而我居然还没想到原因.今天突然用命令行设置了 ...
- redis的redis.conf文件详解
常用的: GENERAL: daemonize yes 守护进程 port 6379 指定Redis监听端口 requirepass 1 设置认证密码为1 REPLICATION: slave ...
- redis配置文件redis.conf参数说明
redis配置文件redis.conf参数说明 (2013-01-09 21:20:40)转载▼ 标签: redis配置 redis.conf 配置说明 杂谈 分类: nosql # By defau ...
- Redis配置文件(redis.conf)说明
Redis 配置 Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf. 你可以通过 CONFIG 命令查看或设置配置项. 语法3> Redis CONFIG 命令 ...
随机推荐
- JFinal Web开发学习(三)前后台路由设计
效果图: 一.写控制器 1.在controller包中新建AdminController后台控制器,继承Controller,实现一个index方法,作为的处理方法. /admin 后面,这个控制器中 ...
- JFinal Web开发学习(一)开启HelloWorld
初次接触JFinal框架,接触过MVC思想,接触过Spring. JFinal官网: http://www.jfinal.com/ 之前很嫌弃JavaWeb开发,主要原因是繁琐的xml配置. 官方推荐 ...
- JAVA软件安装
Java配置----JDK开发环境搭建及环境变量配置 文章来源:http://www.cnblogs.com/smyhvae/p/3788534.html Tomcat安装.配置和部署笔记 文章来源: ...
- Linux移植之auto.conf、autoconf.h、Mach-types.h的生成过程简析
在Linux移植之make uImage编译过程分析中分析了uImage文件产生的过程,在uImage产生的过程中,顺带还产生了其它的一些中间文件.这里主要介绍几个比较关键的文件 1.linux-2. ...
- c# 24种设计模式
备忘录模式(Memento Pattern) 策略模式(Strategy Pattern) 抽象工厂模式(Abstract Factory Pattern) 代理模式(Proxy Pattern) 单 ...
- 如何使用queue_delayed_work函数
本文转自如何使用queue_delayed_work函数 1. delayed_workqueue主要用在需要延迟处理任务的驱动中,这些驱动的特性主要是不能使用中断. delayed_workqueu ...
- windows下git的使用方法(码云)
这表文章主要是用了可视化操作: 使用命令行操作:https://www.cnblogs.com/mswyf/p/9370238.html 一.安装Git Bash 为了在windows下使用Git,我 ...
- javascript数组中数字和非数字下标的区别(转)
http://blog.csdn.net/qq_27461663/article/details/52014911 考完试后闲来无事,想起好多天没写js了,于是打算实践一下最近看到的一些好玩的点子.结 ...
- BUG(0):用某位表示特定属性
用某个bit表示特定属性通常有两种方式: 1.指定某个特定的value #define _PAGE_VALID 0x0001 0bit 为 1 时表示此时的page entry是有效的 用法如下,此时 ...
- 如何查看api项目接口
http://www.api.com/Api/Page/index/?format_type=json&api_cate=cms&ma=8026