一.節點取余
根據redis的鍵或者ID,再根據節點數量進行取余。
key:value如下
name:1 zhangsna:18:北京
對name:1 進行hash操作,得出來得值是2423423452,用這個值除3,余1則放到1號節點中進行存儲,余2則放到2號節點存儲。
二.一致性hash
一致性哈希分區(Distributed Hash Table) 實現思路是為系統中每個節
點分配一個token, 范圍一般在0~232, 這些token構成一個哈希環。 數據讀寫
執行節點查找操作時, 先根據key計算hash值, 然后順時針找到第一個大於
等於該哈希值的token節點, 如圖10-3所示
這種方式相比節點取余最大的好處在於加入和刪除節點只影響哈希環中
相鄰的節點, 對其他節點無影響。 但一致性哈希分區存在幾個問題:
·加減節點會造成哈希環中部分數據無法命中, 需要手動處理或者忽略
這部分數據, 因此一致性哈希常用於緩存場景。
當使用少量節點時, 節點變化將大范圍影響哈希環中數據映射, 因此
這種方式不適合少量數據節點的分布式方案。
·普通的一致性哈希分區在增減節點時需要增加一倍或減去一半節點才
能保證數據和負載的均衡。
傳統的取模方式
例如10條數據 0 1 2 3 4 5 6 7 8 9
3個節點node a b c
如果按照取模的方式,那就是
node a: 0,3,6,9
node b: 1,4,7
node c: 2,5,8
當增加一個節點的時候,數據分布就變更為
node a:0,4,8
node b:1,5,9
node c: 2,6
node d: 3,7
總結:數據3,4,5,6,7,8,9在增加節點的時候,都需要做搬遷,成本太高
而搬遷就是從節點a的機器上把數據移動到節點d上
一致性哈希方式
最關鍵的區別就是,對節點和數據,都做一次哈希運算,然后比較節點和數據的哈希值,數據取和節點最相近的節點做為存放節點。這樣就保證當節點增加或者減少的時候,影響的數據最少。
十條數據,算出各自的哈希值,(這里就不變了,實際上要經過一系列計算)
0 : 0
1 : 1
2 : 2
3 : 3
4 : 4
5 : 5
6 : 6
7 : 7
8 : 8
9 : 9
有三個節點,算出各自的哈希值
node a: 3
node b: 5
node c: 7
這個時候比較兩者的哈希值,5等於b,則歸屬b,4小於b,歸屬b,3等於a,則歸屬a,最后所有大於c的,歸屬於c(這里只是模擬)
相當於整個哈希值就是一個環,對應的映射結果:
node a: 0,1,2,3
node b: 4,5
node c: 6,7,8,9
這個時候加入node d, 就可以算出node d的哈希值:
node d: 9
這個時候對應的數據就會做遷移:
node a: 0,1,2,3
node b: 4,5
node c: 6,7
node d: 8,9
只有最后8,9這2條數據被存儲到新的節點,其他不變
三.虛擬槽分區
虛擬槽分區巧妙地使用了哈希空間, 使用分散度良好的哈希函數把所有
數據映射到一個固定范圍的整數集合中, 整數定義為槽(slot) 。 這個范圍
一般遠遠大於節點數, 比如Redis Cluster槽范圍是0~16383。 槽是集群內數據
管理和遷移的基本單位。 采用大范圍槽的主要目的是為了方便數據拆分和集
群擴展。 每個節點會負責一定數量的槽, 如圖10-4所示。
當前集群有5個節點, 每個節點平均大約負責3276個槽。 由於采用高質
量的哈希算法, 每個槽所映射的數據通常比較均勻, 將數據平均划分到5個
節點進行數據分區。 Redis Cluster就是采用虛擬槽分區, 下面就介紹Redis數
據分區方法。
redis將每個數據放到一個槽中,而很多槽放到節點中。當槽進行擴容,只需要把某些槽遷移到新節點即可。