Help us shape the future of Go! Take the 2026 Go Developer Survey

consistent

package
v1.12.19 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CalcHashVirtualKey added in v1.12.12

func CalcHashVirtualKey(key string, index int) uint64

hashVirtualKey 计算以播种 key 生成的第 index 个虚拟点的哈希值: FNV-64a(key + ":" + index) + mix64。同一节点相邻 index 经 mix64 雪崩打散, 使该节点的虚拟点在环上均匀分布。

func CalcHashVirtualNode added in v1.12.12

func CalcHashVirtualNode(nodeID uint32, index int) uint64

hashVirtualNode 计算虚拟节点的哈希值

Types

type Hash

type Hash[A comparable, T any] struct {
	// contains filtered or unexported fields
}

Hash 一致性哈希实现 A:节点 id 类型(comparable,用作 nodes 索引与环槽位的归属标识) T:节点负载类型(任意)

func NewHash

func NewHash[A comparable, T any](virtuals int) *Hash[A, T]

NewHash 创建一致性哈希实例

func (*Hash[A, T]) AddNode

func (ch *Hash[A, T]) AddNode(nodeId A, node T) error

AddNode 添加节点。nodeId 为该节点唯一 id(环槽位以它标识归属并去重), 该节点的第 i 个虚拟点环位置 = hash(fmt.Sprint(nodeId) + ":" + i)。 整型 id 的播种布局与 CalcHashVirtualNode 一致(十进制无前导零)。

func (*Hash[A, T]) Clear

func (ch *Hash[A, T]) Clear()

Clear 清空所有节点

func (*Hash[A, T]) GetNode

func (ch *Hash[A, T]) GetNode(key string) T

GetNode 根据key获取对应的节点

func (*Hash[A, T]) GetNodeByHash added in v1.12.12

func (ch *Hash[A, T]) GetNodeByHash(key uint64) T

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]) GetNodeCount

func (ch *Hash[A, T]) GetNodeCount() int

GetNodeCount 获取节点数量

func (*Hash[A, T]) GetNodes

func (ch *Hash[A, T]) GetNodes() []T

GetNodes 获取所有节点

func (*Hash[A, T]) GetNodesByKey added in v1.12.12

func (ch *Hash[A, T]) GetNodesByKey(key string, count int) []T

GetNodesForKey 获取某个key的所有备份节点(用于故障转移)

func (*Hash[A, T]) GetVirtualNodeCount

func (ch *Hash[A, T]) GetVirtualNodeCount() int

GetVirtualNodeCount 获取虚拟节点数量(即哈希环槽位数)

func (*Hash[A, T]) RemoveNode

func (ch *Hash[A, T]) RemoveNode(nodeID A) T

RemoveNode 移除节点(按节点 id)

func (*Hash[A, T]) UpdateNode

func (ch *Hash[A, T]) UpdateNode(nodeID A, node T) error

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 获取虚拟节点数量(即哈希环槽位数;无锁)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL