我亲历过Redis宕机导致损失惨重的教训。
真正的Redis高可用不是简单的主从复制,而是构建能自动愈合的分布式神经系统。
这篇文章跟大家一起聊聊Redis如何保证高可用,希望对你会有所帮助。

致命陷阱:异步复制导致的数据丢失
# 主节点写入后宕机(未同步到从节点)
SET order:1001 "confirmed"
# 从节点提升为主节点后,订单状态丢失
解决方案:
// 强制同步写入(谨慎使用)
Jedis jedis = new Jedis("master", 6379);
jedis.waitReplicas(1, 1000); // 等待1个从节点同步

哨兵选举四部曲:
quorum数量的哨兵确认Java客户端连接哨兵示例:
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.10:26379");
sentinels.add("192.168.1.11:26379");
JedisSentinelPool pool = new JedisSentinelPool(
"mymaster", sentinels, poolConfig);
try (Jedis jedis = pool.getResource()) {
// 自动路由到当前主节点
jedis.set("config:timeout", "500");
}

节点通信Gossip协议:
// 模拟节点间状态传播
public void gossip(Node node) {
// 随机选择3个节点交换状态
List<Node> peers = selectRandomPeers(3);
for (Node peer : peers) {
sendPing(peer, currentState);
}
}
跨槽位操作解决方案:
# 错误:多key不在同槽位
MGET user:1001:name user:1002:age
# 正确:使用hash tag强制同槽位
MGET user:{1001}:name user:{1001}:age

四层防护体系:
发生场景:

解决方案:
# 1. 增加哨兵节点数(至少3个)
sentinel monitor mymaster 192.168.1.10 6379 2
# 2. 设置主节点最小从节点数
min-replicas-to-write 1
// 缓存穿透+雪崩防护代码示例
public String getProductInfo(String id) {
// 1. 查询缓存
String cacheKey = "product:" + id;
String value = jedis.get(cacheKey);
// 2. 缓存穿透:空值缓存
if ("NULL_OBJ".equals(value)) returnnull;
// 3. 缓存未命中
if (value == null) {
// 4. 互斥锁防止雪崩
if (jedis.setnx("lock:"+id, "1") == 1) {
jedis.expire("lock:"+id, 3); // 避免死锁
try {
// 5. 数据库查询
value = db.query("SELECT...");
// 6. 空结果防穿透
jedis.setex(cacheKey, 300, value == null ? "NULL_OBJ" : value);
} finally {
jedis.del("lock:"+id);
}
} else {
// 7. 其他线程等待重试
Thread.sleep(100);
return getProductInfo(id);
}
}
return value;
}
告警规则示例:
# 复制延迟 > 5秒
repl_delay{instance="*"} > 5
# 内存使用 > 90%
memory_used_percentage > 0.9
# 连接数 > 80%上限
connected_clients / maxclients > 0.8
三级防御体系:

五个核心原则:
高可用的本质不是避免故障,而是在故障发生时系统仍能持续提供服务。
通过主从复制、哨兵机制、Cluster集群的三级防御,配合严谨的监控和容量规划,才能构建真正弹性的Redis架构。