Redis Cluster爲什麼有16384個槽?

前言

Redis 集羣並沒有使用一致性hash,而是引入了哈希槽的概念。Redis 集羣有16384個哈希槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,集羣的每個節點負責一部分hash槽。但爲什麼哈希槽的數量是16384(2^14)個呢,這個問題在github上有人提過,作者也給出瞭解答(點擊查看),下面我們來簡單分析一下。

正文

Redis Cluster的工作原理:我們讓兩個redis節點之間進行通信的時候,需要在客戶端執行下面一個命令

127.0.0.1:7000>cluster meet 127.0.0.1:7001

如下圖所示


意思很簡單,讓7000節點和7001節點知道彼此存在!
在握手成功後,兩個節點之間會定期發送ping/pong消息,交換數據信息,如下圖所示。

在redis節點發送心跳包時需要把所有的槽信息放到這個心跳包裏,以便讓節點知道當前集羣信息在發送心跳包時使用char進行bitmap壓縮後是2k(16384÷8÷1024=2kb),也就是說使用2k的空間創建了16k的槽數。

雖然使用CRC16算法最多可以分配65535(2^16-1)個槽位,65535=65k,壓縮後就是8k(8 * 8 (8 bit) * 1024(1k) = 8K),也就是說需要需要8k的心跳包,作者認爲這樣做不太值得;並且一般情況下一個redis集羣不會有超過1000個master節點,所以16k的槽位是個比較合適的選擇

(1)如果槽位爲65536,發送心跳信息的消息頭達8k,發送的心跳包過於龐大。
如上所述,在消息頭中,最佔空間的是myslots[CLUSTER_SLOTS/8]。
當槽位爲65536時,這塊的大小是:
65536÷8÷1024=8kb
因爲每秒鐘,redis節點需要發送一定數量的ping消息作爲心跳包,如果槽位爲65536,這個ping消息的消息頭太大了,浪費帶寬。
(2)redis的集羣主節點數量基本不可能超過1000個。
如上所述,集羣節點越多,心跳包的消息體內攜帶的數據越多。如果節點過1000個,也會導致網絡擁堵。因此redis作者,不建議redis cluster節點數量超過1000個。
那麼,對於節點數在1000以內的redis cluster集羣,16384個槽位夠用了。沒有必要拓展到65536個。
(3)槽位越小,節點少的情況下,壓縮率高
Redis主節點的配置信息中,它所負責的哈希槽是通過一張bitmap的形式來保存的,在傳輸過程中,會對bitmap進行壓縮,但是如果bitmap的填充率slots / N很高的話(N表示節點數),bitmap的壓縮率就很低。
如果節點數很少,而哈希槽數量很多的話,bitmap的壓縮率就很低。

 

文章參考:

https://blog.csdn.net/BrianWey/article/details/102552504

https://www.jianshu.com/p/de268f62f99b



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章