
个人主页 for_ever_love__ 欢迎各位大佬莅临其他栏目: 大模型开发从0到1 其他栏目: iOS项目总结大全 其他栏目: 我想学python了 其他栏目: iOS UI 文章目录Redis 持久化讲透RDB、AOF 与混合持久化怎么选一、为什么要两种机制二、RDB快照2.1 触发方式2.2 原理fork Copy-On-Write2.3 RDB 的优缺点三、AOF追加日志3.1 原理3.2 刷盘策略决定安全性3.3 AOF 重写解决文件膨胀3.4 AOF 的优缺点四、混合持久化Redis 4.0五、生产怎么配决策表推荐配置大多数场景如果只当缓存用六、启动时加载哪个文件七、运维实操7.1 查看持久化状态7.2 备份策略7.3 监控指标八、三个常见误区九、小结Redis 持久化讲透RDB、AOF 与混合持久化怎么选Redis 是内存数据库断电数据就没了。持久化就是把内存数据落盘的机制。本篇讲清楚 RDB 和 AOF 各自的机制、优缺点、混合持久化是什么、以及生产到底该怎么配。一、为什么要两种机制先说结论RDB 和 AOF 是两种完全不同的思路。RDBAOF思路快照某个时刻的全量数据日志记录每一条写命令内容二进制压缩数据文本协议格式的命令恢复直接加载快逐条重放慢文件大小小大数据安全性丢最后一次快照之后的数据最多丢 1 秒取决于刷盘策略这个对比决定了它们的定位RDB 适合备份和快速恢复AOF 适合保证数据安全。二、RDB快照2.1 触发方式自动触发配置save规则# redis.conf save 3600 1 # 3600 秒内有 1 次修改就触发 save 300 100 # 300 秒内有 100 次修改 save 60 10000 # 60 秒内有 10000 次修改满足任意一个条件就触发。多个条件是为了在不同写入压力下都能有合理的快照频率。手动触发redis-cli SAVE# ⚠️ 阻塞主进程执行期间不能处理任何请求redis-cli BGSAVE# ✅ 后台执行fork 子进程处理生产只用BGSAVE永远不要用SAVE。其他触发时机主从复制时主库收到SYNC会自动BGSAVE执行SHUTDOWN时如果没开 AOFFLUSHALL也会触发生成一个空快照2.2 原理fork Copy-On-WriteBGSAVE的过程1. 主进程 fork() 出一个子进程 ├─ 子进程和主进程共享同一份内存页表复制不复制物理内存 │ 2. 子进程把内存数据写入临时 RDB 文件 │ 3. 主进程继续处理请求 ├─ 如果有写请求被修改的内存页会被复制一份COW ├─ 主进程改副本子进程看到的还是 fork 那一刻的快照 │ 4. 子进程写完用临时文件替换旧的 RDB 文件关键技术是 Copy-On-Write写时复制fork 时并不真的复制内存那样太慢而是让父子进程共享物理页只有某页被修改时才复制那一页。⚠️COW 的内存开销如果 fork 之后有大量写入被修改的页都要复制内存占用可能瞬间翻倍。所以要预留内存Redis 实际使用内存不要超过机器的 45%~50%。⚠️fork 本身会短暂阻塞虽然 fork 不复制内存但复制页表需要时间。内存越大页表越大fork 越慢。几十 GB 的实例 fork 可能阻塞几百毫秒。# 监控最近一次 fork 耗时微秒INFO stats# latest_fork_usec: 12345 ← 12ms2.3 RDB 的优缺点✅优点文件紧凑二进制压缩适合备份恢复速度快直接加载fork 后主进程几乎不受影响适合做灾难恢复把 RDB 文件拷到别的地方❌缺点会丢数据两次快照之间的数据宕机就没了fork 有阻塞风险大实例频繁快照会导致大量磁盘 IO三、AOF追加日志3.1 原理每执行一条写命令就把这条命令以 Redis 协议格式追加到 AOF 文件末尾。SET nameTom# AOF 文件里记录RESP 协议格式*3$3SET$4name$3Tom启动时重新执行 AOF 文件里的所有命令来恢复数据。3.2 刷盘策略决定安全性这是 AOF 最关键的配置项appendfsync always # 每条命令都 fsync最安全性能最差 appendfsync everysec # 每秒 fsync 一次折中默认 appendfsync no # 交给操作系统决定最快最不安全策略数据安全性能always最多丢 1 条命令每个写都要刷盘QPS 大幅下降everysec默认推荐最多丢 1 秒数据很好no可能丢很多OS 通常 30 秒刷一次最好生产用everysec这是安全性与性能的平衡点。# 查看配置CONFIG GET appendfsync3.3 AOF 重写解决文件膨胀问题不断追加文件会越来越大。INCR counter# 执行 1000 次# AOF 里记录 1000 条 INCR 命令# 但恢复时只需要最终的 counter 1000AOF 重写Rewrite根据当前内存数据生成一份能重建当前状态的最小命令集。redis-cli BGREWRITEAOF# 后台重写自动触发配置auto-aof-rewrite-percentage 100 # 比上次重写后增长了 100% auto-aof-rewrite-min-size 64mb # 且文件至少 64MB重写原理跟 RDB 类似fork 子进程子进程读当前内存数据生成新 AOF写的是最终值命令不是历史命令期间主进程的新写命令同时追加到旧 AOF 缓冲区和重写缓冲区子进程写完主进程把重写缓冲区的增量命令追加到新 AOF新 AOF 原子替换旧文件3.4 AOF 的优缺点✅优点数据安全性高everysec最多丢 1 秒AOF 是文本格式虽然协议格式不直观便于人工检查和修复写错了可以用redis-check-aof修❌缺点文件比 RDB 大恢复慢要逐条重放命令重写时有 fork 开销# AOF 文件损坏时修复redis-check-aof--fixappendonly.aof四、混合持久化Redis 4.0这是现在的最优解结合两者优点aof-use-rdb-preamble yes # 4.0 默认开启机制AOF 重写时子进程把当前内存数据以RDB 二进制格式写入新 AOF 文件的开头重写期间的增量命令以AOF 文本格式追加在后面┌─────────────────────────┐ │ RDB 格式的全量数据 │ ← 恢复时直接加载快 ├─────────────────────────┤ │ AOF 格式的增量命令 │ ← 保证数据完整 └─────────────────────────┘效果恢复速度快RDB 部分 数据丢失少AOF 部分。# 查看是否开启CONFIG GET aof-use-rdb-preamble# 1) aof-use-rdb-preamble# 2) yes五、生产怎么配决策表场景建议纯缓存数据丢了可从 DB 重建可以不开持久化save 一般业务缓存允许少量丢失只开 RDB重要数据不能丢RDB AOF 都开混合持久化极致性能数据不重要全关推荐配置大多数场景# RDB save 3600 1 save 300 100 save 60 10000 dbfilename dump.rdb dir /var/lib/redis # AOF appendonly yes appendfsync everysec aof-use-rdb-preamble yes # 混合持久化 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 重要AOF 和 RDB 都开时启动时用 AOF 恢复数据更全如果只当缓存用save # 关闭 RDB appendonly no # 关闭 AOF maxmemory 4gb maxmemory-policy allkeys-lru⚠️ 但要注意即使关了持久化主从复制仍然依赖 RDB全量同步时主库要生成 RDB。所以完全关掉 RDB 可能导致主从全量同步失败。稳妥做法是关 AOF保留 RDB。六、启动时加载哪个文件优先级AOF 高于 RDB。启动时 ├─ appendonly yes 且存在 AOF 文件 → 加载 AOF数据更全 └─ 否则 → 加载 RDB⚠️ 一个坑如果开着 AOF但 AOF 文件损坏或为空Redis 会加载空的 AOF导致数据看起来全没了。这时候不要慌关掉 AOF 重启就能从 RDB 恢复。# 应急临时关闭 AOF 从 RDB 恢复redis-cli CONFIG SET appendonly no# 重启后数据从 RDB 加载# 确认数据没问题再重新开启会触发一次重写生成新 AOFredis-cli CONFIG SET appendonlyyes七、运维实操7.1 查看持久化状态INFO persistence关键字段rdb_last_bgsave_status:ok # 上次 BGSAVE 是否成功 rdb_last_save_time:1730000000 # 上次成功保存的时间戳 rdb_changes_since_last_save:15 # 距上次保存后有多少次修改 aof_enabled:1 # AOF 是否开启 aof_last_bgrewrite_status:ok # 上次重写是否成功 aof_last_write_status:ok # ⚠️ 如果这里是 err 要警惕⚠️aof_last_write_status:err是危险信号说明 AOF 刷盘失败通常是磁盘满了此时 Redis 会拒绝写入默认no-appendfsync-on-rewrite的策略。7.2 备份策略# 定期备份 RDBcrontab03* * *cp/var/lib/redis/dump.rdb /backup/redis/dump_$(date\%Y\%m\%d).rdb要点RDB 文件要异地备份不能只在本机定期验证备份能否恢复很多人备份了从没验证过保留多份按天保留 7~30 天7.3 监控指标指标命令告警阈值最近 fork 耗时INFO stats→latest_fork_usec 5000000.5秒AOF 写入状态INFO persistence→aof_last_write_status非 ok距上次保存的修改数rdb_changes_since_last_save持续增长说明没触发AOF 文件大小文件系统监控增长过快要检查重写八、三个常见误区误区 1开了 AOF 就不会丢数据——everysec最多丢 1 秒的数据。要真的不丢得用always但性能会崩。Redis 的定位本来就不是强一致存储。误区 2RDB 的 fork 不影响业务——fork 会短暂阻塞主进程大实例几十 GB可能阻塞几百毫秒到秒级。监控latest_fork_usec。误区 3AOF 文件可以直接看懂——AOF 是RESP 协议格式不是可读的SET key value。虽然比二进制好但也不算可读。九、小结RDB 快照文件小、恢复快、但会丢快照之后的数据AOF 日志数据安全性高最多丢 1 秒、文件大、恢复慢生产必用appendfsync everysecalways太慢no太危险混合持久化4.0 默认最优AOF 文件里 RDB 全量 AOF 增量Redis 的 fork 靠Copy-On-Write但 COW 会让内存临时上涨Redis 内存不要超过机器内存的 50%启动时 AOF 优先于 RDBAOF 损坏时关掉 AOF 可从 RDB 恢复纯缓存可以关持久化但建议保留 RDB主从复制依赖它监控latest_fork_usec和aof_last_write_statusRDB 要异地备份并定期验证可恢复下一篇讲缓存三大问题——穿透、击穿、雪崩。这是 Redis 用作缓存时最经典、也最容易引发线上事故的三个场景。