Redis持久化的两种方式是什么

文章导读
Redis 的持久化通常就两种:RDB 快照和 AOF 追加日志。搜这个问题的人多数是在改配置之前想先确认一件事——我这台实例现在到底开了哪一种、要不要两个都开。所以要按顺序来:先确认现状,再看两者差别,最后再动手改配置,别一上来就加一行 appendonly yes 重启。
📋 目录
  1. A Redis持久化的两种方式有哪些
  2. B Redis持久化的两种方式中aof与rdb各有什么特点
  3. C 持久化的两种方式:先把能核对的事实摆清楚
  4. D 持久化的两种方式最容易搞错的一点
  5. E 持久化的两种方式:一个照着就能做完的做法
A A

Redis 的持久化通常就两种:RDB 快照和 AOF 追加日志。搜这个问题的人多数是在改配置之前想先确认一件事——我这台实例现在到底开了哪一种、要不要两个都开。所以要按顺序来:先确认现状,再看两者差别,最后再动手改配置,别一上来就加一行 appendonly yes 重启。

判断顺序是:先用 redis-cli CONFIG GET save、CONFIG GET appendonly 和 INFO persistence 确认当前实例开了哪一种,再去改配置。RDB 是周期性快照,文件小、恢复快,但会丢最后一次快照之后的数据;AOF 是命令追加日志,丢数据窗口小,但文件更大、恢复更慢。两者可以同时开启,但重启加载时以 AOF 为准。是否都开,取决于你能接受丢多少数据,这个需要结合版本和磁盘余量自行确认。

Redis持久化的两种方式有哪些

这一步在第 0 位:先把候选集合定下来,再去判断实例属于哪一种。Redis 里能落盘的机制就是 RDB 和 AOF 两条,混合持久化(aof-use-rdb-preamble)不是第三种独立方式,它是 AOF 重写时把前半段写成 RDB 格式,加载时仍走 AOF 通道。要核对这一点,直接看配置项和 INFO 输出即可:

redis-cli CONFIG GET save
redis-cli CONFIG GET appendonly
redis-cli CONFIG GET aof-use-rdb-preamble
redis-cli INFO persistence

INFO persistence 里,rdb_last_save_time、rdb_changes_since_last_save 反映 RDB 侧;aof_enabled(老版本)、aof_last_write_status、aof_rewrite_in_progress 反映 AOF 侧。日志里也有能核对的行:启动时加载 RDB 会打 DB loaded from disk,加载 AOF 会打 DB loaded from append only file,后台快照会打 Background saving started by pid。注意不要拿 /etc/redis/redis.conf 想当然,先用 INFO server 里的 config_file 字段和 CONFIG GET dir 确认进程实际加载的是哪个文件、数据目录在哪。

Redis持久化的两种方式中aof与rdb各有什么特点

两者差别不用背结论,用下面的配置项就能当场核对:

Redis持久化的两种方式是什么
  • RDB 侧看 save 的三元组(如 900 1、300 10、60 10000)、dbfilename、dir。特点:二进制快照,文件通常更小,加载快;代价是两次快照之间的写入没有落盘,进程被强杀会丢这一段。
  • AOF 侧看 appendonly、appendfsync、appendfilename、auto-aof-rewrite-percentage、auto-aof-rewrite-min-size。特点:按命令追加写,appendfsync everysec 时通常只丢约一秒内未刷盘的写入;代价是文件通常更大,重启加载要重放命令,慢于 RDB。
  • appendfsync always 每次都刷盘,落盘最稳,但对写入延迟影响明显,是否可接受要结合业务确认。
  • Redis 7 之后 AOF 默认放在 appendonlydir 目录并由 manifest 文件管理,和旧版本的单文件 appendonly.aof 不一样,排查时先确认版本:redis-cli INFO server 里的 redis_version。

核对文件是否真在写:ls -l 看 dir 下 dump.rdb 或 appendonlydir 里文件的大小和 mtime 是否在变化,这比只看配置项可靠。

持久化的两种方式:先把能核对的事实摆清楚

先不下结论,把对象和现象摆出来。对象:实例版本、部署形态(单机/主从/集群)、数据目录。前提:能接受丢多少数据、磁盘还剩多少、是否允许重启。现象:

Redis持久化的两种方式是什么
  • CONFIG GET save 返回空表示 RDB 快照规则被关掉,但它不影响手动 BGSAVE。
  • CONFIG GET appendonly 返回 yes 表示 AOF 通道开启,具体刷盘频率还要看 appendfsync。
  • INFO persistence 的 rdb_last_bgsave_status、aof_last_bgrewrite_status 是 ok 还是 err,直接说明上一次落盘是否成功。
  • dir 目录的剩余空间,AOF 重写期间会同时存在新旧文件,空间不够会导致重写失败。
  • 日志中的 Background saving terminated with success / Can't save in background: fork 这类行,是判断 fork 是否失败的依据。

持久化的两种方式最容易搞错的一点

最常见的误解是「两个都开就等于双保险,重启时两份数据都会加载」。实际上 appendonly yes 时,Redis 启动只加载 AOF,dump.rdb 不会被合并进去。所以如果 AOF 因为写到一半被截断而损坏,即使 dump.rdb 完好,也不会自动回退去读它。

能区分这两种情况的检查动作:在一个测试实例上,先确认 CONFIG GET appendonly 为 yes,然后停掉 Redis,把 dump.rdb 改名藏起来,再启动,看数据是否还在——在就说明走的是 AOF。这个动作只建议在测试实例做,生产上先做备份再考虑。反过来说,如果你想验证 RDB 是否可用,就在 AOF 关闭的前提下做同样的测试。

持久化的两种方式:一个照着就能做完的做法

以下是一条完整路径,命令和配置都可直接替换成你的路径后执行。

Redis持久化的两种方式是什么
# 1. 记录现状,作为回滚依据
redis-cli INFO server | grep -E 'redis_version|config_file'
redis-cli CONFIG GET dir
redis-cli CONFIG GET save
redis-cli CONFIG GET appendonly
redis-cli CONFIG GET appendfsync
redis-cli INFO persistence
cp /etc/redis/redis.conf /etc/redis/redis.conf.bak

# 2. 在配置文件里补上这两段(路径按 CONFIG GET dir 的结果改)
dir /var/lib/redis
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 3. 重启后在测试实例上触发一次落盘并核对
redis-cli BGSAVE
redis-cli BGREWRITEAOF
redis-cli INFO persistence
ls -l /var/lib/redis

每一步该看到什么:第 2 步改完配置文件后,CONFIG GET 的返回值在重启前不会变,别拿它判断是否生效;第 3 步重启后再跑 CONFIG GET appendonly 应返回 yes,INFO persistence 里 rdb_last_bgsave_status 与 aof_last_bgrewrite_status 应为 ok,rdb_changes_since_last_save 会归零,ls 看到的 dump.rdb 或 appendonlydir 下文件 mtime 应该是刚刚。

如果要验证真能恢复,在确认是测试实例、且已经备份的前提下,可以考虑用 redis-cli DEBUG RELOAD 重载一次数据,观察 key 数量是否一致。DEBUG RELOAD 会丢掉未持久化的写入,生产环境不要随手执行。另外,appendonly 从 no 改成 yes 的生效方式在不同版本上表现不同,有的版本需要重启才能完成切换,这一点建议按你实例的版本在 CONFIG SET 之后用 INFO persistence 的实际变化来确认,而不是凭印象操作。