【Golang】consistenthash一致性哈希

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) 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 len(m.keys) == 0 {
		return ""
	}
	hash := int(m.hash([]byte(key)))
	idx := sort.Search(len(m.keys), func(i int) bool {
		return m.keys[i] >= hash		
	})
	return m.hashMap[m.keys[idx%len(m.keys)]]
}

每一个真实结点对应replicas个虚拟结点,从一个key获取它存储的结点的时候会选择相邻最近的结点。

发布了422 篇原创文章 · 获赞 14 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/105463650