一 算法描述
当 Hash 表更新节点的数量时,只有 k/n 的关键字位置有变化,其他关键字的位置的映射关系不变。与一致性 Hash 算法相比,其他算法的节点个数 n 变化后,更多的 Key 关键字和节点的映射会发生变化。
实现一致性 Hash 算法的前提是:
-
每个请求的 Key 的范围是 0 到 2的32次方,一共有 k 个 Key。
-
一共有 n 个节点,每个节点对应一个服务器。
二 常规实现
把 Key 的取值范围内的数字(一共2的32方个数字)组成一个环节,然后随机在这个环上落 n 个点,相邻的两个点形成一个左闭右开的区间,一共有 n 个区间。
每个 Key 一定只落在 n 个区间中的一个区间内,它属性该区间所分配的节点。
当服务节点增加或减少时,会有区间新增或消失,平均只有 k/n 个 Key 会受到影响,变更其属于的节点。
如下图所示,在插入节点 C 之前,1,2,3 都属于节点 A,当插入节点 C 后,1,2 归属 C,属于B 的节点不会改变。
三 增加虚节点
常规实现在实际应用中会遇到问题:当 n 的数量太少时,会导致 n 个节点所管辖的区间并不均匀。
既然是 n 的数量太少,那么增加 n 的数量不就行了?对的,可以成倍地增加 n 的数量,将一个实际的节点扩充为 100 倍的虚节点,先查找每个 Key 属于哪个虚节点,再查找该需虚节点属于哪个实节点。
由于众多虚节点的引入,使得每个节点被分配到的 Key 的数量差距变小。
入如下图所示,增加节点 A、B、C 节点的虚节点后,把区间分得更细小,使得每个实际节点被分配到的 Key 的数量更均匀。还可以通过设置权值,让不同处理能力的实节点处理不同量级的 Key。