Redis 高可用與集群原理
1. 前言
Redis 單機雖然高性能,但一旦節點宕機,數據丟失或服務不可用問題會非常嚴重。為了解決這一問題,Redis 提供了 主從復制、哨兵(Sentinel)、Cluster 集群 等高可用機制。
這一篇文章我們重點拆解:
- Sentinel 哨兵機制:如何發現故障、如何自動主從切換。
- Cluster 集群架構:如何實現分片存儲與高可用。
- Gossip 協議:節點間如何通信。
- 故障轉移源碼剖析:Redis 內部實現流程。
2. Redis 高可用架構演進
-
主從復制(Replication)
- 提供讀寫分離,但主節點宕機會導致服務中斷,需要人工干預。
-
哨兵(Sentinel)
- 自動監控主節點健康,支持 自動故障轉移。
-
Cluster 集群
- 支持 數據分片(水平擴展),并內置高可用。
👉 可以理解為:
復制 = 數據冗余
Sentinel = 自動運維
Cluster = 擴展能力 + 內置高可用
3. Sentinel 哨兵機制
3.1 Sentinel 的作用
- 監控(Monitoring):周期性檢測 Master 和 Slave 是否可達。
- 通知(Notification):當節點異常時,向客戶端/其他哨兵發送通知。
- 故障轉移(Failover):自動將一個 Slave 提升為新的 Master,并讓其他 Slave 復制它。
3.2 故障檢測機制
- 主觀下線(SDOWN):某個 Sentinel 認為 Master 不可達。
- 客觀下線(ODOWN):多數 Sentinel 達成共識,確認 Master 宕機。
3.3 Leader 選舉
在多個 Sentinel 中,需要選出一個 Leader 來執行故障轉移,算法基于 Raft 的選舉思想:
- 每個 Sentinel 給候選者投票。
- 超過半數票數的 Sentinel 當選 Leader。
3.4 源碼剖析(sentinel.c)
哨兵檢測主觀下線:
// sentinel.c
if (mst->flags & SRI_MASTER) {if ((mst->flags & SRI_S_DOWN) == 0 && mst->link->disconnected) {mst->flags |= SRI_S_DOWN; // 標記主觀下線sentinelEvent(LL_WARNING, "+sdown", mst, "%@");}
}
這段代碼表明,當哨兵發現主節點無法連接時,會標記為 S_DOWN。
4. Redis Cluster 集群架構
4.1 核心特性
- 分布式存儲:采用 16384 個哈希槽(hash slots),每個節點負責一部分槽位。
- 高可用:每個分片至少有 1 個 Master 和若干 Slave。
- 自動故障轉移:某個 Master 掛掉時,其 Slave 自動升級為新的 Master。
4.2 集群拓撲
┌───────────┐│ Client │└─────┬─────┘│┌─────────────▼─────────────┐│ Cluster ││ ┌────────┐ ┌────────┐ ││ │ Master │ │ Master │ │ ...│ │ Slot 0 │ │ Slot 5461 ││ └───▲────┘ └────▲───┘ ││ │ │ ││ ┌─┴─┐ ┌─┴─┐ ││ │Slave│ │Slave│ ││ └─────┘ └─────┘ │└────────────────────────────┘
4.3 請求路由
- Client 向某個節點發起請求。
- 如果 Key 不在本節點的槽位范圍,返回
MOVED
重定向。 - 客戶端更新槽位映射表,下次直連正確節點。
5. Gossip 協議
Redis Cluster 中節點通信依賴 Gossip 協議,類似于 流言傳播:
- 每個節點周期性地向隨機節點發送 PING。
- 接收節點返回 PONG,附帶自己已知的集群信息。
- 這樣集群拓撲信息逐漸在所有節點中收斂。
消息類型:
- MEET:新節點加入。
- PING/PONG:心跳檢測與狀態同步。
- FAIL:節點失效信息。
👉 Gossip 的特點是 去中心化、最終一致性。
6. 故障轉移源碼剖析
當 Master 宕機時,Cluster 的轉移邏輯如下:
- 檢測故障
// cluster.c
if (node->flags & (CLUSTER_NODE_FAIL | CLUSTER_NODE_PFAIL)) {// 標記為下線
}
- Slave 競選新 Master
- 每個 Slave 會嘗試升級為 Master。
- 使用投票機制,獲得過半節點支持的 Slave 升級。
- 重新分配槽位
// cluster.c
clusterFailoverReplaceYourMaster();
執行槽位遷移,客戶端可繼續訪問。
- 客戶端感知
- 客戶端收到
MOVED
/ASK
,刷新槽位映射。
7. 總結
本文深入分析了 Redis 高可用與集群原理:
- Sentinel:實現了自動故障轉移,基于 SDOWN/ODOWN 和選舉機制。
- Cluster:通過哈希槽實現數據分片和自動轉移。
- Gossip 協議:支撐集群中節點間的通信和狀態同步。
- 源碼剖析:揭示了 Redis 在
sentinel.c
、cluster.c
中的故障轉移實現。
📌 下一步可以寫 Redis 持久化(RDB/AOF)與復制原理,這樣整個高可用 + 數據可靠性體系就完整了。