Redis 持久化与高可用实践(RDB / AOF / Sentinel / Cluster 全解析)

这篇是我把几套生产环境踩坑与复盘整理成的一份"从 0 到 1 + 长期可维护"的实践文。目标是:明确策略、给出默认可用的配置模板、把常见坑一次讲透

适用场景:新项目选型、老项目稳定性加固、从单机迁移到 HA/Cluster、应对数据安全与故障切换要求。


目录

  1. 核心结论先说在前面

  2. 持久化:RDB vs AOF(以及"二者结合"的推荐范式)

  3. 高可用形态:主从复制基础、Sentinel、Cluster

  4. 典型拓扑与配置模板(可直接改名上线)

  5. 备份/恢复/演练:从脚本到流程

  6. 性能与稳定性调优(内核、Redis 配置、内存与淘汰)

  7. 生产避坑清单(高频问题→定位→对策)

  8. 迁移与升级策略(Standalone→Sentinel、Sentinel→Cluster)

  9. 运维清单与值班自检表


1. 核心结论先说在前面

  • 持久化策略

    • 低延迟场景:首选 RDB + AOF(everysec) 组合。RDB 提供"冷备点",AOF 控制丢失窗口(通常 ≤1s)。

    • 极端数据安全:AOF(appendfsync always),但写放大大、吞吐下降明显,一般不建议全站开启。

    • 只读/可丢缓存:可以 仅 RDB 或甚至关闭持久化,靠上游重建(但要清楚发生重启的业务影响)。

  • 高可用形态

    • 单实例 HA:主从 + Sentinel(入门首选,维护简单,客户端/驱动支持成熟)。

    • 水平扩展 + HA:Redis Cluster(3 主 3 备起步) 。选它是因为容量/吞吐/隔离/自治 ,也要接受跨槽限制

  • 复制一致性 :Redis 复制本质是异步。务必配合:

    • min-replicas-to-write / min-replicas-max-lag(提升写安全,避免主孤岛)

    • 按需使用 WAIT 命令等待复制到 N 个副本再返回(强一致片段,但影响时延)。

  • 默认稳妥配置(可作为起步模板):

    • appendonly yesappendfsync everysecno-appendfsync-on-rewrite yes

    • save 900 1 / save 300 10 / save 60 10000(按业务写入频率调整)

    • stop-writes-on-bgsave-error yes(防止静默数据丢失)

    • repl-backlog-size 256mb(按主写入速率与断链窗口估算)

    • maxmemory + 合理淘汰策略(缓存型业务尤为重要)


2. 持久化:RDB vs AOF(以及"二者结合"的推荐范式)

2.1 RDB(快照)

  • 原理 :定期把内存快照写入 .rdb 文件(BGSAVE 子进程)。

  • 优点:文件小、恢复快、对线上写入影响较小(写时复制)。

  • 缺点 :两次快照之间的新写入可能丢失

  • 关键配置

    复制代码
    # 触发条件按需调整(示例:90% 读多写少)
    save 900 1
    save 300 10
    save 60 10000
    
    rdbcompression yes
    rdbchecksum yes
    stop-writes-on-bgsave-error yes

2.2 AOF(追加日志)

  • 原理 :把写命令追加到日志;重启时"重放"恢复。Redis 新版本使用 多段 AOF(BASE/INCR),并支持 RDB 作为 AOF 前导以加速恢复。

  • 优点更小的数据丢失窗口everysec 常见);可以手工编辑修复尾部。

  • 缺点:文件膨胀、重写时可能有额外 I/O 压力。

  • 关键配置

    复制代码
    appendonly yes
    appendfsync everysec           # 安全与性能折中(常用)
    no-appendfsync-on-rewrite yes  # 重写期间尽量少阻塞
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    aof-load-truncated yes
    # 新版:AOF 使用 RDB 作为 preamble(通常默认开启,恢复更快)
    # aof-use-rdb-preamble yes

2.3 推荐组合:RDB + AOF(everysec)

  • 为什么:RDB 提供"恢复基线",AOF 提供"小丢失窗口";重启时优先加载 AOF,若 AOF 不可用仍可回退到 RDB。

  • 通用建议先做对的,再做快的。先把 AOF + 定期 RDB 固住,再谈参数与 I/O 优化。


3. 高可用形态:主从复制基础、Sentinel、Cluster

