先说结论
Redis 通过 RDB 快照和 AOF 日志实现数据持久化,通过异步主从复制保存副本,使用 Sentinel 完成主从架构的监控与自动切换,或使用 Redis Cluster 同时实现分片和故障转移。它们通常只能降低数据丢失风险,不能自动提供跨节点强一致。
RDB 快照
RDB 在某个时间点生成内存数据快照文件,适合备份、全量复制和快速恢复。
优点:
- 文件紧凑,适合备份和跨机房传输。
- 重启恢复通常比重放大量 AOF 快。
- 主进程主要负责 Fork,具体写文件由子进程完成。
不足:
- 两次快照之间的数据可能在故障时丢失。
- Fork 大进程会带来页表复制和延迟抖动。
- 快照期间写入导致 Copy-on-Write,可能增加内存峰值。
- 磁盘慢或内存大时生成时间较长。
Fork 和 Copy-on-Write
生成 RDB 时,子进程读取 Fork 时刻的内存视图。主进程继续处理写入;被修改的内存页复制后由主进程使用,子进程仍看到旧页。
因此执行 BGSAVE 时要关注:
- 实例内存大小。
- 系统剩余内存。
- 写入速率。
- Transparent Huge Pages。
- Fork 耗时和磁盘吞吐。
高写入期间 COW 可能让 RSS 明显增长,容器 Limit 过紧会导致 OOMKilled。
AOF 日志
AOF 记录会改变数据的写命令,重启时重放恢复。
常见刷盘策略:
- Always:每条命令同步磁盘,安全性高但吞吐和延迟成本大。
- Everysec:通常每秒刷盘一次,性能与数据安全折中,故障时可能丢约一秒数据。
- No:由操作系统决定刷盘,性能较好但丢失窗口更大。
生产常选择 Everysec,但要根据业务可接受的数据损失目标决定。
AOF Rewrite
AOF 持续追加会不断变大。Rewrite 根据当前内存状态生成等价但更紧凑的命令,例如一个 Key 被修改一万次,重写后只保留恢复当前值所需的命令。
Rewrite 同样涉及 Fork、COW、CPU 和磁盘 IO。不能只关注 AOF 文件大小,还要监控重写持续时间、失败次数和磁盘余量。
RDB 和 AOF 怎么选
| 维度 | RDB | AOF |
|---|---|---|
| 数据丢失窗口 | 快照间隔 | 取决于刷盘策略 |
| 文件大小 | 通常较小 | 通常较大 |
| 恢复速度 | 通常较快 | 需要重放日志 |
| 运行开销 | 周期性 Fork 与写文件 | 持续追加与定期重写 |
| 备份 | 适合 | 也可使用但管理更复杂 |
重要数据可以同时开启 RDB 和 AOF。具体 Redis 版本的加载优先级和混合持久化能力需要结合官方文档和配置确认。
混合持久化
混合模式在 AOF 重写文件前部保存 RDB 格式快照,后部追加重写期间的命令,兼顾恢复速度和 AOF 的较小数据丢失窗口。
启用前要确认 Redis 版本、运维工具和备份流程都支持该格式。
持久化不等于备份
误删除和错误写入也会进入 AOF 和副本。持久化用于进程重启恢复,高可用用于实例故障切换,历史恢复仍需要独立备份、保留周期和恢复演练。
主从复制流程
Replica 连接 Master
↓
身份验证与复制握手
↓
能增量同步?
├── 是:发送积压缓冲区中的命令
└── 否:生成 RDB 全量同步
↓
Replica 加载快照
↓
持续接收新写命令
主从复制通常异步,Master 执行成功后不会等待所有 Replica 应用。因此刚写入的数据可能暂时无法从 Replica 读取,Master 故障时尚未同步的数据也可能丢失。
全量同步
Replica 首次加入或断线太久时进行全量同步。Master 生成快照并发送,同时把期间的新写命令保存在缓冲区;Replica 加载快照后再应用增量命令。
大实例全量同步会消耗 Fork、磁盘、网络和 Replica 加载时间。多个 Replica 同时全量同步可能形成复制风暴。
增量同步
Master 维护复制 ID、Offset 和复制积压缓冲区。Replica 短暂断线重连后,如果缺失数据仍在缓冲区,可以只补发断线期间命令。
缓冲区过小会让稍长网络抖动退化为全量同步。大小应结合写入速率和预期最长断线时间配置。
复制延迟
常见原因:
- 网络延迟或带宽不足。
- Replica CPU、磁盘或内存压力。
- Master 大量写入。
- Big Key 传输和处理。
- Lua 或慢命令阻塞事件循环。
- Replica 执行持久化和全量同步。
读写分离时必须接受短暂旧数据。写后立刻读取关键状态应读 Master,或使用业务版本校验。
Sentinel 解决什么问题
Sentinel 监控 Master 和 Replica,在 Master 故障时选择 Replica 提升为新 Master,并通知其他 Replica 和客户端切换。
它提供:
- 监控与故障检测。
- 主观下线和客观下线判断。
- Leader Sentinel 选举。
- Replica 选主和故障转移。
- 客户端获取当前 Master 地址。
Sentinel 不负责数据分片,数据集仍完整保存在每个 Master/Replica 节点。
主观下线与客观下线
单个 Sentinel 认为节点不可达是主观下线。达到配置数量的 Sentinel 都认为 Master 不可达,才形成客观下线并尝试故障转移。
这样可以减少单个 Sentinel 网络异常造成误切换,但仍需合理部署到不同故障域,并处理网络分区。
Sentinel 选新 Master 的考虑
通常综合 Replica 优先级、复制状态、数据 Offset 和稳定性选择。数据越接近原 Master 的 Replica 越适合提升。
故障切换期间客户端会经历短暂失败,需要使用支持 Sentinel 的客户端并配置重连、有限重试和幂等。
脑裂和数据丢失
网络分区时旧 Master 可能仍接收写入,而 Sentinel 在另一侧提升新 Master。网络恢复后旧 Master 降为 Replica,它在分区期间接收的写入可能丢失。
可通过限制 Master 在可用 Replica 不足或复制延迟过大时拒绝写入,降低脑裂损失。但这是用可用性换数据安全,仍无法提供严格共识一致性。
Redis Cluster
Cluster 将 16384 个 Slot 分配给多个 Master,每个 Master 管理部分数据,并可配置 Replica。
Key → CRC16 → Slot 0..16383 → 对应 Master
它解决:
- 数据容量超过单机内存。
- 写入和读取压力水平分散。
- 单 Master 故障时由 Replica 提升。
MOVED 和 ASK
客户端请求到错误节点时:
- MOVED 表示 Slot 已稳定属于另一个节点,客户端应更新拓扑缓存。
- ASK 常见于 Slot 迁移过程中,表示本次请求临时去目标节点,但不立即永久修改归属。
生产应使用支持 Cluster 拓扑感知的客户端,不要自己手写重定向逻辑。
Cluster 的限制
- 多 Key 操作通常要求 Key 在同一 Slot。
- 故障切换仍可能丢失未同步写入。
- Slot 迁移时 Big Key 会造成抖动。
- 节点扩缩容涉及数据迁移和带宽。
- 热 Key 可能让单 Slot、单节点过载。
- Cluster Bus 和节点数量增加运维复杂度。
Sentinel 和 Cluster 怎么选
- 数据量能放入单机、主要需要自动主从切换:Sentinel。
- 数据量或吞吐需要水平分片:Cluster。
- 强一致事务、跨 Key 复杂关系:重新评估 Redis 是否适合做事实源。
云厂商代理版 Redis 可能隐藏 Sentinel 或 Cluster 细节,但数据丢失窗口、分片限制和故障语义仍需向厂商确认。
故障切换期间客户端设计
- 使用连接池和拓扑感知客户端。
- 设置连接、命令和重试超时。
- 只对幂等操作进行有限重试。
- 写失败不能无限重试并堵塞业务线程。
- 关键写入要有数据库或消息日志作为事实源。
- 熔断和降级避免重连风暴。
数据恢复流程
- 隔离故障实例,避免继续接受写入。
- 保存 RDB、AOF 和日志副本。
- 在隔离环境验证文件完整性。
- 启动临时实例加载数据。
- 对比业务数据库或事件日志进行校验。
- 根据恢复点补偿缺失数据。
- 灰度切换流量并持续观察。
不要直接拿未经验证的持久化文件覆盖线上当前数据。
监控指标
used_memory、RSS 和内存碎片率。- RDB/AOF 最近成功时间和失败次数。
- AOF 重写状态和文件大小。
- 主从复制 Offset 和延迟。
- Replica 连接状态与全量同步次数。
- Sentinel 切换事件。
- Cluster Slot 覆盖和失败节点。
- 磁盘容量、Fork 耗时和 COW 内存。
容易踩坑的地方
- 开启 AOF 就绝对不丢数据。
- 有 Replica 就等于完成备份。
- Sentinel 能解决数据分片。
- Cluster 能提供强一致。
- Redis 只使用内存,磁盘性能不重要。
- Fork 不会影响线上延迟。
- 故障切换后客户端会自动无感恢复。
常见问题
追问 1:RDB 和 AOF 应该怎么选?
缓存可只使用 RDB 或接受重建;重要数据通常同时使用 RDB 与 AOF,并选择 Everysec 等合适刷盘策略。但 Redis 仍不应替代关键业务事实数据库。
追问 2:AOF Everysec 会丢多少数据?
通常可能丢失最近约一秒尚未同步磁盘的数据,但具体还受操作系统、磁盘和 Redis 实现影响。机器或磁盘故障场景不能做绝对承诺。
追问 3:为什么主从切换会丢数据?
复制异步,Master 已确认但尚未发送或 Replica 尚未应用的写入,在原 Master 故障后不会存在于新 Master。
追问 4:Sentinel 需要几个节点?
通常至少三个并部署在不同故障域,以形成多数判断。还要根据 Quorum 和故障转移授权配置,不能只看进程数量。
追问 5:Redis Cluster 为什么是 16384 个 Slot?
Slot 是 Key 到节点之间的逻辑分片层,便于迁移和拓扑管理。固定数量在集群消息开销和分片粒度间折中,客户端无需为每个 Key 保存节点映射。
追问 6:如何减少脑裂造成的数据丢失?
限制 Master 在可用 Replica 数不足或复制延迟过大时拒绝写入,将节点分布在合理故障域,并让关键业务拥有外部事实源和补偿。这会牺牲部分可用性。
追问 7:持久化文件损坏怎么办?
先复制原文件,在隔离环境使用官方检查和修复工具评估,再结合历史备份和业务事实源恢复。不要直接在唯一线上副本上操作。