
传统哈希算法(如hash(key) % N)在集群扩容或缩容时,数据迁移成本极高。例如,3节点扩容至4节点需迁移75%的数据,10节点扩容至11节点需迁移90.9%的数据。这是由于取模运算的基数(节点数N)变化导致所有key的映射关系被破坏。
一致哈希将哈希空间组织为环形结构(模数为2^32),节点和key均通过哈希函数映射到环上。key的寻址规则为:从key的位置顺时针查找,遇到的第一个节点即为目标节点。 优势:节点变化时仅影响相邻区间的数据。例如:
当物理节点较少时,可能出现数据分布倾斜(如80%请求集中在单个节点)。通过为每个物理节点创建多个虚拟节点(如"Node-A-01"、"Node-A-02"等),并将虚拟节点均匀映射到哈希环上,可实现:
// 虚拟节点示例代码
type VirtualNode struct {
HashKey uint32
PhysicalNode string
}
func AddNode(ring *[]VirtualNode, nodeName string, replicaCount int) {
for i := 0; i < replicaCount; i++ {
vnode := VirtualNode{
HashKey: crc32.ChecksumIEEE([]byte(fmt.Sprintf("%s-%d", nodeName, i))),
PhysicalNode: nodeName,
}
*ring = append(*ring, vnode)
}
sort.Slice(*ring, func(i, j int) bool { return (*ring)[i].HashKey < (*ring)[j].HashKey })
}