上篇文章和小伙伴们聊了使用快照的方式实现 redis 数据的持久化,这只是持久化的一种方式,本文我们就来看看另一种持久化方式, AOF(append-only file)。
本文是 Redis 系列的第九篇文章,了解前面的文章有助于更好的理解本文:
1.Linux 上安装 Redis
2.Redis 中的五种数据类型简介
3.Redis 字符串 (STRING) 介绍
4.Redis 字符串 (STRING) 中 BIT 相关命令
5.Redis 列表与集合
6.Redis 散列与有序集合
7.Redis 中的发布订阅和事务
8.Redis 快照持久化
# AOF 持久化
与快照持久化不同,AOF 持久化是将被执行的命令写到 aof 文件末尾,在恢复时只需要从头到尾执行一遍写命令即可恢复数据,AOF 在 redis 中默认也是没有开启的,需要我们手动开启,开启方式如下:
打开 redis.conf 配置文件,修改 appendonly 属性值为 yes ,如下:
appendonly yes
另外几个和 AOF 相关的属性如下:
appendfilename "appendonly.aof"
# appendfsync always
appendfsync everysec
# appendfsync no
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
这几个属性的含义分别如下:
1.appendfilename 表示生成的 AOF 备份文件的文件名。
2.appendfsync 表示备份的时机,always 表示每执行一个命令就备份一次,everysec 表示每秒备份一次,no 表示将备份时机交给操作系统。
3.no-appendfsync-on-rewrite 表示在对 aof 文件进行压缩时,是否执行同步操作。
4.最后两行配置表示 AOF 文件的压缩时机,这个我们一会再细说。
同时为了避免快照备份的影响,我们将快照备份关闭,关闭方式如下:
save ""
# save 900 1
# save 300 10
# save 60 10000
此时,当我们在 redis 中进行数据操作时,就会自动生成 AOF 的配置文件 appendonly.aof ,如下:
注意此时没有 dump.rdb 文件,这时我们将 redis 关闭并重启,会发现之前的数据都还在,这就是 AOF 备份的结果。
# AOF 备份的几个关键点
1.通过上面的介绍,小伙伴们了解到 appendfsync 的取值一共有三种,我们在项目中首选 everysec,always 选项会严重降低 redis 性能。
2.使用 everysec ,最坏的情况下我们可能丢失1秒的数据。
# AOF 文件的重写与压缩
AOF 备份有很多明显的优势,当然也有劣势,那就是文件大小。随着系统的运行,AOF 的文件会越来越大,甚至把整个电脑的硬盘填满,AOF 文件的重写与压缩机制可以在一定程度上缓解这个问题。
当 AOF 的备份文件过大时,我们可以向 redis 发送一条 bgrewriteaof 命令进行文件重写,如下:
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
(0.71s)
bgrewriteaof 的执行原理和我们上文说的 bgsave 的原理一致,这里我就不再赘述,因此 bgsave 执行过程中存在的问题在这里也一样存在。
bgrewriteaof 也可以自动执行,自动执行时间则依赖于 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 配置,auto-aof-rewrite-percentage 100 表示当目前 aof 文件大小超过上一次重写时的 aof 文件大小的百分之多少时会再次进行重写,如果之前没有重写,则以启动时的 aof 文件大小为依据,同时还要求 AOF 文件的大小至少要大于 64M(auto-aof-rewrite-min-size 64mb)。
# 最佳实践
- 如果 redis 只做缓存服务器,那么可以不使用任何持久化方式。
- 同时开启两种持久化方式,在这种情况下,当 redis 重启的时候会优先载入 AOF 文件来恢复原始的数据, 因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整;RDB 的数据不完整时,同时使用两者时服务器重启也只会找 AOF 文件。那要不要只使用 AOF 呢? 作者建议不要,因为 RDB 更适合用于备份数据库( AOF 在不断变化不好备份), 快速重启,而且不会有 AOF 可能潜在的 bug ,留着作为一个万一的手段。
- 因为 RDB 文件只用作后备用途,建议只在 slave 上持久化 RDB 文件,而且只要 15 分钟备份一次就够了,只保留 save 900 1 这条规则。
- 如果 Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只 load 自己的 AOF 文件就可以了。代价一是带来了持续的 IO,二是 AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少 AOF rewrite 的频率,AOF 重写的基础大小默认值 64M 太小了,可以设到 5G 以上。默认超过原大小 100% 大小时重写可以改到适当的数值。
- 如果不 Enable AOF ,仅靠 Master-Slave Replication 实现高可用性也可以。能省掉一大笔 IO 也减少了 rewrite 时带来的系统波动。代价是如果 Master/Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB 文件,载入较新的那个。
OK,redis 数据持久化我们就介绍这么多,更多资料,小伙伴们可以参考官方文档。小伙伴在看官方文档时,有什么问题欢迎留言讨论。