Redis如何保證高可用?
前言
我親歷過Redis宕機(jī)導(dǎo)致?lián)p失慘重的教訓(xùn)。
真正的Redis高可用不是簡單的主從復(fù)制,而是構(gòu)建能自動(dòng)愈合的分布式神經(jīng)系統(tǒng)。
這篇文章跟大家一起聊聊Redis如何保證高可用,希望對你會有所幫助。
這兩天蘇三的星球太火爆了,公眾號上所有的優(yōu)惠券都已經(jīng)搶完了。
一、主從復(fù)制:高可用的基石與陷阱
主從復(fù)制全流程解析
圖片
致命陷阱:異步復(fù)制導(dǎo)致的數(shù)據(jù)丟失
# 主節(jié)點(diǎn)寫入后宕機(jī)(未同步到從節(jié)點(diǎn))
SET order:1001 "confirmed"
# 從節(jié)點(diǎn)提升為主節(jié)點(diǎn)后,訂單狀態(tài)丟失解決方案:
// 強(qiáng)制同步寫入(謹(jǐn)慎使用)
Jedis jedis = new Jedis("master", 6379);
jedis.waitReplicas(1, 1000); // 等待1個(gè)從節(jié)點(diǎn)同步二、哨兵模式:自動(dòng)故障轉(zhuǎn)移的藝術(shù)
三節(jié)點(diǎn)哨兵集群部署
圖片
哨兵選舉四部曲:
- 主觀下線(SDOWN):單個(gè)哨兵檢測到主節(jié)點(diǎn)失聯(lián)
- 客觀下線(ODOWN):超過quorum數(shù)量的哨兵確認(rèn)
- 領(lǐng)導(dǎo)者選舉:基于Raft算法選出主哨兵
- 故障轉(zhuǎn)移:提升最優(yōu)從節(jié)點(diǎn)為新主節(jié)點(diǎn)
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()) {
// 自動(dòng)路由到當(dāng)前主節(jié)點(diǎn)
jedis.set("config:timeout", "500");
}三、Redis Cluster:水平擴(kuò)展的終極方案
數(shù)據(jù)分片原理
圖片
節(jié)點(diǎn)通信Gossip協(xié)議:
// 模擬節(jié)點(diǎn)間狀態(tài)傳播
public void gossip(Node node) {
// 隨機(jī)選擇3個(gè)節(jié)點(diǎn)交換狀態(tài)
List<Node> peers = selectRandomPeers(3);
for (Node peer : peers) {
sendPing(peer, currentState);
}
}跨槽位操作解決方案:
# 錯(cuò)誤:多key不在同槽位
MGET user:1001:name user:1002:age
# 正確:使用hash tag強(qiáng)制同槽位
MGET user:{1001}:name user:{1001}:age四、多級高可用架構(gòu)設(shè)計(jì)
電商平臺真實(shí)案例
圖片
四層防護(hù)體系:
- 代理層:Twemproxy自動(dòng)路由+負(fù)載均衡
- 集群層:雙集群互備+就近訪問
- 數(shù)據(jù)層:1主2從+讀寫分離
- 災(zāi)備層:跨地域異步復(fù)制
五、避坑指南
腦裂問題:最危險(xiǎn)的故障模式
發(fā)生場景:
圖片
解決方案:
# 1. 增加哨兵節(jié)點(diǎn)數(shù)(至少3個(gè))
sentinel monitor mymaster 192.168.1.10 6379 2
# 2. 設(shè)置主節(jié)點(diǎn)最小從節(jié)點(diǎn)數(shù)
min-replicas-to-write 1緩存雪崩預(yù)防
// 緩存穿透+雪崩防護(hù)代碼示例
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. 數(shù)據(jù)庫查詢
value = db.query("SELECT...");
// 6. 空結(jié)果防穿透
jedis.setex(cacheKey, 300, value == null ? "NULL_OBJ" : value);
} finally {
jedis.del("lock:"+id);
}
} else {
// 7. 其他線程等待重試
Thread.sleep(100);
return getProductInfo(id);
}
}
return value;
}六、監(jiān)控體系:高可用的生命線
告警規(guī)則示例:
# 復(fù)制延遲 > 5秒
repl_delay{instance="*"} > 5
# 內(nèi)存使用 > 90%
memory_used_percentage > 0.9
# 連接數(shù) > 80%上限
connected_clients / maxclients > 0.8總結(jié)
三級防御體系:
圖片
五個(gè)核心原則:
- 冗余設(shè)計(jì):最少1主2從,跨機(jī)架部署
- 自動(dòng)故障轉(zhuǎn)移:哨兵quorum數(shù) = 節(jié)點(diǎn)數(shù)/2 + 1
- 容量規(guī)劃:內(nèi)存使用率控制在70%以下
- 性能隔離:業(yè)務(wù)集群物理隔離
- 混沌工程:定期模擬節(jié)點(diǎn)宕機(jī)、網(wǎng)絡(luò)分區(qū)
高可用的本質(zhì)不是避免故障,而是在故障發(fā)生時(shí)系統(tǒng)仍能持續(xù)提供服務(wù)。
通過主從復(fù)制、哨兵機(jī)制、Cluster集群的三級防御,配合嚴(yán)謹(jǐn)?shù)谋O(jiān)控和容量規(guī)劃,才能構(gòu)建真正彈性的Redis架構(gòu)。



































