Golang的一致性哈希實現


https://www.cnblogs.com/ldaniel/p/5413821.html

一致性哈希的具體介紹,可以參考:http://www.cnblogs.com/haippy/archive/2011/12/10/2282943.html

 
 1 import (
 2     "hash/crc32"
 3     "sort"
 4     "strconv"
 5     "sync"
 6 )
 7 ​
 8 const DEFAULT_REPLICAS = 100
 9 type SortKeys []uint32
10 ​
11 func (sk SortKeys) Len() int {
12     return len(sk)
13 }
14 ​
15 func (sk SortKeys) Less(i, j int) bool {
16     return sk[i] < sk[j]
17 }
18 ​
19 func (sk SortKeys) Swap(i, j int) {
20     sk[i], sk[j] = sk[j], sk[i]
21 }
22 ​
23 type HashRing struct {
24     Nodes map[uint32]string
25     Keys  SortKeys
26     sync.RWMutex
27 }
28 ​
29 func (hr *HashRing)New(nodes []string) {
30     if nodes == nil {
31         return
32     }
33 ​
34     hr.Nodes = make(map[uint32]string)
35     hr.Keys = SortKeys{}
36     for _, node := range(nodes) {
37         for i := 0; i < DEFAULT_REPLICAS; i++ {
38             str := node + strconv.Itoa(i)
39             hr.Nodes[hr.hashStr(str)] = node
40             hr.Keys = append(hr.Keys, hr.hashStr(str))
41         }
42     }
43     sort.Sort(hr.Keys)
44 }
45 
46 func (hr *HashRing) hashStr(key string) uint32 {
47     return crc32.ChecksumIEEE([]byte(key))
48 }
49 
50 func (hr *HashRing) GetNode(key string) string {
51     hr.RLock()
52     defer hr.RUnlock()
53     hash := hr.hashStr(key)
54     i := hr.get_position(hash)
55     return hr.Nodes[hr.Keys[i]]
56 }
57 ​
58 func (hr *HashRing) get_position(hash uint32) int {
59     i := sort.Search(len(hr.Keys), func(i int) bool {
60         return hr.Keys[i] >= hash})
61 ​
62     if i < len(hr.Keys) {
63         if i == len(hr.Keys) - 1 {
64             return 0
65         } else {
66             return i
67         }
68     } else {
69         return len(hr.Keys) - 1
70     }
71 }
72  
73  

基本思想:
(1)一共有16384個槽,每台服務器分管其中的一部分
(2)插入一個數據的時候,先根據CRC16算法計算key對應的值,然后用該值對16384取余數(即CRC16(key) mod 16384),確定將數據放到哪個槽里面
(3)在增加的時候,之前的節點各自分出一些槽給新節點,對應的數據也一起遷出
(4)客戶端可以向任何一個Redis節點發送請求,然后由節點將請求重定向到正確的節點上

為什么要選擇的槽是16384個呢?
crc16會輸出16bit的結果,可以看作是一個分布在0-2^16-1之間的數,redis的作者測試發現這個數對2^{14}求模的會將key在0-2^{14-1}之間分布得很均勻,因此選了這個值。

參考資料:
[1]https://www.cnblogs.com/abc-begin/p/8203613.html
[2]哈希算法:https://blog.csdn.net/tanggao1314/article/details/51457585



作者:尚亦汐
鏈接:https://www.jianshu.com/p/fa623e59fdcf
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM