Redis数据分布一致性哈希
一致性哈希
一致性哈希的原理:
把所有的哈希值空間組織成一個虛擬的圓環(哈希環),整個空間按順時針方向組織。因為是環形空間,0 和2^32-1 是重疊的。
假設我們有四臺機器要哈希環來實現映射(分布數據),我們先根據機器的名稱或者IP 計算哈希值,然后分布到哈希環中(紅色圓圈)。
現在有4 條數據或者4 個訪問請求,對key 計算后,得到哈希環中的位置(綠色圓圈)。沿哈希環順時針找到的第一個Node,就是數據存儲的節點。
在這種情況下,新增了一個Node5 節點,不影響數據的分布。
刪除了一個節點Node4,只影響相鄰的一個節點。
谷歌的MurmurHash 就是一致性哈希算法。在分布式系統中,負載均衡、分庫分表等場景中都有應用。
一致性哈希解決了動態增減節點時,所有數據都需要重新分布的問題,它只會影響到下一個相鄰的節點,對其他節點沒有影響。
但是這樣的一致性哈希算法有一個缺點,因為節點不一定是均勻地分布的,特別是在節點數比較少的情況下,所以數據不能得到均勻分布。解決這個問題的辦法是引入虛擬節點(Virtual Node)。
比如:2 個節點,5 條數據,只有1 條分布到Node2,4 條分布到Node1,不均勻。
Node1 設置了兩個虛擬節點,Node2 也設置了兩個虛擬節點(虛線圓圈)。
這時候有3 條數據分布到Node1,1 條數據分布到Node2。
Redis 虛擬槽分區
Redis 既沒有用哈希取模,也沒有用一致性哈希,而是用虛擬槽來實現的。
Redis 創建了16384 個槽(slot),每個節點負責一定區間的slot。比如Node1 負責0-5460,Node2 負責5461-10922,Node3 負責10923-16383。
Redis 的每個master 節點維護一個16384 位(2048bytes=2KB)的位序列,比如:序列的第0 位是1,就代表第一個slot 是它負責;序列的第1 位是0,代表第二個slot不歸它負責。
對象分布到Redis 節點上時,對key 用CRC16 算法計算再%16384,得到一個slot的值,數據落到負責這個slot 的Redis 節點上。
查看key 屬于哪個slot:
redis> cluster keyslot leon注意:key 與slot 的關系是永遠不會變的,會變的只有slot 和Redis 節點的關系。
問題:怎么讓相關的數據落到同一個節點上?
比如有些multi key 操作是不能跨節點的,如果要讓某些數據分布到一個節點上,例如用戶2673 的基本信息和金融信息,怎么辦?
在key 里面加入{hash tag}即可。Redis 在計算槽編號的時候只會獲取{}之間的字符串進行槽編號計算,這樣由于上面兩個不同的鍵,{}里面的字符串是相同的,因此他們可以被計算出相同的槽。
user{2673}base=…
user{2673}fin=…
127.0.0.1:7293> set a{qs}a 1 OK 127.0.0.1:7293> set a{qs}b 1 OK 127.0.0.1:7293> set a{qs}c 1 OK 127.0.0.1:7293> set a{qs}d 1 OK 127.0.0.1:7293> set a{qs}e 1 OK問題:客戶端連接到哪一臺服務器?訪問的數據不在當前節點上,怎么辦?
?
總結
以上是生活随笔為你收集整理的Redis数据分布一致性哈希的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis数据分布哈希后取模
- 下一篇: Redis中的客户端重定向