“Redis 的大多数性能问题,本质都是:把不该 Master 干的活,全塞给了 Master。”
这篇文章用“火锅店后厨模型”生动类比 Redis 主从架构中的职责错配问题。下面我为你系统梳理其六大核心问题与解决方案,并补充关键工程建议:
🔥 问题一:Master 不应做持久化(RDB / AOF)
-
错误做法:在 Master 上开启
save或appendonly yes -
后果:
- RDB:
fork()复制页表,大数据量下阻塞主线程(Copy-on-Write 虽优化但仍耗资源) - AOF:持续写磁盘 +
fsync消耗 I/O 和 CPU
- RDB:
-
✅ 正确做法:
- Master 只处理读写请求
- 由 Slave 节点承担持久化任务(开启 AOF +
appendfsync everysec)
📌 面试金句: “持久化与高并发服务解耦,是保障 Redis 稳定性的第一原则。”
🔒 问题二:关键数据应在 Slave 开启 AOF(everysec)
-
配置建议:
# 在 Slave 节点配置 appendonly yes appendfsync everysec # 平衡性能与数据安全 no-appendfsync-on-rewrite no -
为什么不是 always?
always每次写都fsync,性能极差;everysec是工程上最佳折中(最多丢 1 秒数据)。
🌐 问题三:Master 与 Slave 应在同一局域网
-
原因:
-
主从复制依赖低延迟、高带宽网络
-
跨机房/跨地域易导致:
- 复制延迟增大
- 网络抖动触发全量同步(
SYNC而非PSYNC) - 缓冲区溢出(
repl-backlog不足)
-
-
✅ 部署建议:
- 同一可用区(AZ)部署主从
- 跨地域仅用于灾备或只读场景(接受最终一致性)
⚠️ 问题四:高负载时勿随意增加 Slave
-
误区:“加 Slave 能分担读压力” → 实则加重 Master 负担!
-
Master 额外开销:
- 为每个 Slave 维护独立的复制缓冲区(
client output buffer) - 发送 RDB 快照或增量命令
- 处理 ACK 和心跳
- 为每个 Slave 维护独立的复制缓冲区(
-
✅ 正确做法:
- 先监控
replication backlog、CPU、网络带宽 - 在业务低峰期扩容
- 使用 Proxy 层(如 Codis、Twemproxy)管理读写分离
- 先监控
🌀 问题五:避免在 Master 执行 BGREWRITEAOF
-
风险:
BGREWRITEAOF会fork()子进程重写 AOF- 主进程仍需记录增量写入到 AOF 重写缓冲区
- 内存压力 + CPU 负载飙升 → 请求延迟突增
-
✅ 解决方案:
- 不在 Master 执行,改在 Slave 上重写后替换
- 或安排在凌晨等低峰时段自动触发
🔗 问题六:主从结构用“链式”,不用“星型/图状”
-
错误结构(星型) :
Master ├── Slave1 ├── Slave2 └── Slave3- Master 压力大(N 倍复制流量)
- 故障切换复杂
-
推荐结构(链式) :
Master → Slave1 → Slave2 → Slave3- 复制压力逐级分摊
- Master 挂掉后,Slave1 可快速晋升(配合 Sentinel)
- 网络和资源消耗更低
📌 面试加分项: “链式复制不仅减轻主节点负担,还简化了故障转移拓扑。”
✅ 总结:Redis 性能优化的核心原则
| 原则 | 说明 |
|---|---|
| 职责分离 | Master 只干“炒菜”(处理请求),不干“记账”(持久化) |
| 就近部署 | 主从同机房,降低网络不确定性 |
| 谨慎扩容 | 加 Slave 前评估 Master 资源余量 |
| 结构扁平 | 链式 > 星型,减少主节点扇出 |
| 避开陷阱 | 禁用 keys *、避免大 Key、防止缓存雪崩/穿透 |
如果你正在准备面试,记住这句话就能打动面试官:
“让 Redis Master 专心抗并发,其他脏活累活交给 Slave 或外围系统——这才是高可用缓存架构的起点。”