3.1 主从复制基础

  • 复制机制 :初次全量同步 + 之后命令流增量;断联后支持部分重同步(PSYNC)

  • 常用参数

    复制代码
    replica-read-only yes
    repl-diskless-sync yes
    repl-diskless-sync-delay 5
    repl-backlog-size 256mb
    min-replicas-to-write 1         # 至少有1个副本在线主才写
    min-replicas-max-lag 5          # 超过5s延迟则视为不安全
  • 只读从库:默认只读,适合做报表与只读流量分流(避免主库压力过大)。

3.2 Sentinel(哨兵)

  • 作用 :自动故障检测、投票选主、通知客户端新主地址

  • 部署 :至少 3 个哨兵实例 (奇数),建议与 Redis 节点分机房/可用区部署。

  • 核心配置sentinel.conf):

    复制代码
    port 26379
    daemonize yes
    
    # 监控一个 master:<name> <ip> <port> <quorum>
    sentinel monitor app-master 10.0.0.10 6379 2
    
    sentinel down-after-milliseconds app-master 5000
    sentinel failover-timeout app-master 60000
    sentinel parallel-syncs app-master 1
    
    # 可选:通知/脚本
    # sentinel notification-script app-master /opt/sentinel/notify.sh
    # sentinel client-reconfig-script app-master /opt/sentinel/reconfig.sh
  • 客户端接入

    • 方式一:连接哨兵,按 master name 查询主;

    • 方式二:用支持 Sentinel 的驱动(Java/Lettuce、Go/redis、Node/ioredis 等)自动刷新连接。

3.3 Redis Cluster(分片+高可用)

  • 特性:16384 槽位(hash slot)分布到多主节点,每个主有 ≥1 个副本;主节点故障时由副本升主。

  • 限制 :多键操作需在同槽 (可用 {tag} 控制);Lua 脚本/事务等有跨槽限制。

  • 常用参数redis.conf):

    复制代码
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 15000
    cluster-announce-ip 10.0.0.10     # 跨网段/容器时要显式设置
    cluster-announce-port 6379
    cluster-announce-bus-port 16379
  • 集群建议规模3 主 3 备起步(6 节点),单 AZ 内至少 3 台物理/虚拟机,尽量跨 AZ。

  • 创建与检查

    复制代码
    # 创建集群(示例6节点,3主3从)
    redis-cli --cluster create \
      10.0.0.10:6379 10.0.0.11:6379 10.0.0.12:6379 \
      10.0.0.13:6379 10.0.0.14:6379 10.0.0.15:6379 \
      --cluster-replicas 1
    
    # 查看拓扑
    redis-cli -c -h 10.0.0.10 -p 6379 cluster nodes
    redis-cli -c -h 10.0.0.10 -p 6379 cluster info

4. 典型拓扑与配置模板(可直接改名上线)

4.1 单实例高可用(主从 + Sentinel)

  • 拓扑1 主 + 2 从 + 3 Sentinel

  • 适用:中小体量、强一致要求不高、运维成本友好。

  • 主库片段(redis.conf)

    复制代码
    port 6379
    # 持久化
    save 900 1
    save 300 10
    save 60 10000
    appendonly yes
    appendfsync everysec
    no-appendfsync-on-rewrite yes
    
    # 复制与安全
    repl-diskless-sync yes
    repl-backlog-size 256mb
    min-replicas-to-write 1
    min-replicas-max-lag 5
    
    # 内存
    maxmemory 16gb
    maxmemory-policy allkeys-lru
    
    # 安全(按需)
    # requirepass <pass>
    # aclfile /etc/redis/users.acl
  • 从库片段

    复制代码
    replicaof 10.0.0.10 6379
    replica-read-only yes
  • Sentinel(3 份,仅示例一份):见上 3.2 配置。

4.2 Redis Cluster(3 主 3 从)

  • 每个节点的 redis.conf (变化项:cluster-announce-ip、端口):

    复制代码
    port 6379
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 15000
    
    # 持久化
    appendonly yes
    appendfsync everysec
    save 900 1
    save 300 10
    
    # 内存淘汰(缓存型很关键)
    maxmemory 16gb
    maxmemory-policy allkeys-lru
  • 创建集群:参考 3.3 脚本。

  • 扩容/缩容 :使用 redis-cli --cluster reshardadd-nodedel-node,务必在低峰期进行。


5. 备份/恢复/演练:从脚本到流程

