之前爱可生开源社区公众号发表了dble 沿用 jumpstringhash,移除 Mycat 一致性 hash 原因解析, 阐述了跳跃法相对环割法的性能优势。很多读者表示对其中"跳跃法的原理"不是很理解,本文就来详细阐述一下。 一致性哈希
之前爱可生开源社区公众号发表了dble 沿用 jumpstringhash,移除 Mycat 一致性 hash 原因解析, 阐述了跳跃法相对环割法的性能优势。很多读者表示对其中"跳跃法的原理"不是很理解,本文就来详细阐述一下。
首先,我们的需求是,将数据(key-value pair)分布在多个节点上。这点可以简单的用取模实现,
节点 | key |
---|---|
1 | 1 4 7 10 |
2 | 2 5 8 11 |
3 | 3 6 9 12 |
然而,当增加新节点时,数据将发生大规模转移:
节点 | key |
---|---|
1 | (1) 5 9 |
2 | (2) 6 10 |
3 | (3) 7 11 |
4 | 4 8 12 |
一致性哈希的主要目的是,在节点数量发生变更时,只需要在节点间移动少量数据,而不是"全部洗牌"。
除了经典的环割法一致性哈希外,Google 发表了另一种实现简洁且高效的跳跃法一致性哈希《A Fast, Minimal Memory, Consistent Hash Algorithm》(文末附链接)
在爱可生开源数据库中间件 dble 中,关于 jump consistent hash 的配置方法详见 dble 官方手册中"跳增字符串算法"的部分(文末附链接)。
与原始论文不同, 本文节点(又称 bucket)从 1 开始编号,而非从 0 开始。
ch(key,1)=1
(ch 为 consistent_hash 之缩写)。可以看到,每增加一个节点,只需要移动总共 1/n 的数据,而不是取模法中的几乎所有数据。
所谓随机抽取,我们采用可重现的随机:首次调用 Rand()
之前将 key 作为随机数种子。因而对于一个 key,首次放入和后续取回使用的是相同的随机数序列。
例如有 k1,k2,k3 三个 key, 随着节点数量从 1 到 15 增长, 它们各自会在某一时刻“跳跃”,而后“稳定”一段时间。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
k1 | 1 | 1 | 3 | 3 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 |
k2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 8 | 8 | 8 | 8 | 8 | 8 | 8 |
k3 | 1 | 2 | 2 | 2 | 2 | 6 | 6 | 8 | 8 | 8 | 11 | 11 | 11 | 11 |
我们用数学归纳法来表达一下某个 key 在不同节点数时的位置:
结合基础情况和归纳情况,我们得出了 n 为任意正整数时的分配方法。数学归纳法的逻辑和递归代码直接对应:
func ch(r *rand.Rand, k int, i int) int {
if i == 1 {
// 基础情况
return 1
} else {
// 归纳情况
b := ch(k, i-1)
if rand.Float() < 1.0/float64(i) {
return i
} else {
return b
}
}
}
func ch_wrapper(k int, i int) int {
r := rand.Seed(k) // 在计算之前, 将key作为随机数种子
return ch(r, k, i)
}
注意,要先计算 ch(k, i-1)
再决定本轮是否跳转( if rand < 1.0/i
)。不能因为本轮决定跳转就不计算上一轮的结果,否则会因节点数不同而产生不一样的随机序列。
工程代码中一般使用循环代替递归。本文不再赘述递归转循环的办法。
我们看到,对于一个 key,我们要从 1~N(N 为节点数)循环一遍,即复杂度为节点数的线性关系. 原始论文中给出了一个巧妙的方法,使复杂度从线性降低到了对数:既然每一次是否跳跃的决策中我们随机决定,那么,与其一次次决定是否跳跃,我们是否能够直接随机地决定下一次跳跃的目标?当然,这个随机目标的取值符合一定的概率分布。
关于这个巧妙方法的具体内容和论证,敬请期待下篇。
文中相关资源链接: 《A Fast, Minimal Memory, Consistent Hash Algorithm》 https://arxiv.org/ftp/arxiv/papers/1406/1406.2294.pdf 《DBLE 手册中跳增字符算法部分》 Https://actiontech.GitHub.io/dble-docs-cn/1.config_file/1.01_rule.xml.html
--结束END--
本文标题: 技术分享 | Jump Consistent Hash 原理解析(上篇)
本文链接: https://lsjlt.com/news/4292.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-10-23
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0