redis持久化AOF的rewrite操作的实现
Redis AOF是类似于log的机制,每次写操作都会写到硬盘上,当系统崩溃时,可以通过AOF来恢复数据。每个带有写操作的命令被Redis服务器端收到运行时,该命令都会被记录到AOF文件上。由于只是一个append到文件操作,所以写到硬盘上的操作往往非常快。
其实Redis oaf机制包括了两件事,rewrite和AOF。rewrite类似于普通数据库管理系统日志恢复点,当AOF文件随着写命令的运行膨胀时,当文件大小触碰到临界时,rewrite会被运行。
rewrite会像replication一样,fork出一个子进程,创建一个临时文件,遍历数据库,将每个key、value对输出到临时文件。输出格式就是Redis的命令,但是为了减小文件大小,会将多个key、value对集合起来用一条命令表达。在rewrite期间的写操作会保存在内存的rewrite buffer中,rewrite成功后这些操作也会复制到临时文件中,在最后临时文件会代替AOF文件。
以上在AOF打开的情况下,如果AOF是关闭的,那么rewrite操作可以通过bgrewriteaof命令来进行。
Redis AOF流程
Redis Server启动,如果AOF机制打开那么初始化AOF状态,并且如果存在AOF文件,读取AOF文件。
随着Redis不断接受命令,每个写命令都被添加到AOF文件,AOF文件膨胀到需要rewrite时又或者接收到客户端的bgrewriteaof命令。
fork出一个子进程进行rewrite,而父进程继续接受命令,现在的写操作命令都会被额外添加到一个aof_rewrite_buf_blocks缓冲中。
当子进程rewrite结束后,父进程收到子进程退出信号,把aof_rewrite_buf_blocks的缓冲添加到rewrite后的文件中,然后切换AOF的文件fd。rewrite任务完成,继续第二个步骤。
自动的bgrewriteaof
为了避免aof文件过大,我们会周期性的做bgrewriteaof来重整aof文件。以前我们会额外的配置crontab在业务低峰期执行这个命令,这额外的增加一个workaroud的脚本任务在大集群里是很糟糕的,不易检查,出错无法即时发现。
于是这个自动bgrewriteaof功能被直接加到redis的内部。首先对于aof文件,server对象添加一个字段来记录aof文件的大小server.appendonly_current_size,每次aof发生变化都会维护这个字段。
aof.c
=================
116 nwritten = write(server.appendfd,server.aofbuf,sdslen(server.aofbuf));
.....
128 server.appendonly_current_size += nwritten;
bgrewriteaof完毕或者实例启动载入aof数据后也会调用aofUpdateCurrentSize这个函数维护这个字段,同时会记录下此时的aof文件的大小server.auto_aofrewrite_base_size作为基准值,用于接下来判断aof增长率。
aof.c
=================
385 aofUpdateCurrentSize();
386 server.auto_aofrewrite_base_size = server.appendonly_current_size;
有了当前值和基准值我们就可以判断aof文件的增长情况。另外还需要配置两个参数来判断是否需要自动触发bgrewriteaof。
redis.h
===============
int auto_aofrewrite_perc; /* Rewrite AOF if % growth is > M and... */
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来动态修改的。
复制代码
redis 127.0.0.1:6379> config get auto-aof-rewrite-percentage
1) "auto-aof-rewrite-percentage"
2) "100"
redis 127.0.0.1:6379> config get auto-aof-rewrite-min-size
1) "auto-aof-rewrite-min-size"
2) "1048576"
redis 127.0.0.1:6379> config get auto-aof-rewrite-min-size
1) "auto-aof-rewrite-min-size"
2) "1048576"
redis 127.0.0.1:6379> config set auto-aof-rewrite-percentage 200
OK
redis 127.0.0.1:6379> config set auto-aof-rewrite-min-size 10485760
OK
触发执行rewrite执行的实现:
redis.c
===============
635 if (server.bgsavechildpid == -1 &&
636 server.bgrewritechildpid == -1 &&
637 server.auto_aofrewrite_perc &&
638 server.appendonly_current_size > server.auto_aofrewrite_min_size)
639 {
640 long long base = server.auto_aofrewrite_base_size ?
641 server.auto_aofrewrite_base_size : 1;
642 long long growth = (server.appendonly_current_size*100/base) - 100;
643 if (growth >= server.auto_aofrewrite_perc) {
644 redisLog(REDIS_NOTICE,"Starting automatic rewriting of AOF on %lld%% growth",growth);
645 rewriteAppendOnlyFileBackground();
646 }
647 }
本文标签: redis 持久化AOF rewrite操作
内容版权声明:【蓝色网居】部分资源来源于网络,如有侵犯您的所有权,请随时告知我们,我们将立即删除!感谢配合!
【手机扫一扫查看文本】
目录 head命令 转发 批量 自定义 集群 docker docker迁移 远程仓库 rewrite操作 常用案例 修改默认网段 rediscluster 持久化AOF ssh代理 shell判断 linux系统优化 python3 tail history记录 常用的linux 日志管理 linux phpmyadmin安装 保留和删除

