GroupCache源码分析(3):consistenthash

GroupCache源码分析(3):consistenthash

(1)概述:

一致性哈希原理参考极客兔兔的文章:
动手写分布式缓存 - GeeCache第四天 一致性哈希(hash)

(2)源码:

// Package consistenthash provides an implementation of a ring hash.
// Package consistenthash 提供了一个哈希环
package consistenthash

import (
	"hash/crc32"
	"sort"
	"strconv"
)
// Hash maps bytes to uint32
type Hash func(data []byte) uint32

type Map struct {
	hash     Hash
	// 虚拟节点倍数
	replicas int
	// 哈希环 keys
	keys     []int // Sorted
	// 虚拟节点与真实节点之间的联系,键是虚拟节点的哈希值,值是真实节点的名称
	hashMap  map[int]string
}

// New 采取依赖注入的方式,允许用于替换成自定义的 Hash 函数,默认为 crc32.ChecksumIEEE 算法。
func New(replicas int, fn Hash) *Map {
	m := &Map{
		replicas: replicas,
		hash:     fn,
		hashMap:  make(map[int]string),
	}
	// 如果 fn 为空,也就是不自定义设计哈希值,则默认为 crc32.ChecksumIEEE 算法
	if m.hash == nil {
		m.hash = crc32.ChecksumIEEE
	}
	return m
}

// IsEmpty returns true if there are no items available.
func (m *Map) IsEmpty() bool {
	return len(m.keys) == 0
}

// Add adds some keys to the hash.
// 添加 keys 到 hash 中
func (m *Map) Add(keys ...string) {
	for _, key := range keys {
		// 创建虚拟节点和真实节点之间的映射
		for i := 0; i < m.replicas; i++ {
			// 计算hash值
			hash := int(m.hash([]byte(strconv.Itoa(i) + key)))
			// 加入到keys
			m.keys = append(m.keys, hash)
			m.hashMap[hash] = key
		}
	}
	// 给keys排列
	sort.Ints(m.keys)
}

// Get gets the closest item in the hash to the provided key.
// Get 拿到最近的一个节点提供给键
func (m *Map) Get(key string) string {
	if m.IsEmpty() {
		return ""
	}

	// 计算 key 的哈希值
	hash := int(m.hash([]byte(key)))

	// Binary search for appropriate replica.
	// 二分检索拿到 大于等于 key的哈希值的第一个虚拟节点
	idx := sort.Search(len(m.keys), func(i int) bool { return m.keys[i] >= hash })

	// Means we have cycled back to the first replica.
	// 因为是一个哈希环,所以如果idx等于 keys的长度的话,那它的下标就应该是0
	if idx == len(m.keys) {
		idx = 0
	}

	return m.hashMap[m.keys[idx]]
}

一致性哈希就到这。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值