Redis Cluster 詳解
1. 為什么需要 Redis Cluster?
Redis 作為一個高性能的內存數據庫,在單機模式下可能會遇到以下問題:
- 單機容量受限:Redis 是基于內存存儲的,單機的內存資源有限,單實例的 Redis 只能存儲有限的數據。
- 單點故障(SPOF):單機 Redis 宕機后,所有緩存數據都無法訪問,影響業務可用性。
- 性能瓶頸:單機 Redis 受 CPU 和 I/O 限制,無法支撐高并發的訪問需求。
- 擴展性差:單機模式不支持水平擴展,無法通過增加機器來提高存儲和計算能力。
Redis Cluster(集群模式) 是 Redis 官方提供的分布式解決方案,主要用于解決以上問題。
2. Redis Cluster 解決了什么問題?有什么優勢?
Redis Cluster 解決了以下問題:
- 數據分片存儲,突破單機限制
- 通過 哈希槽(hash slot)+ 多節點 的方式,將數據存儲到多個 Redis 實例中,實現水平擴展。
- 解決了單機存儲受限的問題。
- 無中心化架構,避免單點故障
- 傳統的 Redis Sentinel 模式存在 主從架構 + 哨兵管理,但仍然有中心節點。
- Redis Cluster 去中心化,所有節點都存儲集群信息,任何節點都可以提供集群狀態。
- 解決了單點故障的問題。
- 主從復制 + 自動故障轉移
- Redis Cluster 采用主從架構,每個 Master 可以有多個 Slave 備份。
- 如果某個 Master 宕機,Redis Cluster 會自動提升 Slave 為新的 Master,保證集群可用性。
- 動態擴展,支持水平擴容
- Redis Cluster 允許 動態添加 / 刪除節點,可以在運行時擴展 Redis 集群,而不會影響業務。
- 解決了 Redis 單機模式擴展性差的問題。
Redis Cluster 的核心優勢
特點 | Redis Cluster 解決方案 |
---|---|
存儲受限 | 數據分片存儲,支持多個節點 |
單點故障 | 無中心化架構,主從復制 |
故障恢復 | 自動故障轉移 |
性能瓶頸 | 多主架構,支持并行讀寫 |
擴展性 | 可動態擴容 / 縮容 |
3. Redis Cluster 是如何分片的?
Redis Cluster 采用 哈希槽(hash slot)+ 數據分片 機制進行數據分片:
-
整個集群有 16384 個哈希槽(slot)。
-
每個 Key 通過哈希算法分配到某個哈希槽:
slot = CRC16(key) % 16384
CRC16
是一種高效的哈希計算方法。
-
哈希槽分布到不同的 Redis 節點:
-
例如:3 個 Redis 節點,每個節點存儲部分哈希槽:
節點 A:0 - 5460 節點 B:5461 - 10922 節點 C:10923 - 16383
-
如果有新的節點加入,Redis Cluster 會重新分配哈希槽。
-
4. 為什么 Redis Cluster 的哈希槽是 16384 個?
Redis Cluster 選擇 16384 作為固定的哈希槽數量,主要基于以下考慮:
- 兼容 CRC16 計算
- Redis 使用
CRC16
算法計算 Key 的哈希值,并使用 模運算(% 16384) 確定哈希槽。 - 16384(21?)是 2 的冪,計算高效。
- Redis 使用
- 負載均衡
- 16384 個槽足夠均勻地分配到多個節點,避免熱點數據集中在某個節點。
- 遷移成本低
- 槽的數量適中,在節點增加/刪除時,可以快速遷移哈希槽,減少數據重新分布的影響。
- 適用于大規模集群
- 16384 個槽能支持數百個 Redis 節點,適用于不同規模的集群擴展。
5. 如何確定給定 key 應該分布到哪個哈希槽中?
Redis Cluster 通過 CRC16 哈希算法 計算 key 的哈希槽:
slot = CRC16(key) % 16384
示例:
import crcmodcrc16 = crcmod.predefined.Crc('crc-16')
crc16.update(b'mykey')
slot = crc16.crcValue % 16384
print(slot) # 輸出哈希槽號
Redis 客戶端會計算 Key 的哈希槽,并直接請求對應的 Redis 節點。
6. Redis Cluster 支持重新分配哈希槽嗎?
是的,Redis Cluster 允許動態調整哈希槽分配,以支持擴容或縮容:
- 增加新節點:
- 新增節點后,部分哈希槽會從已有 Master 遷移到新節點。
- 使用
redis-cli --cluster reshard
進行槽位重新分配。
- 刪除節點:
- 刪除節點時,節點上的哈希槽會遷移到其他節點。
哈希槽遷移過程:
- CLUSTER SETSLOT IMPORTING
- CLUSTER SETSLOT MIGRATING
- 數據同步
- 更新哈希槽信息
7. Redis Cluster 擴容/縮容期間可以提供服務嗎?
可以!Redis Cluster 支持在線擴容/縮容,在數據遷移過程中仍然可以提供服務:
- 客戶端訪問時,可能會遇到 MOVED 重定向
- 例如:客戶端請求 Key 時,如果 Key 的哈希槽遷移到了新的節點,返回
MOVED <slot> <new-node-ip>
,客戶端會重新請求正確的節點。
- 例如:客戶端請求 Key 時,如果 Key 的哈希槽遷移到了新的節點,返回
- 數據在后臺遷移,不影響正常讀寫
- Redis Cluster 采用 漸進式遷移,不會一次性移動所有數據,而是逐步將哈希槽數據轉移到新節點。
8. Redis Cluster 中的節點是如何通信的?
Redis Cluster 采用 Gossip 協議 進行節點間通信,保證集群狀態一致:
- PING:定期發送心跳檢測其他節點的狀態。
- PONG:響應
PING
,并附帶本節點的狀態信息。 - MEET:新節點加入集群時,使用
MEET
命令。 - FAIL:如果多數節點判定某個 Master 故障,則廣播
FAIL
信息,觸發故障轉移。
每個 Redis Cluster 節點都維護整個集群的拓撲信息,即便某些節點故障,集群仍然可以繼續運行。
9. Redis Cluster 緩存的數據量太大怎么辦?
當 Redis Cluster 的數據量過大時,可以采取以下措施:
- 水平擴展(增加節點):增加新的 Redis 節點,并重新分配哈希槽,使新節點分擔數據存儲壓力。
- 數據淘汰策略:使用
maxmemory-policy
進行數據淘汰,如volatile-lru
、allkeys-lru
等。 - 數據壓縮:對于字符串、JSON 數據,可以使用 Snappy、Gzip 等方式進行壓縮,減少存儲占用。
- 冷熱數據分層:將熱數據存入 Redis,冷數據存入 MySQL、MongoDB 等持久化存儲中。
- 使用 BigKey 拆分:避免存儲大 key(如超大列表、集合、哈希),可以拆分為多個小 key 存儲。
10. Redis Cluster 的基本架構
一個典型的 Redis Cluster 由多個 Redis 實例組成,每個實例可以是主節點(Master)或從節點(Slave):
- 主節點(Master):負責存儲數據并處理客戶端請求,每個 Master 管理一部分哈希槽。
- 從節點(Slave):作為 Master 的備份,提供高可用性,Master 宕機時從節點可自動提升為 Master。
- 客戶端(Client):連接 Redis Cluster,向不同的 Master 發送請求,并根據哈希槽計算數據存儲位置。
Redis Cluster 默認使用 無中心化架構,每個節點既存儲數據,又維護整個集群的元數據(比如槽位信息、其他節點狀態等)。
總結
問題 | 解答 |
---|---|
為什么需要 Redis Cluster? | 解決單機存儲、可用性、性能瓶頸問題。 |
Redis Cluster 如何分片? | 采用 16384 個哈希槽,通過 CRC16(Key) % 16384 計算槽位,并分布到不同節點。 |
為什么是 16384 個哈希槽? | 兼顧計算效率、負載均衡、擴展性和數據遷移成本。 |
Redis Cluster 能動態擴容嗎? | 支持在線擴容/縮容,遷移期間不影響業務。 |
Redis Cluster 節點如何通信? | 采用 Gossip 協議,進行 PING/PONG 心跳檢測,支持自動故障轉移。 |
數據量太大怎么辦? | 采用水平擴展、數據淘汰策略、數據壓縮、冷熱分層等優化方案。 |
基本架構? | 由多個 Master 節點和 Slave 節點組成,每個 Master 負責一部分哈希槽。 |
Redis Cluster 通過數據分片 + 無中心化架構 + 自動故障恢復,實現了高可用、可擴展的分布式 Redis! 🚀
擴展閱讀
1. Redis Cluster 的哈希槽為什么是 16384?
Redis Cluster 采用 16384 個哈希槽(slot)來進行數據分片和管理,主要基于以下幾個原因:
(1) 兼顧性能與靈活性
- 太少的哈希槽:如果哈希槽數量太少,例如 1024,數據分布會很粗糙,負載均衡效果不佳。
- 太多的哈希槽:如果哈希槽數量過多(如 10^6 級別),每次集群管理和遷移操作都會涉及大量計算,增加開銷。
16384 是一個合理的折中方案,它既能保證數據分布的均衡性,又能在擴展和遷移時保持較低的計算和存儲成本。
(2) CRC16 計算的高效性
Redis Cluster 采用 CRC16(循環冗余校驗)算法計算哈希槽:
Slot = CRC16(Key) % 16384
CRC16 是一種高效的哈希計算方式,16384(21?)是 2 的冪,可以通過位運算高效計算哈希槽。
(3) 分片和遷移的平衡
-
16384 個槽可以被
多個 Master 節點
平均分配。例如:
- 3 個 Master:每個 Master 約管理 5461 個槽(16384 ÷ 3)。
- 6 個 Master:每個 Master 約 2730 個槽(16384 ÷ 6)。
-
這樣,擴容和數據遷移時,不會造成太大的數據重分布,遷移成本較低。
(4) 兼容性
Redis Cluster 設計時考慮到 多個 Redis 實例部署在多個服務器上,16384 適用于不同規模的集群:
- 小規模集群(3~6 個節點)→ 適量的槽可保證均衡分配。
- 大規模集群(數十個節點)→ 16384 個槽依然可以較好地分片。
2. 什么是 Gossip 協議?
(1) Gossip 協議的基本概念
Gossip 協議是一種 去中心化的分布式通信協議,用于 節點之間同步信息,類似于“八卦傳播”:
- 每個節點只與部分其他節點通信,而不是全網廣播。
- 信息在多個通信輪次后,逐步傳播到整個集群。
Redis Cluster 采用 Gossip 協議 來管理節點狀態,保持集群的可用性。
(2) Redis Cluster 中的 Gossip 協議
在 Redis Cluster 中,每個節點都會定期向部分節點 發送狀態信息,以此來同步集群狀態,確保各個節點了解彼此的情況。
Gossip 協議中的幾種消息
- PING:節點定期向其他節點發送
PING
消息,詢問對方狀態。 - PONG:收到
PING
后,節點返回PONG
作為響應,并附帶自己的狀態信息。 - MEET:新節點加入集群時,使用
MEET
消息通知集群中的其他節點。 - FAIL:如果某個 Master 節點被大多數節點判定為不可用,整個集群會廣播
FAIL
消息,觸發故障轉移。
示例
假設 Redis Cluster 有 6 個節點:
A B C D E F
- A 發送 PING 給 B 和 C。
- B 發送 PING 給 D 和 E。
- C 發送 PING 給 F 和 A。
- 經過幾輪傳播后,所有節點都可以獲取最新的集群狀態。
(3) Gossip 協議的優點
- 去中心化:無中心服務器,避免單點故障。
- 高效傳播:不像傳統的全網廣播,Gossip 只向部分節點發送信息,網絡開銷更小。
- 容錯性強:即使部分節點故障,其他節點仍可繼續傳播信息,保證集群健康。
總結
問題 | 解答 |
---|---|
Redis Cluster 的哈希槽為什么是 16384? | 16384 是 21?,兼顧數據分片均衡、遷移效率、CRC16 計算高效性。 |
Gossip 協議是什么? | 一種去中心化的分布式通信協議,Redis Cluster 通過 Gossip 進行節點狀態同步。 |
Gossip 協議在 Redis Cluster 中的作用? | 負責集群節點狀態同步、故障檢測(PING/PONG)、節點加入(MEET)、故障傳播(FAIL)。 |
Gossip 讓 Redis Cluster 實現了 去中心化管理、高效容錯,結合 16384 哈希槽的設計,使得 Redis Cluster 既能 高效分片存儲,又能 保證集群高可用!