
这篇是我把几套生产环境踩坑与复盘整理成的一份"从 0 到 1 + 长期可维护"的实践文。目标是:明确策略、给出默认可用的配置模板、把常见坑一次讲透 。
适用场景:新项目选型、老项目稳定性加固、从单机迁移到 HA/Cluster、应对数据安全与故障切换要求。
目录
-
核心结论先说在前面
-
持久化:RDB vs AOF(以及"二者结合"的推荐范式)
-
高可用形态:主从复制基础、Sentinel、Cluster
-
典型拓扑与配置模板(可直接改名上线)
-
备份/恢复/演练:从脚本到流程
-
性能与稳定性调优(内核、Redis 配置、内存与淘汰)
-
生产避坑清单(高频问题→定位→对策)
-
迁移与升级策略(Standalone→Sentinel、Sentinel→Cluster)
-
运维清单与值班自检表
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 yes
、appendfsync everysec
、no-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 reshard
、add-node
、del-node
,务必在低峰期进行。
5. 备份/恢复/演练:从脚本到流程
5.1 备份策略
-
RDB 冷备 :定期复制
.rdb
到异地/对象存储(带版本与校验); -
AOF :先
BGREWRITEAOF
生成紧凑版,再打包上传(避免巨大日志)。 -
频率 :日常建议 日备 + 周全量,重要业务增加关键时点手动快照。
-
校验:
redis-check-rdb dump-2025-09-01.rdb redis-check-aof appendonly.aof
5.2 恢复流程(单实例)
-
下线流量、停止 Redis;
-
备份当前数据文件到临时目录(防误操作);
-
放入目标
dump.rdb
(或appendonly.aof
),确保权限与 owner 一致; -
启动 Redis,观察日志与
INFO
; -
业务侧灰度放量。
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-lru
或allkeys-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. 生产避坑清单(高频问题→定位→对策)
-
BGSAVE/BGREWRITEAOF 失败
-
现象:日志提示
fork
失败或 OOM; -
排查:
vm.overcommit_memory
、内存碎片、容器内存限制; -
对策:开启
activedefrag
、扩内存、调整触发频率。
-
-
主从复制频繁全量
-
现象:网络抖动后总是从头同步;
-
排查:
repl-backlog-size
太小; -
对策:增大到能覆盖网络波动期的写入量(按 QPS 与命令平均大小估)。
-
-
写入被拒(OOM 或不安全写)
-
现象:
OOM command not allowed
/ 触发min-replicas-to-write
保护; -
对策:设置
maxmemory
与合理淘汰策略,或检查从库延迟/下线。
-
-
AOF 膨胀/恢复慢
-
现象:AOF 文件超大,重放耗时长;
-
对策:定期
BGREWRITEAOF
,启用"RDB 作为 AOF 前导",老版本升级。
-
-
Cluster 跨槽操作失败
-
现象:
CROSSSLOT Keys in request don't hash to the same slot
; -
对策:使用 hash tag (如
user:{42}:profile
、order:{42}:list
)让相关 Key 落同槽。
-
-
Sentinel 频繁误判
-
现象:网络抖动导致频繁 failover;
-
对策:增大
down-after-milliseconds
、合理quorum
、跨 AZ 部署 Sentinel。
-
-
容器/云环境 IP 上报错误
-
现象:Cluster 节点互相连不上;
-
对策:显式设置
cluster-announce-ip
、cluster-announce-port
、protected-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 info
、cluster 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 和口令就能落地。