免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5155 | 回复: 1
打印 上一主题 下一主题

[Redis] Redis2.4版的自动bgrewriteaof [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-16 18:26 |只看该作者 |倒序浏览
Redis2.4版的自动bgrewriteaof








2.4版本做了很多功能改进,尤其是aof这块变动较大。增加了自动的bgrewriteaof,开启两个后台线程来避免主线程fsync、rename、close等阻塞操作,另外修复了出现重复命令进入aof文件的bug,下面是基于2.4.1的源码aof这块的改进分析。

自动的bgrewriteaof
为了避免aof文件过大,我们会周期性的做bgrewriteaof来重整aof文件。以前我们会额外的配置crontab在业务低峰期执行这个命令,这额外的增加一个workaroud的脚本任务在大集群里是很糟糕的,不易检查,出错无法即时发现。

于是这个自动bgrewriteaof功能被直接加到redis的内部。首先对于aof文件,server对象添加一个字段来记录aof文件的大小server.appendonly_current_size,每次aof发生变化都会维护这个字段。

aof.c
  1. =================
  2. 116     nwritten = write(server.appendfd,server.aofbuf,sdslen(server.aofbuf));
  3. .....
  4. 128     server.appendonly_current_size += nwritten;bgrewriteaof
复制代码
完毕或者实例启动载入aof数据后也会调用aofUpdateCurrentSize这个函数维护这个字段,同时会记录下此时的aof文件的大小server.auto_aofrewrite_base_size作为基准值,用于接下来判断aof增长率。

aof.c
=================
  1. 385     aofUpdateCurrentSize();
  2. 386     server.auto_aofrewrite_base_size = server.appendonly_current_size
复制代码
;有了当前值和基准值我们就可以判断aof文件的增长情况。另外还需要配置两个参数来判断是否需要自动触发bgrewriteaof。

redis.h
===============
  1. int auto_aofrewrite_perc;       /* Rewrite AOF if % growth is > M and... */
  2. off_t auto_aofrewrite_min_size; /* the AOF file is at least N bytes. */auto_aofrewrite_perc: aof
复制代码
文件的大小超过基准百分之多少后触发bgrewriteaof。默认这个值设置为100,意味着当前aof是基准大小的两倍的时候触发bgrewriteaof。把它设置为0可以禁用自动触发的功能。
auto_aofrewrite_min_size: 当前aof文件大于多少字节后才触发。避免在aof较小的时候无谓行为。默认大小为64mb。
两个参数都是可以在conf里静态配置,或者通过config set来动态修改的。
  1. redis 127.0.0.1:6379> config get auto-aof-rewrite-percentage
  2. 1) "auto-aof-rewrite-percentage"
  3. 2) "100"
  4. redis 127.0.0.1:6379> config get auto-aof-rewrite-min-size
  5. 1) "auto-aof-rewrite-min-size"
  6. 2) "1048576"
  7. redis 127.0.0.1:6379> config get auto-aof-rewrite-min-size
  8. 1) "auto-aof-rewrite-min-size"
  9. 2) "1048576"
  10. redis 127.0.0.1:6379> config set auto-aof-rewrite-percentage 200
  11. OK
  12. redis 127.0.0.1:6379> config set auto-aof-rewrite-min-size 10485760
复制代码
OK然后就是触发检查的主逻辑,serverCron时间事件中每次都会检查现有状态和参数来判断是否需要启动bgrewriteaof。

redis.c
===============
  1. 635          if (server.bgsavechildpid == -1 &&
  2. 636              server.bgrewritechildpid == -1 &&
  3. 637              server.auto_aofrewrite_perc &&
  4. 638              server.appendonly_current_size > server.auto_aofrewrite_min_size)
  5. 639          {
  6. 640             long long base = server.auto_aofrewrite_base_size ?
  7. 641                             server.auto_aofrewrite_base_size : 1;
  8. 642             long long growth = (server.appendonly_current_size*100/base) - 100;
  9. 643             if (growth >= server.auto_aofrewrite_perc) {
  10. 644                 redisLog(REDIS_NOTICE,"Starting automatic rewriting of AOF on %lld%% growth",growth);
  11. 645                 rewriteAppendOnlyFileBackground();
  12. 646             }
  13. 647         }
复制代码
以上代码显示,如果aof文件增长百分率growth大于auto_aofrewrite_perc,则自动的触发后一个bgrewriteaof。

延迟bgrewriteaof
这是个小的改进,手动触发的bgrewriteaof的时候如果同时存在bgsave在备份,会推迟这次操走的事件,设置server.aofrewrite_scheduled=1,待到bgsave结束后的下一次serverCron里才会触发。

设置aofrewrite_scheduled=1

aof.c
  1. 706 void bgrewriteaofCommand(redisClient *c) {
  2. 707     if (server.bgrewritechildpid != -1) {
  3. 708         addReplyError(c,"Background append only file rewriting already in progress");
  4. 709     } else if (server.bgsavechildpid != -1) {
  5. 710         server.aofrewrite_scheduled = 1;
  6. 711         addReplyStatus(c,"Background append only file rewriting scheduled");
  7. 712     } else if (rewriteAppendOnlyFileBackground() == REDIS_OK) {
  8. 713         addReplyStatus(c,"Background append only file rewriting started");
  9. 714     } else {
  10. 715         addReply(c,shared.err);
  11. 716     }
  12. 717 }
复制代码
触发bgrewriteaof

redis.c
  1. 598     if (server.bgsavechildpid == -1 && server.bgrewritechildpid == -1 &&
  2. 599         server.aofrewrite_scheduled)
  3. 600     {
  4. 601         rewriteAppendOnlyFileBackground();
  5. 602    }
复制代码
在2.4.1的这里存在一个bug,因为没有地方把server.aofrewrite_scheduled = 0;在刚发布的2.4.2里fix了这个bug。

论坛徽章:
0
2 [报告]
发表于 2012-02-17 22:56 |只看该作者
谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP