Documentation
¶
Index ¶
- func CalcHashVirtualKey(key string, index int) uint64
- func CalcHashVirtualNode(nodeID uint32, index int) uint64
- type Hash
- func (ch *Hash[A, T]) AddNode(nodeId A, node T) error
- func (ch *Hash[A, T]) Clear()
- func (ch *Hash[A, T]) GetNode(key string) T
- func (ch *Hash[A, T]) GetNodeByHash(key uint64) T
- func (ch *Hash[A, T]) GetNodeByKey(nodeID A) T
- func (ch *Hash[A, T]) GetNodeCount() int
- func (ch *Hash[A, T]) GetNodes() []T
- func (ch *Hash[A, T]) GetNodesByKey(key string, count int) []T
- func (ch *Hash[A, T]) GetVirtualNodeCount() int
- func (ch *Hash[A, T]) RemoveNode(nodeID A) T
- func (ch *Hash[A, T]) UpdateNode(nodeID A, node T) error
- type StaticHash
- func (h *StaticHash[A, T]) AddNode(nodeId A, node T) error
- func (h *StaticHash[A, T]) Freeze() *StaticHash[A, T]
- func (h *StaticHash[A, T]) GetNode(key string) T
- func (h *StaticHash[A, T]) GetNodeByHash(key uint64) T
- func (h *StaticHash[A, T]) GetNodeByKey(nodeID A) T
- func (h *StaticHash[A, T]) GetNodeCount() int
- func (h *StaticHash[A, T]) GetNodes() []T
- func (h *StaticHash[A, T]) GetNodesByKey(key string, count int) []T
- func (h *StaticHash[A, T]) GetVirtualNodeCount() int
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CalcHashVirtualKey ¶ added in v1.12.12
hashVirtualKey 计算以播种 key 生成的第 index 个虚拟点的哈希值: FNV-64a(key + ":" + index) + mix64。同一节点相邻 index 经 mix64 雪崩打散, 使该节点的虚拟点在环上均匀分布。
func CalcHashVirtualNode ¶ added in v1.12.12
hashVirtualNode 计算虚拟节点的哈希值
Types ¶
type Hash ¶
type Hash[A comparable, T any] struct { // contains filtered or unexported fields }
Hash 一致性哈希实现 A:节点 id 类型(comparable,用作 nodes 索引与环槽位的归属标识) T:节点负载类型(任意)
func (*Hash[A, T]) AddNode ¶
AddNode 添加节点。nodeId 为该节点唯一 id(环槽位以它标识归属并去重), 该节点的第 i 个虚拟点环位置 = hash(fmt.Sprint(nodeId) + ":" + i)。 整型 id 的播种布局与 CalcHashVirtualNode 一致(十进制无前导零)。
func (*Hash[A, T]) GetNodeByHash ¶ added in v1.12.12
GetNodeByUint64 根据uint64类型的key获取节点
func (*Hash[A, T]) GetNodeByKey ¶ added in v1.12.12
func (ch *Hash[A, T]) GetNodeByKey(nodeID A) T
GetNodeByID 根据节点 ID 获取节点
func (*Hash[A, T]) GetNodesByKey ¶ added in v1.12.12
GetNodesForKey 获取某个key的所有备份节点(用于故障转移)
func (*Hash[A, T]) GetVirtualNodeCount ¶
GetVirtualNodeCount 获取虚拟节点数量(即哈希环槽位数)
func (*Hash[A, T]) RemoveNode ¶
func (ch *Hash[A, T]) RemoveNode(nodeID A) T
RemoveNode 移除节点(按节点 id)
func (*Hash[A, T]) UpdateNode ¶
UpdateNode 更新节点信息(按节点 id;环上该节点的槽位引用随之刷新、位置不变)
type StaticHash ¶ added in v1.12.12
type StaticHash[A comparable, T any] struct { // contains filtered or unexported fields }
StaticHash 一次性构建、运行期只读的「完全无锁」一致性哈希。 A:节点 id 类型(comparable);T:节点负载类型(任意)。
与 Hash[A, T] 的关系:播种方式与环结构完全一致(同一节点 id 集合得到 完全相同的环布局与路由结果),可在一处切换实现而无数据归属变化; 区别仅在同步策略:
- Hash :读路径每次加 RWMutex,支持运行期动态增删节点(成本换灵活性);
- StaticHash:读路径完全无锁、无原子、无堆分配(零同步开销), 代价是构建完成(Freeze)后不允许任何写操作。
适用场景:服务启动时一次性加载全部节点,运行期不会新增/移除/变更节点; 任何节点变更(新增、上下线、扩缩容)都必须重启服务后重新构建。
用法:
h := consistent.NewStaticHash[uint32, *Node](150)
h.AddNode(1, n1)
h.AddNode(2, n2)
h.Freeze() // 构建完成,进入只读阶段(对外提供服务前调用)
// 此后 h 可被任意多个 goroutine 并发读取,全程无锁
owner := h.GetNodeByHash(playerID)
chain := h.GetNodesByKey("player-10001", 3)
并发安全模型:
- 构建阶段(AddNode)必须在启动流程中完成,写入发生在对外发布之前 (同一 goroutine 顺序执行,或经通道/启动同步建立 happens-before);
- Freeze 之后所有字段不再写入。Go 语言保证多 goroutine 并发只读 slice 与 map 是安全的,因此读路径不需要任何同步原语;
- 误在 Freeze 后调用 AddNode 会 panic(frozen 为原子检查,误用也呈确定行为)。
func NewStaticHash ¶ added in v1.12.12
func NewStaticHash[A comparable, T any](virtuals int) *StaticHash[A, T]
NewStaticHash 创建 StaticHash(构建期对象,AddNode 后需 Freeze)
func (*StaticHash[A, T]) AddNode ¶ added in v1.12.12
func (h *StaticHash[A, T]) AddNode(nodeId A, node T) error
AddNode 添加节点(仅构建期、Freeze 前调用,无锁——构建假定单 goroutine)。 nodeId 播种与 Hash.AddNode 完全一致:第 i 个虚拟点环位置 = CalcHashVirtualKey(fmt.Sprint(nodeId), i)。节点 id 重复会报错。 Freeze 后调用会 panic。
func (*StaticHash[A, T]) Freeze ¶ added in v1.12.12
func (h *StaticHash[A, T]) Freeze() *StaticHash[A, T]
Freeze 冻结哈希:构建完成后调用,此后只读。重复调用安全。 返回接收者自身,便于链式。Freeze 后调用 AddNode 将 panic。
func (*StaticHash[A, T]) GetNode ¶ added in v1.12.12
func (h *StaticHash[A, T]) GetNode(key string) T
GetNode 根据 string key 获取对应的节点(无锁,Freeze 后并发安全)
func (*StaticHash[A, T]) GetNodeByHash ¶ added in v1.12.12
func (h *StaticHash[A, T]) GetNodeByHash(key uint64) T
GetNodeByHash 根据 uint64 key 获取对应的节点(无锁,Freeze 后并发安全)
func (*StaticHash[A, T]) GetNodeByKey ¶ added in v1.12.12
func (h *StaticHash[A, T]) GetNodeByKey(nodeID A) T
GetNodeByKey 根据节点 id 获取节点(无锁;map 只读并发安全)
func (*StaticHash[A, T]) GetNodeCount ¶ added in v1.12.12
func (h *StaticHash[A, T]) GetNodeCount() int
GetNodeCount 获取节点数量(无锁)
func (*StaticHash[A, T]) GetNodes ¶ added in v1.12.12
func (h *StaticHash[A, T]) GetNodes() []T
GetNodes 获取所有节点(无锁;返回副本)
func (*StaticHash[A, T]) GetNodesByKey ¶ added in v1.12.12
func (h *StaticHash[A, T]) GetNodesByKey(key string, count int) []T
GetNodesByKey 获取某个 key 的所有备份节点(用于故障转移;无锁)
func (*StaticHash[A, T]) GetVirtualNodeCount ¶ added in v1.12.12
func (h *StaticHash[A, T]) GetVirtualNodeCount() int
GetVirtualNodeCount 获取虚拟节点数量(即哈希环槽位数;无锁)