饮墨

子安饮墨馀三斗,留与卿儿作赋来

Redis 高可用选型实战:Sentinel vs Cluster,3 个场景帮你做决定

Redis 挂了,缓存雪崩、Session 丢失、排行榜空白——这不是假设,是每个用 Redis 的团队迟早会遇到的事。单节点 Redis 是单点故障的代名词。问题是:上高可用该选 Sentinel 还是 Cluster?本文从真实业务场景出发,给你一套可落地的选型方案。


痛点:单节点 Redis 的三大致命风险

  1. 进程崩溃 = 服务不可用:Redis 是单线程模型,一旦 OOM 被 kill 或者主机宕机,所有依赖 Redis 的服务瞬间瘫痪。
  2. 数据丢失:即使开了 RDB/AOF 持久化,故障恢复期间仍有数据窗口丢失,且恢复耗时不可控。
  3. 容量天花板:单节点内存上限受物理机限制,当数据量超过 64GB,性能开始劣化,大 key 扫描、fork 快照都会卡顿。

线上出过一个典型事故:某电商大促期间,唯一的 Redis 实例因 maxmemory 配置不当触发 OOM,被 Linux OOM Killer 直接杀掉,导致商品缓存全部失效,数据库瞬间被打爆,故障持续 12 分钟。


方案:两种高可用架构对比

维度 Sentinel(哨兵模式) Cluster(集群模式)
核心能力 自动故障转移 + 读写分离 数据分片 + 自动故障转移
数据分布 全量数据在每个节点 16384 个 slot 分散到多节点
最大容量 受单节点内存限制 理论无上限(横向扩展)
客户端复杂度 低,标准客户端即可 中等,需要支持 MOVED/ASK 重定向
适用场景 数据量 < 32GB,读多写少 数据量大、吞吐要求高
运维复杂度 中高(扩缩容需迁移 slot)

一句话结论:数据装得下一台机器选 Sentinel,装不下或者需要线性扩展选 Cluster。


实操步骤

场景一:用 Sentinel 搭建 1 主 2 从 + 3 哨兵

架构: 1 个 Master + 2 个 Replica + 3 个 Sentinel 进程(奇数保证投票选主)。

Step 1:启动主从复制

# Master (10.0.1.1:6379) — redis.conf
bind 0.0.0.0
port 6379
requirepass "YourStrongPass123"
masterauth "YourStrongPass123"

# Replica (10.0.1.2:6379 / 10.0.1.3:6379) — redis.conf
bind 0.0.0.0
port 6379
requirepass "YourStrongPass123"
masterauth "YourStrongPass123"
replicaof 10.0.1.1 6379

Step 2:配置 Sentinel

三台机器各部署一个 Sentinel,配置相同:

# sentinel.conf
port 26379
sentinel monitor mymaster 10.0.1.1 6379 2
sentinel auth-pass mymaster YourStrongPass123
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 30000
sentinel parallel-syncs mymaster 1

关键参数解释: - 2 — quorum 值,至少 2 个 Sentinel 同意才触发故障转移 - down-after-milliseconds 5000 — 5 秒无响应判定主观下线 - parallel-syncs 1 — 故障转移时同时同步的从节点数,设为 1 减少带宽冲击

Step 3:启动并验证

# 启动 Sentinel
redis-sentinel /etc/redis/sentinel.conf

# 查看 Sentinel 状态
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster

场景二:用 Cluster 搭建 3 主 3 从

当数据量超过单机内存,或者需要超过 10 万 QPS 的写吞吐,上 Cluster:

# 6 个节点(10.0.1.1~10.0.1.6),每个节点 redis.conf 加上:
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

# 启动所有节点后,一条命令创建集群:
redis-cli --cluster create \
  10.0.1.1:6379 10.0.1.2:6379 10.0.1.3:6379 \
  10.0.1.4:6379 10.0.1.5:6379 10.0.1.6:6379 \
  --cluster-replicas 1 -a YourStrongPass123

# 验证集群状态
redis-cli -c -a YourStrongPass123 cluster info
redis-cli -c -a YourStrongPass123 cluster nodes

场景三:应用端连接配置(Python 示例)

# Sentinel 模式连接
from redis.sentinel import Sentinel

sentinel = Sentinel(
    [('10.0.1.1', 26379), ('10.0.1.2', 26379), ('10.0.1.3', 26379)],
    socket_timeout=0.5,
    password='YourStrongPass123'
)
master = sentinel.master_for('mymaster', password='YourStrongPass123')
slave = sentinel.slave_for('mymaster', password='YourStrongPass123')

master.set('key', 'value')       # 写走 Master
print(slave.get('key'))           # 读走 Replica

# Cluster 模式连接
from redis.cluster import RedisCluster

rc = RedisCluster(
    startup_nodes=[{"host": "10.0.1.1", "port": 6379}],
    password='YourStrongPass123',
    decode_responses=True
)
rc.set('key', 'value')
print(rc.get('key'))

3 个常见坑

坑 1:Sentinel 脑裂导致数据丢失

现象: 网络分区时,旧 Master 还在接受写入,Sentinel 已经选出新 Master,分区恢复后旧 Master 降为 Replica,期间写入的数据全部丢失。

解法: 在 Master 的 redis.conf 中加:

min-replicas-to-write 1
min-replicas-max-lag 10

含义:如果没有至少 1 个 Replica 在 10 秒内同步过数据,Master 拒绝写入。这样分区后的孤立 Master 会自动拒绝写请求,避免脑裂丢数据。

坑 2:Cluster 模式下 multi-key 操作报错

现象: MGET key1 key2 key3 直接报 CROSSSLOT Keys in request don't hash to the same slot

解法: 使用 Hash Tag 强制相关 key 落到同一个 slot:

# 用 {} 包裹的部分决定 slot 分配
SET {user:1001}.name "张三"
SET {user:1001}.age "30"
MGET {user:1001}.name {user:1001}.age   # 正常执行

坑 3:Cluster 扩容后 slot 分布不均

现象: 新增节点后,部分节点 slot 数为 0,请求全压在旧节点上。

解法: 扩容后必须手动 rebalance:

# 添加新节点
redis-cli --cluster add-node 10.0.1.7:6379 10.0.1.1:6379 -a YourStrongPass123

# 重新平衡 slot
redis-cli --cluster rebalance 10.0.1.1:6379 \
  --cluster-use-empty-masters -a YourStrongPass123

# 确认分布
redis-cli --cluster info 10.0.1.1:6379 -a YourStrongPass123

总结

  • 数据量 < 32GB + 读多写少 → Sentinel(1 主 2 从 + 3 哨兵),运维简单,成本低
  • 数据量大或写吞吐要求高 → Cluster(至少 3 主 3 从),支持线性扩展
  • 防脑裂必须配 min-replicas-to-write,Cluster 扩容后必须 rebalance
  • 不管哪种方案,监控是底线:Sentinel 要监控 sentinel_masters_down,Cluster 要监控 cluster_state 和 slot 覆盖率

选对架构只是第一步,后续还要关注持久化策略(RDB + AOF 混合)、内存淘汰策略(allkeys-lru vs volatile-ttl)、以及大 key 治理。这些留给下一篇。

您还没有登录,请登录后发表评论。