redis持久化机制之AOF


通过设置配置项appendonly yes即可开启AOF持久化,默认不开启

AOF的工作流程:命令写入aof buffer-->同步到文件-->文件重写-->启动时加载AOF文件。如下图





可以通过参数appendfsync参数来控制缓冲区同步文件策略,参数及其说明如下表

可配置值说明
always每次命令写入aof_buffer后都会调用fsync同步到aof文件,fsync完成后线程才返回。线程每次都会等fsync完成后才返回,性能较差,数据安全性最高
everysec命令先写入aof_buffer,然后调用系统write操作,write操作完成后线程就返回,由后台专门的线程每秒执行一次fsync操作。推荐使用;最多丢失2s内的数据,之后会解释为什么是2s。
nom命令先写入到aof_buffer,然后调用系统write操作,write操作后线程返回,fsync操作由操作系统负责,时间不确定。fsync由系统负责,数据安全性无法确保,并且会加大每次fsync同步到硬盘的数据量。不推荐
AOF重写:

随着命令的不断写入,会导致aof文件越来越大,这样肯定是不行的,所以需要重写AOF文件,来使AOF文件变小,同时redis从更小的aof文件中恢复数据也更快。

为什么重写可以使AOF文件变小呢?

1、aof文件中存储了大量无用的命令,例如del key1,set key2 A、set key2 B,aof文件中有些命令完全是无效或者多余的;所以redis重写时会根据线程内存中的数据重新生成有效的命令

2、AOF中包含了过期的数据的命令

3、把多条命令合并,例如lpush list A、lpush list B可以转化成lpush list A B;同时为了防止单挑命令过大造成客户端缓冲区溢出,会以64个元素为界限拆分成多条命令


如何触发AOF重写呢?

1、手动触发:使用命令bgrewriteaof

2、自动触发:redis根据参数auto-aof-rewrite-min-size和auto-aof-rewrite-percentage自动确定触发时机

    auto-aof-rewrite-min-size:代表触发aof重写的最小文件体积,默认64M

    auto-aof-rewrite-percentage:代表当前aof文件空间(aof_current_size)和上一次重写后aof文件空间(aof_base_size)的比值,用来确定aof文件增长多少后触发重写

自动触发的机制:aof_current_size > auto-aof-rewrite-min-size && (aof_current_size - aof_base_size) / aof_base_size >=  auto-aof-rewrite-percentage


AOF重写流程:

流程说明:

(1)如果当前正在执行AOF重写,则请求不执行;如果当前正在执行bgsave,则重写延迟到bgsave操作完成后执行

(2)主进程fork出子进程,会短暂阻塞主进程影响读写

(3.1)fork完成后,主进程继续响应命令,并把修改命令写入到aof_buf,并根据appendfsync策略同步到磁盘,保证原有AOF机制的正确性

(3.2)由于fork操作运用写时复制技术,子进程只能共享fork操作时的内存数据,且由于主进程依然响应命令,所以需要把重写期间的命令保存到“AOF重写缓冲区(aof_rewrite_buf)“,防止新生成的aof文件丢失重写期间的数据

(4)子线程根据共享的内存快照,根据命令合并规则生成新的aof文件。每次批量写入磁盘数据量由aof-rewrite-incremental-fsync控制,默认32M,防止单次刷盘数据过多造成磁盘阻塞

(5.1)新的aof文件写入完成后,子进程发送信号给父进程,父进程更新统计信息

(5.2)主进程把AOF重写缓冲区的数据写入到新的aof文件

(5.3)新的aof文件替换旧的aof文件


重启加载备份文件:

如下图


关于AOF追加阻塞:

当使用everysec同步硬盘策略时,redis会由专门的子线程负责对aof_buf中的数据执行fsync操作同步到硬盘,当硬盘资源紧张时会造成redis主线程阻塞。

阻塞流程:

    1、主线程把数据写入到aof_buf

    2、子线程每秒执行一次fsync操作

    3、主线程把数据写入到aof_buf后会对比上次fsync操作的时间,此时有有两种情况:①如果距上次fsync操作成功时间大于2s则阻塞主线程直到fsync操作完成。②如果距上次fsync操作成功时间小于2s则主线程直接返回。


所以,1、everysec配置项最多丢失2s的数据,而不是1s。2、如果fsync操作慢的话可能会造成redis主线程阻塞,影响吞吐量。

以上内容来自阅读《Redis开发与运维》后的总结与笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值