Redis 持久化机制

Redis 工作时数据都存储在内存中,万一服务器断电,则所有数据都会丢失。针对这种情况,Redis 采用持久化机制来增强数据安全性。

1、RDB(保存数据)

① 机制描述

每隔一定的时间把内存中的数据作为一个快照保存到硬盘上的文件中。Redis 默认开启 RDB 机制。

② 触发时机

[1]基于默认配置

查看 redis 的配置文件 redis.conf:

含义:

配置含义
save 900 1900 秒内至少有一次修改则触发保存操作
save 300 10300 秒内至少有 10 次修改则触发保存操作
save 60 1000060 秒内至少有 1 万次修改则触发保存操作

[2]使用保存命令

save 或 bgsave

[3]使用 flushall 命令

这个命令也会产生 dump.rdb 文件,但里面是空的,没有意义

[4]服务器关闭

如果执行 SHUTDOWN 命令让 Redis 正常退出,那么此前 Redis 就会执行一次持久化保存。

③ 相关配置

配置项取值作用
save“”禁用 RDB 机制
dbfilename文件名,例如:dump.rdb设置 RDB 机制下,数据存储文件的文件名
dirRedis 工作目录路径指定存放持久化文件的目录的路径。注意:这里指定的必须是目录不能是文件名

2、AOF(保存命令)

① 机制描述

根据配置文件中指定的策略,把生成数据的命令保存到硬盘上的文件中。

②AOF 基本配置

配置项取值作用
appendonlyyes启用 AOF 持久化机制
no禁用 AOF 持久化机制[默认值]
appendfilename“文件名”AOF 持久化文件名
dirRedis 工作目录路径指定存放持久化文件的目录的路径。注意:这里指定的必须是目录不能是文件名
appendfsyncalways每一次数据修改后都将执行文件写入操作,缓慢但是最安全。
everysec每秒执行一次写入操作。折中。
no由操作系统在适当的时候执行写入操作,最快。

③AOF 重写

对比下面两组命令:

AOF 重写前AOF 重写后
set count 1
incr count
incr count
incr count
set count 4

两组命令执行后对于 count 来说最终的值是一致的,但是进行 AOF 重写后省略了中间过程,可以让 AOF 文件体积更小。而 Redis 会根据 AOF 文件的体积来决定是否进行 AOF 重写。参考的配置项如下:

配置项含义
auto-aof-rewrite-percentage 100文件体积增大 100%(体积翻倍)时执行 AOF 重写
auto-aof-rewrite-min-size 64mb文件体积增长到 64mb 时执行 AOF 重写

实际工作中不要进行频繁的 AOF 重写,因为 CPU 资源和硬盘资源二者之间肯定是 CPU 资源更加宝贵,所以不应该过多耗费 CPU 性能去节省硬盘空间。

3、持久化文件损坏修复

Redis 服务器启动时如果读取了损坏的持久化文件会导致启动失败,此时为了让 Redis 服务器能够正常启动,需要对损坏的持久化文件进行修复。这里以 AOF 文件为例介绍修复操作的步骤。

  • 第一步:备份要修复的 appendonly.aof 文件

  • 第二步:执行修复程序

    /usr/local/redis/bin/redis-check-aof –fix /usr/local/redis/appendonly.aof

  • 第三步:重启 Redis

注意:所谓修复持久化文件仅仅是把损坏的部分去掉,而没法把受损的数据找回。

4、两种持久化机制的取舍

①RDB

[1]优势

适合大规模的数据恢复,速度较快

[2]劣势

会丢失最后一次快照后的所有修改,不能绝对保证数据的高度一致性和完整性。Fork 的时候,内存中的数据被克隆了一份,大致 2 倍的膨胀性需要考虑,但上述成立有条件,Linux 也有优化手段

②AOF

[1]优势

选择 appendfsync always 方式运行时理论上能够做到数据完整一致,但此时性能又不好。文件内容具备一定可读性,能够用来分析 Redis 工作情况。

[2]劣势

持久化相同的数据,文件体积比 RDB 大,恢复速度比 RDB 慢。效率在同步写入时低于 RDB,不同步写入时与 RDB 相同。

③RDB 和 AOF 并存

Redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整

RDB 的数据不实时,同时使用两者时服务器重启也只会找 AOF 文件。那要不要只使用 AOF 呢?作者建议不要,因为 RDB 更适合用于备份数据库(AOF 在不断变化不好备份)、快速重启,而且不会有 AOF 可能潜在的 bug,留着作为一个万一的手段。

④ 使用建议

如果 Redis 仅仅作为缓存可以不使用任何持久化方式。

其他应用方式综合考虑性能和完整性、一致性要求。

RDB 文件只用作后备用途,建议只在 Slave 上持久化 RDB 文件,而且只要 15 分钟备份一次就够了,只保留save 900 1这条规则。

如果 Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只 load 自己的 AOF 文件就可以了。代价一是带来了持续的 IO,二是 AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少 AOF rewrite 的频率,AOF 重写的基础大小默认值 64M 太小了,可以设到 5G 以上。默认超过原大小 100%大小时重写可以改到适当的数值。

如果不开启 AOF,仅靠Master-Slave Replication 实现高可用性能也不错。能省掉一大笔 IO 也减少了 rewrite 时带来的系统波动。代价是如果 Master/Slave 同时出现故障,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB 文件,载入较新的那个。新浪微博就选用了这种架构。

5、模式的抉择应用场景介绍

AOF 和 RDB 对比:

命令RDBAOF
启动优先级
体积
恢复速度
数据安全性丢数据根据策略决定

RDB 的最佳策略:

  • 关闭
  • 集中管理(用于备份数据)
  • 主从模式,从开。

AOF 的最佳策略:

  • 建议 开 每秒刷盘(同步)->aof 日志文件中
  • AOF 重写集中管理

最佳的策略:

  • 小分片(max_memery 4G 左右)
  • 监控机器的负载-哨兵