27.4 一致性哈希算法的golang实现和迁移率测试

本节重点介绍 :

  • 一致性哈希算法的golang实现
    • 使用uint32封装索引排序的结构
    • 定义一致性哈希环数据结构
    • 选择哈希函数
    • 完成Add、Remove、Get方法

一致性哈希算法的golang实现

使用uint32封装索引排序的结构

  • 使用uint32封装
  • 实现Len Less Swap方法就可以使用sort.Sort排序
type uints []uint32

// Len returns the length of the uints array.
func (x uints) Len() int {
   
    return len(x) }

// Less returns true if element i is less than element j.
func (x uints) Less(i, j int) bool {
   
    return x[i] < x[j] }

// Swap exchanges elements i and j.
func (x uints) Swap(i, j int) {
   
    x[i], x[j] = x[j], x[i] }

定义一致性哈希环数据结构


type Consistent struct {
   
   
	circle       map[uint32]string // 索引和key的map
	members      map[string]bool   // 快速查找key的set
	sortedHashes uints             // 索引的有序数组
	replicas     int               // 虚拟节点数
	count        int64             // 节点总数
	sync.RWMutex                   //  读写锁
}

编写 初始化函数

  • 根据传入的虚拟节点数初始化
// 编写 初始化函数
func NewConsistent(replicas int) *Consistent {
   
   
	c := new(Consistent)
	c.replicas = replicas
	c.circle = make(map[uint32]string)
	c.members = make(map[string]bool)
	return c
}


Add方法添加元素

// Add方法添加元素
func (c *Consistent) Add(elt string) {
   
   
	c.Lock()
	defer c.Unlock()
	c.add(elt)
}

内部的add方法,遍历虚拟节点数添加key

  • 首先遍历虚拟节点数
  • 在key的前添加i
  • hashkey 用哈希算法生成一个 uint32
  • 然后将key更新的到member
  • 将uint32索引切片排序
// 内部的add方法,遍历虚拟节点数添加key
func (c *Consistent) add(key string) {
   
   
	for i := 0; i < c.replicas; i++ {
   
   
		c.circle[c.hashKey(c.genKey(key, i))] = key
	}
	c.members[key] = true
	c.updateSortedHashes()
	c.count++
}

将key加上虚拟节点的索引

// 将key加上虚拟节点的索引
func (c *Consistent) genKey(key string, idx int) string {
   
   
	return strconv.Itoa(idx) + key
}

核心方法 hashKey

  • 根据key生成hash值,底层使用murmur3算法
  • 这个算法比crc32均匀性要好
// 根据key生成hash值,底层使用murmur3算法,这个算法比crc32均匀性要好
func (c *Consistent) hashKey(key string) uint32 {
   
   
	return murmur3.Sum32(str2bytes(key))
}

同时需要频繁的string 转换为 []byte

  • 可以通过unsafe 强制转换绕过复制提高性能
// 可以通过unsafe 强制转换绕过复制提高性能
func str2bytes(s string) (b []byte) {
   
   
	sh := *(*reflect.StringHeader)(unsafe.Pointer(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

福大大架构师每日一题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值