在 go-zero 的分布式缓存零碎分享里,Kevin 重点讲到过一致性hash的原理和分布式缓存中的实际。本文来具体讲讲一致性hash的原理和在 go-zero 中的实现。

以存储为例,在整个微服务零碎中,咱们的存储不可能说只是一个单节点。

  • 一是为了进步稳固,单节点宕机状况下,整个存储就面临服务不可用;
  • 二是数据容错,同样单节点数据物理损毁,而多节点状况下,节点有备份,除非互为备份的节点同时损毁。

那么问题来了,多节点状况下,数据应该写入哪个节点呢?

hash

所以实质来讲:咱们须要一个能够将输出值“压缩”并转成更小的值,这个值通常情况下是惟一、格局极其紧凑的,比方uint64

  • 幂等:每次用同一个值去计算 hash 必须保障都能失去同一个值
hash
hashkey % Nhash route散发
consistent hash

consistent hash

consistent hash

rehash

rehash
key31
normal hash

数据歪斜

node 1node
consistent hashvirtual node
virtual node

具体实现

Get()

Get

先说说实现的原理:

keyvirtual nodeh.keys[index]ringactual node
ring[]nodevirtual node hashvirtual node hash
nodevirtual nodering

这个其实也就表明了一致性hash的调配策略:

virtual nodekeynodevirtual nodevirtual nodehashvirtual node

Add Node

Get
type ConsistentHash struct {
  hashFunc Func                            // hash 函数
  replicas int                            // 虚构节点放大因子
  keys     []uint64                    // 存储虚构节点hash
  ring     map[uint64][]interface{}                    // 虚构节点与理论node的对应关系
  nodes    map[string]lang.PlaceholderType    // 理论节点存储【便于疾速查找,所以应用map】
  lock     sync.RWMutex
}

好了这样,根本的一个一致性hash就实现齐备了。

具体代码:https://github.com/tal-tech/g…

应用场景

结尾其实就说了,一致性hash能够宽泛应用在分布式系统中:

redis clustercache proxy

以上这些分布式系统中,都能够在负载平衡模块中应用。

我的项目地址

https://github.com/tal-tech/go-zero

欢送应用 go-zero 并 star 反对咱们!

微信交换群

关注『微服务实际』公众号并点击 交换群 获取社区群二维码。