一致性哈希
背景:历史故事
问题
- 服务扩缩容,数据迁移成本
- 数据分布不均匀
- 正常:系统运行效率和性能
- 异常:单点故障或者容灾扩容,容易导致雪崩的连锁反应
解决方案和效果
服务扩缩容,数据迁移成本
传统哈希实现
取模数随着节点数变动而变动,节点数不同的情况下数据集合计算的到的哈希分布变动不稳定,数据迁移通常不稳定,全量迁移的可能性相对较大。
例:服务节点从4个缩容为1个,关注其中数据的分布变化情况(如key=5、key=9数据的变化)
数据迁移成本,假设数据量是M,节点数是N。当服务进行扩缩容时,所有key计算得到的hash值分布和原先的分布大相径庭,那么这种最坏的情况会导致每个服务节点上的全量数据都要进行迁移,时间复杂度是O(M)。
一致性哈希实现
取模数是固定的,和节点数量无关。数据集合计算的到的哈希分布也是稳定的,数据迁移通常是部分的迁移。
例:下面是一个一致性哈希的经典案例
- 首先,将关键字经由通用的哈希函数映射为 32 位整型哈希值。这些哈希值会形成 1 个环,最大的数字 232 相当于 0。
- 其次,设集群节点数为 N,将哈希环由小至大分成 N 段,每个主机节点处理哈希值落在该段内的数据。比如下图中,当节点数 N 等于 3 且均匀地分段时,节点 0 处理哈希值在 [0, 31∗232] 范围内的关键字,节点 1 处理 [31∗232, 32∗232] 范围内的关键字,而节点 2 则处理的范围是 [32∗232, 232]
- 3台性能相同的服务器取模分配
- 2:1:1 的权重
- 节点 0 处理哈希值在 [0, 31∗232] 范围内的关键字,节点 1 处理 [31∗232, 32∗232] 范围内的关键字,而节点 2 则处理的范围是 [32∗232, 232]
- 3台性能不同的服务器取模分配
- 2:1:1 的权重
- 节点 0 处理的哈希值范围调整为 [0, 231],节点 1 的处理范围调整为 [231, 3∗230],节点 2 的处理范围调整为 [3∗230, 232]
可见,其中取模的值是固定的,于是数据集的hash分布也是稳定的。
数据迁移成本,假设数据量是M,节点数是N。当服务进行扩缩容时,所有key计算得到的hash值分布和原先的分布是几乎没有变化的。那么只要移动M/N的数据量就可以完成数据迁移,时间复杂度也就是O(M/N)。
数据分布不均匀
- 正常:系统运行效率和性能
- 异常:单点故障或者容灾扩容,容易导致雪崩的连锁反应
没有引入虚拟节点层
例:异常情况,节点0宕机,导致0上的数据迁移到相邻的节点1。
引入虚拟节点层
可以理解为额外维护的的一个哈希表,使得物理机上的数据在哈希环上不一定是连续的,可以由隔开的不同分段的数据组合而成。
例:如果图中绿色的节点 0 宕机,按照哈希环上数据的迁移规则,8 个绿色虚拟节点上的数据就会沿着顺时针方向,分别迁移至相邻的虚拟节点上,最终会迁移到真实节点 1(橙色)、节点 2(蓝色)、节点 3(水红色)上。所以,宕机节点上的数据会迁移到其他所有节点上。扩容也是同理。
在实际的工程中,虚拟节点的数量会大很多,比如 Nginx 的一致性哈希算法,每个权重为 1 的真实节点就含有160 个虚拟节点。注意,虚拟节点增多虽然会提升均衡性,但也会消耗更多的内存与计算力。
拓展
标签:32,哈希,一致性,迁移,数据,节点,232 来源: https://blog.csdn.net/qq_43230007/article/details/123164193
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。