一致性哈希的原理,可以直接看小林coding的什么是一致性哈希
Golang——groupcache
在golang
官方的仓库中有个名叫groupcache
的仓库,里面提供了个简单的一致性哈希算法是实现,先简单分析一下这个的源码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| package consistenthash
import ( "hash/crc32" "sort" "strconv" )
type Hash func(data []byte) uint32
type Map struct { hash Hash replicas int keys []int hashMap map[int]string }
func New(replicas int, fn Hash) *Map { m := &Map{ replicas: replicas, hash: fn, hashMap: make(map[int]string), } if m.hash == nil { m.hash = crc32.ChecksumIEEE } return m }
func (m *Map) IsEmpty() bool { return len(m.keys) == 0 }
func (m *Map) Add(keys ...string) { for _, key := range keys { for i := 0; i < m.replicas; i++ { hash := int(m.hash([]byte(strconv.Itoa(i) + key))) m.keys = append(m.keys, hash) m.hashMap[hash] = key } } sort.Ints(m.keys) }
func (m *Map) Get(key string) string { if m.IsEmpty() { return "" }
hash := int(m.hash([]byte(key)))
idx := sort.Search(len(m.keys), func(i int) bool { return m.keys[i] >= hash })
if idx == len(m.keys) { idx = 0 }
return m.hashMap[m.keys[idx]] }
|
consistenthash
包对外提供了三个函数:
New(replicas int, fn Hash)
:返回一个Map
对象,这个Map
对象是重新定义过的,其中replicas
代表每个节点对应的虚拟节点的数量,fn
代表哈希函数(nil
的话会使用默认的哈希函数crc32.ChecksumIEEE
),并且初始化一个map
。
Add
:向哈希环上添加节点
Get
:传入一个key
,获取其对应分配的实际节点