5.1 备份策略

  • RDB 冷备 :定期复制 .rdb 到异地/对象存储(带版本与校验);

  • AOF :先 BGREWRITEAOF 生成紧凑版,再打包上传(避免巨大日志)。

  • 频率 :日常建议 日备 + 周全量,重要业务增加关键时点手动快照。

  • 校验

    复制代码
    redis-check-rdb dump-2025-09-01.rdb
    redis-check-aof appendonly.aof

5.2 恢复流程(单实例)

  1. 下线流量、停止 Redis;

  2. 备份当前数据文件到临时目录(防误操作);

  3. 放入目标 dump.rdb(或 appendonly.aof),确保权限与 owner 一致;

  4. 启动 Redis,观察日志与 INFO

  5. 业务侧灰度放量。

5.3 恢复流程(Cluster)

  • 同槽迁移:尽量在集群内重建节点而非整体"外部恢复";

  • 节点级恢复 :按节点维度恢复 RDB/AOF,重入集群(CLUSTER MEET),再做 slot 迁移;

  • 强演练:每季度做一次"节点级数据损坏恢复演练",记录耗时与回放步骤。


6. 性能与稳定性调优(内核、Redis 配置、内存与淘汰)

6.1 系统内核与文件系统

复制代码
# 软中断/网络 backlog
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=8192

# TIME_WAIT 回收(按需,谨慎)
sysctl -w net.ipv4.tcp_tw_reuse=1

# 关闭透明大页(THP)
echo never > /sys/kernel/mm/transparent_hugepage/enabled

# 关闭 swap 或保证 swapiness 很低
sysctl -w vm.swappiness=1

# 允许内存 overcommit(防止 fork 失败)
sysctl -w vm.overcommit_memory=1

重点vm.overcommit_memory=1,否则 BGSAVE/BGREWRITEAOF 可能因内存不足失败。

