起因
Redis 单实例够用阶段过了:
- 数据量逼近单机 RAM
- 单点故障 = 整服务挂
- 写入 / QPS 接近单机极限
两个官方 HA 方案:
- Sentinel:master-replica + 自动 failover(数据仍单 master)
- Cluster:sharded,多 master,自动分片 + failover
下面对比哪种适合哪种场景。
Sentinel
[client]
↓ (asks sentinel)
[sentinel × 3] → 监控 master / replica
↓
[master] ←── async replication ──→ [replica × 2]
- 1 master 服务读写
- N replica 异步复制
- 3+ sentinel 监控,master 挂自动选 replica 升 master
部署
sentinel.conf:
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2 # 2 票 = 多数
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
3 个 sentinel 跑在不同机器 → 任意 2 个同意才能 failover。
客户端连接
from redis.sentinel import Sentinel
sentinel = Sentinel([
('sentinel1', 26379),
('sentinel2', 26379),
('sentinel3', 26379),
])
master = sentinel.master_for('mymaster')
replica = sentinel.slave_for('mymaster')
master.set('key', 'val') # 写
replica.get('key') # 读(可能略 stale)
client 问 sentinel 当前 master 是谁 → 直连。
failover 时 sentinel 推新 master → client 重连。
优势
- 简单(仍是单 master 模型)
- 数据完整性强(无分片复杂性)
- 支持所有 Redis command(包括 MULTI/EXEC、Lua、cluster 不支持的)
劣势
- 单 master 写 QPS 上限(10w/s 量级)
- 单机 RAM 上限(200 GB 算极限)
- failover 期间(10-60s)短暂不可写
Cluster
[client]
↓ (knows slot → node mapping)
[node1: slot 0-5460] ←→ [node2: slot 5461-10922] ←→ [node3: slot 10923-16383]
↓ ↓ ↓
[replica1] [replica2] [replica3]
- 16384 个 hash slot 分配到 master 节点
- key 哈希到 slot → slot 在哪个节点
- 每 master 自带 replica 做 failover
- 无 sentinel(cluster 节点之间 gossip)
部署
需要至少 3 master + 3 replica = 6 节点:
redis-cli --cluster create \
127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 \
127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 \
--cluster-replicas 1
redis.conf:
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
客户端
from redis.cluster import RedisCluster
rc = RedisCluster(host='node1', port=7001, decode_responses=True)
rc.set('key', 'val')
rc.get('key')
client 知道 slot 映射 → 直接连到对应节点(无 sentinel proxy)。
MOVED redirect 让 client 学新映射。
优势
- 水平扩展:6 节点撑 60w QPS,3 TB RAM
- 自动 sharding(hash slot)
- failover 同样自动
劣势
- multi-key 操作受限(必须同 slot,hash tag
{...}) - pub/sub 不跨节点(cluster 模式下 pub/sub 是 broadcast 到所有节点)
- 客户端要支持 cluster protocol
- 运维复杂(add/remove node 时 reshard)
关键区别
| Sentinel | Cluster | |
|---|---|---|
| 数据分片 | 否(全在 master) | 是(16384 slot) |
| 容量上限 | 单机 RAM | 累加 |
| 写 QPS 上限 | 单 master | 累加 |
| 节点数 | 1m + N replica + 3 sentinel | 3+ master + 3+ replica |
| failover 控制 | sentinel 投票 | gossip + 选举 |
| multi-key | 完全支持 | 必须同 slot ({tag}) |
| pub/sub | 正常 | 节点间不传 |
| 复杂度 | 中 | 高 |
怎么选
- 数据 < 50 GB + 中等 QPS(< 50k) → Sentinel
- 数据 > 100 GB + 高 QPS → Cluster
- 多 key transaction / Lua 复杂 → Sentinel
- 缓存场景(多数 key 独立) → Cluster
- AWS / GCP / managed:用 ElastiCache / MemoryStore(背后就是这两个)
我们的实际:90% 项目 Sentinel 够。极少几个超大缓存项目用 Cluster。
hash tag (cluster multi-key)
cluster 默认每 key hash 到不同 slot → MGET/MSET 跨 slot 失败。
{...} 强制 key 同 slot:
rc.set('{user:42}:profile', '...')
rc.set('{user:42}:settings', '...')
rc.mget(['{user:42}:profile', '{user:42}:settings']) # OK,同 slot
{user:42} 部分用来 hash。所有 {user:42}:* 在同节点。
设计 key 时考虑:相关 key 用同 tag → 减少跨节点操作。
failover 实测
Sentinel:master kill → 5-10 秒 detect + 选新 master + 客户端重连。
期间写失败 + 读 replica 可用。
Cluster:master kill → 类似 5-15 秒 detect + replica 提升。
该 slot 短暂不可写,其它 slot 正常。
两者都不是"零停机",但都是"短暂不可写"级别。
ProxySQL-like proxy?
Redis 没像 ProxySQL 那么常见的官方 proxy。
第三方:
- twemproxy(Twitter,老)
- codis(豌豆荚,老)
- predixy(Cluster proxy,仍维护)
加 proxy 让 client 不需要懂 sentinel/cluster,但多一跳 + 单点。
非必要不引入。
监控
key 指标:
connected_clientsused_memory/maxmemoryinstantaneous_ops_per_secevicted_keys(开 maxmemory-policy 时)master_link_status(replica)cluster_state(cluster)
Prometheus redis_exporter 一行装。
持久化
appendonly yes + appendfsync everysec → 最多丢 1 秒数据。
save 900 1 RDB 备份基础。
混合(aof + rdb)是默认推荐。
HA 也不替代持久化(脑裂 / 整集群挂)。
踩过的坑
-
Sentinel quorum 配错:2 sentinel + quorum 2 → 任意 sentinel 挂
→ 没法 failover。最少 3 sentinel。 -
cluster reshard 慢:迁移大 slot 几小时。期间客户端 MOVED redirect
多 → latency 抖。计划好低峰期。 -
client 不支持 cluster:老版本 jedis / lettuce / redis-py 没
cluster 支持。升级 client。 -
pub/sub in cluster:消息只在该 channel 所在节点发布。redis
7+ 引入 sharded pub/subSPUBLISH改善但兼容性问题。 -
跨 DC:Redis 不为跨数据中心同步设计。延迟 > 几十 ms 时 replica
lag 严重。跨 DC 用应用层方案(Kafka mirror / 应用双写)。
登录后参与评论。