一致性Hash算法

文章目录

    • 背景
    • 常见方案
      • 一、Hash取模
      • 二、一致性Hash算法
      • 三、虚拟节点
    • 思考题
    • 参考


背景

随着数据量的不断增长,单个数据库已经无法支撑现有的业务时,就需要引入分布式存储。比如MySQL分库分表、Redis Cluster 集群。

引入分布式存储时,不得不面临一个问题:如何保证数据尽可能均匀分布到各个节点上,并且尽量在增减节点时较小范围对现有数据的影响。

以下以集群缓存服务器为案例分析,分析如何实现数据均匀分布的。

常见方案

一、Hash取模

1.1 描述
根据 key 进行 Hash,然后取模分配到N个节点,则可以通过 Hash(key) % N 计算出存放的节点。

1.2 优点
可以实现数据均衡分布,简单易懂。

1.3 缺点
当有节点增加或者删除时,会造成大量数据失效。因此容错性和扩展性都比较差。
下面以3个节点减到2个节点为例子,计算一下失效率:
在这里插入图片描述
图中6个key,标记红色为失效的有4个,失效率=66.7%

二、一致性Hash算法

2.1 描述
首先,构建一个一致性 Hash 环的结构。一致性 Hash 环的大小是 0 到 2^32-1
一致性Hash算法_第1张图片

然后,将缓存服务器的节点(如 IP 地址或 hostname)经过 Hash 算法后散列到这个环上。
如有3个节点时,分布情况如下图所示:
一致性Hash算法_第2张图片
有3个key需要存储到缓存集群时,分别计算 Hash 后映射到这个环上。
然后,按照顺时针方向把 key1 定位到 Node1,key2 定位到 Node2,key3 定位到 Node3。
一致性Hash算法_第3张图片
2.2 优点
2.2.1 容错性
当 Node2 宕机之后,key2 被重新定位到 Node3 节点上,此时只会影响 Node1 和 Node2 之间的数据,很好实现了容错。
一致性Hash算法_第4张图片
2.2.2 扩展性
当缓存集群需要扩展一个 Node4 节点时,key1 被重新定位到 Node4 节点上,此时只会影响 Node3 和 Node4 之间的数据,很好实现了可扩展性。
一致性Hash算法_第5张图片
2.3 缺点
仔细看刚刚图可以发现,节点之间的分布并不均匀。Node1 和 Node2 距离较近,分布较少的数据;而 Node2 和 Node3 距离较远,分布了较多的数据。

三、虚拟节点

为了解决一致性 Hash 出现的分布不均匀的问题,引入 虚拟节点 来解决该问题。
将每台集群节点虚拟为一组节点,如图中每个节点虚拟出2个节点(实际应用中可能有很多)。将虚拟服务器的 Hash 值放置在 Hash 环上。
一致性Hash算法_第6张图片
当有一个 key 需要存储到缓存集群时,先找到虚拟节点,再得到物理服务器信息。

假如有新节点加入时,也按相同规则分配时,即可保证数据的均匀分布。

思考题

数据库在做分库分表,如何能做到在增加分表数时,尽可能少迁移数据呢?

参考

深入解读缓存(二)——一致性Hash算法
一致性 Hash 算法分析

你可能感兴趣的:(算法,算法,分布式,redis)