6.2 Redis 配置热点

  • 延迟敏感

    • appendfsync everysec + no-appendfsync-on-rewrite yes

    • latency-monitor-threshold 100(打开延迟监控,单位毫秒)

  • 内存与碎片

    • maxmemory <size> + 合理 maxmemory-policy(缓存型推荐 allkeys-lruallkeys-lfu

    • activedefrag yes(生产常开,降低碎片)

  • 数据结构优化

    • 小对象压缩阈值(具体名称随版本有变化,如 listpack 相关阈值);

    • 尽量使用紧凑结构(如 Hash 存多字段,避免大量小 Key)。

6.3 慢查询与可观测性

复制代码
# 记录慢查询(单位微秒)
CONFIG SET slowlog-log-slower-than 10000   # >10ms
CONFIG SET slowlog-max-len 2048

# 查看慢日志
SLOWLOG GET 10

# 延迟事件
LATENCY DOCTOR
LATENCY LATEST
  • 打通 Exporter → Prometheus → Grafana,关注内存碎片率、AOF 重写耗时、复制延迟、拒绝写入次数等核心指标。

7. 生产避坑清单(高频问题→定位→对策)

  1. BGSAVE/BGREWRITEAOF 失败

    • 现象:日志提示 fork 失败或 OOM;

    • 排查:vm.overcommit_memory、内存碎片、容器内存限制;

    • 对策:开启 activedefrag、扩内存、调整触发频率。

  2. 主从复制频繁全量

    • 现象:网络抖动后总是从头同步;

    • 排查:repl-backlog-size 太小;

    • 对策:增大到能覆盖网络波动期的写入量(按 QPS 与命令平均大小估)。

  3. 写入被拒(OOM 或不安全写)

    • 现象:OOM command not allowed / 触发 min-replicas-to-write 保护;

    • 对策:设置 maxmemory 与合理淘汰策略,或检查从库延迟/下线。

  4. AOF 膨胀/恢复慢

    • 现象:AOF 文件超大,重放耗时长;

    • 对策:定期 BGREWRITEAOF,启用"RDB 作为 AOF 前导",老版本升级。

  5. Cluster 跨槽操作失败

    • 现象:CROSSSLOT Keys in request don't hash to the same slot

    • 对策:使用 hash tag (如 user:{42}:profileorder:{42}:list)让相关 Key 落同槽。

  6. Sentinel 频繁误判

    • 现象:网络抖动导致频繁 failover;

    • 对策:增大 down-after-milliseconds、合理 quorum、跨 AZ 部署 Sentinel。

  7. 容器/云环境 IP 上报错误

    • 现象:Cluster 节点互相连不上;

    • 对策:显式设置 cluster-announce-ipcluster-announce-portprotected-mode no(仅在安全网络下)。


8. 迁移与升级策略(Standalone→Sentinel、Sentinel→Cluster)

8.1 单机→Sentinel(无停机/短暂停)

  • 新建两个从库(全量同步完成后),部署 3 哨兵;

  • 切流量前压测读从(确认只读链路 OK);

  • 客户端切到 Sentinel 模式;

  • 小流量灰度 → 全量切换。

8.2 单机/Sentinel→Cluster(平滑迁移)

  • 新建 Cluster(3 主 3 从),业务新写双写(或通过数据管道/订阅复制);

  • 扫描旧库 Key,分批迁移到 Cluster(redis-shake/自研脚本/SCAN + MIGRATE);

  • 验证一致性(抽样校验、核心集合完整性校验);

  • 写流量切换到 Cluster → 读流量切换 → 观测一段时间 → 下线旧库。

若业务允许短暂停机,关闭写入口,做全量迁移 + 增量补偿,会简单很多。

8.3 版本升级

  • 同大版本小修:rolling 重启(从→主),使用 REPLICAOF 切换,缩短中断;

  • 跨大版本:先读 release notes 看持久化格式/配置项兼容性,影子集群演练,再灰度。


9. 运维清单与值班自检表

日常巡检(每日/每班次):

  • INFO replication:复制延迟、master_link_status

  • INFO persistence:AOF 重写状态、最近持久化失败次数;

  • INFO memory:使用量、碎片率(>1.5 长期需关注);

  • SLOWLOG LEN / SLOWLOG GET:慢查询堆积;

  • Cluster:cluster infocluster nodes 异常标记。

周度/关键变更前:

  • 触发 RDB 快照与 AOF 重写,校验备份;

  • Sentinel/Cluster 拓扑一致性检查;

  • 压测核心读写路径,记录基线。

季度演练:

  • 单节点宕机 → 恢复;

  • 主从切换演练(Sentinel/Cluster);

  • 备份恢复全链路复盘(计时 + 步骤卡点)。


附:一键化示例(可改名投入使用)

systemd 单实例服务(/etc/systemd/system/redis-6379.service

复制代码
[Unit]
Description=Redis 6379
After=network.target

[Service]
ExecStart=/usr/bin/redis-server /etc/redis/6379.conf --supervised systemd
ExecStop=/usr/bin/redis-cli -p 6379 shutdown
Type=notify
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target

Sentinel systemd(/etc/systemd/system/redis-sentinel.service

复制代码
[Unit]
Description=Redis Sentinel
After=network.target

[Service]
ExecStart=/usr/bin/redis-sentinel /etc/redis/sentinel.conf --supervised systemd
ExecStop=/usr/bin/redis-cli -p 26379 shutdown
Type=notify
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target

结语

Redis 的"正确打开方式"不是单点性能跑多快,而是在"可预期的失败"里依然稳定工作

  • RDB + AOF(everysec) 做好数据兜底;

  • 主从 + Sentinel 扛住单点;

  • 需要水平扩展就上 Cluster ,在建模时用 {} 控制跨槽;

  • 结合 操作系统与 Redis 参数 做到"高性能但不冒险";

  • 备份/恢复/演练 变成固定流程,而不是事故现场临时发挥。

如果你愿意,我可以把上述模板整理成 可下载的配置包 (包含 redis.conf/sentinel.conf/systemd/备份脚本/演练脚本),你直接改 IP 和口令就能落地。

相关推荐
lili00122 分钟前
CC GUI 插件架构剖析:如何为 JetBrains IDE 打造完整的 AI 编程工作台
java·ide·人工智能·python·架构·ai编程
Royzst5 分钟前
学生信息管理案例
java
爱棋笑谦7 分钟前
单元测试简述
java
音符犹如代码15 分钟前
Docker 一键部署带有 TimescaleDB 插件的 PostgreSQL
java·运维·数据库·后端·docker·postgresql·容器
sleepcattt26 分钟前
Java反射技术
java
小锋java123427 分钟前
【技术专题】Spring AI 2.0 - Advisors —— 拦截器模式增强AI能力
java·人工智能
AI人工智能+电脑小能手28 分钟前
【大白话说Java面试题 第56题】【JVM篇】第16题:JVM有哪些垃圾收集器?
java·开发语言·jvm·面试
二哈赛车手1 小时前
新人笔记---简易版AI实现以图搜图功能
java·人工智能·笔记·spring·ai
夕除1 小时前
spring boot 6
java·spring boot·后端
johnrui1 小时前
JUC之AQS
java·开发语言·jvm