redis4.0以前的重写主要有两点:删除抵消的命令、合并重复的命令 。对于set key1 a和del key1这样相互抵消的命令会被直接删除 。对于set key1 a和set key1 b这样重复的命令会进行合并 。这样一通操作之后,AOF文件可能会变得很小 。
redis4.0之后,开启了RDB和AOF的混合模式 。也就是将已有的数据以RDB的方式记录在appendonly.aof文件的头部,对于之后的增量数据以AOF的方式继续追加在appendonly.aof文件中,也就是appendonly.aof文件前半段是快照数据,后半段是redis指令 。
这样的混合模式结合了RDB和AOF的优点,既能最大限度的减少数据丢失,又能在Redis重启后迅速恢复数据 。
那么在什么情况下会触发bgrewriteaof呢?除了手动触发,配置文件中提供了几个相关参数来实现自动触发
# Automatic rewrite of the append only file.# Redis is able to automatically rewrite the log file implicitly calling# BGREWRITEAOF when the AOF log size grows by the specified percentage.## This is how it works: Redis remembers the size of the AOF file after the# latest rewrite (if no rewrite has happened since the restart, the size of# the AOF at startup is used).## This base size is compared to the current size. If the current size is# bigger than the specified percentage, the rewrite is triggered. Also# you need to specify a minimal size for the AOF file to be rewritten, this# is useful to avoid rewriting the AOF file even if the percentage increase# is reached but it is still pretty small.## Specify a percentage of zero in order to disable the automatic AOF# rewrite feature.auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-min-size参数设置成64mb,意思是redis尚未执行过bgrewriteaof(从启动开始算),AOF文件需要达到64mb才会第一次执行bgrewriteaof(此后不会再使用auto-aof-rewrite-min-size参数),redis会记录每次执行bgrewriteaof之后,AOF文件的大小 。
auto-aof-rewrite-percentage设置成100,表示当前的AOF文件大小超过上一次bgrewriteaof后AOF文件的百分比后触发bgrewriteaof 。如果上次bgrewriteaof后,AOF为200mb,现在需要AOF文件达到400mb才会执行bgrewriteaof 。
auto-aof-rewrite-percentage设置成0,表示禁用bgrewriteaof 。auto-aof-rewrite-min-size参数的作用就是在AOF文件比较小的时候,防止因为增长过快而频繁调用bgrewriteaof 。
no-appendfsync-on-rewriteredis主进程在写AOF文件采用always或者everysec配置,和子进程在重写AOF文件的时候,都会产生大量的I/O操作 。可能会使fsync阻塞很长时间,为了缓解这个问题,redis提供了no-appendfsync-on-rewrite这个参数
【Redis持久化RDB和AOF,看这一篇就够了】# When the AOF fsync policy is set to always or everysec, and a background# saving process (a background save or AOF log background rewriting) is# performing a lot of I/O against the disk, in some Linux configurations# Redis may block too long on the fsync() call. Note that there is no fix for# this currently, as even performing fsync in a different thread will block# our synchronous write(2) call.## In order to mitigate this problem it's possible to use the following option# that will prevent fsync() from being called in the main process while a# BGSAVE or BGREWRITEAOF is in progress.## This means that while another child is saving, the durability of Redis is# the same as "appendfsync none". In practical terms, this means that it is# possible to lose up to 30 seconds of log in the worst scenario (with the# default Linux settings).## If you have latency problems turn this to "yes". Otherwise leave it as# "no" that is the safest pick from the point of view of durability.no-appendfsync-on-rewrite no
如果开启该参数,表示在bgsave和bgrewriteaof的过程中,主线程写入AOF不会调用fsync(),相当于配置appendfsync no 。这样有可能会导致redis的修改命令丢失,Linux默认配置下,最多丢失30秒的数据 。
如果关闭该参数,表示在bgsave和bgrewriteaof的过程中,主线程写入AOF会调用fsync(),并且被阻塞,这样是最安全的,不会丢失数据 。
总结本文主要讲解redis两种持久化方式RDB和AOF,以及他们的实现原理 。此外,还讲解了AOF文件过大怎么处理 。了解这些内容,可以帮助我们更好的使用redis 。
作者:Sicimike
原文链接:https://blog.csdn.net/Baisitao_/article/details/105461153
推荐阅读
- redis集群搭建
- Redis命令大全,满足你的日常工作,看这一篇就够了
- Redis这么讲你还不能入门么
- 在SpingBoot中使用Redis对接口进行限流
- 实战基于Redis实现阻塞队列
- redis5.0.7 版本集群liunx部署简易流程
- redis内存碎片
- 一文读懂Redis的dict字典数据结构
- Go语言 连接池相关总结:HTTP、RPC、Redis 和数据库等
- 谈谈 Redis 的过期策略