Skip to content

Commit 693ebe8

Browse files
committed
一致Hash算法
1 parent 3ff4b29 commit 693ebe8

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

MD/Consistent-Hash.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,48 @@
1515

1616
## 一致 Hash 算法
1717

18-
一致 Hash 算法
18+
一致 Hash 算法是将所有的哈希值构成了一个环,其范围在 `0 ~ 2^32-1`。如下图:
19+
20+
![](https://ws1.sinaimg.cn/large/006tNc79gy1fn8kbmd4ncj30ad08y3yn.jpg)
21+
22+
之后将各个节点散列到这个环上,可以用节点的 IP、hostname 这样的唯一性字段作为 Key 进行 `hash(key)`,散列之后如下:
23+
24+
![](https://ws3.sinaimg.cn/large/006tNc79gy1fn8kf72uwuj30a40a70t5.jpg)
25+
26+
之后需要将数据定位到对应的节点上,使用同样的 `hash 函数` 将 Key 也映射到这个环上。
27+
28+
![](https://ws3.sinaimg.cn/large/006tNc79gy1fn8kj9kd4oj30ax0aomxq.jpg)
29+
30+
这样按照顺时针方向就可以把 k1 定位到 `N1节点`,k2 定位到 `N3节点`,k3 定位到 `N2节点`
31+
32+
### 容错性
33+
这时假设 N1 宕机了:
34+
35+
![](https://ws3.sinaimg.cn/large/006tNc79gy1fn8kl9pp06j30a409waaj.jpg)
36+
37+
依然根据顺时针方向,k2 和 k3 保持不变,只有 k1 被重新映射到了 N3。这样就很好的保证了容错性,当一个节点宕机时只会影响到少少部分的数据。
38+
39+
### 拓展性
40+
41+
当新增一个节点时:
42+
43+
![](https://ws1.sinaimg.cn/large/006tNc79gy1fn8kp1fc9xj30ca0abt9c.jpg)
44+
45+
在 N2 和 N3 之间新增了一个节点 N4 ,这时会发现受印象的数据只有 k3,其余数据也是保持不变,所以这样也很好的保证了拓展性。
46+
47+
## 虚拟节点
48+
到目前为止该算法依然也有点问题:
49+
50+
当节点较少时会出现数据分布不均匀的情况:
51+
52+
![](https://ws2.sinaimg.cn/large/006tNc79gy1fn8krttekbj30c10a5dg5.jpg)
53+
54+
这样会导致大部分数据都在 N1 节点,只有少量的数据在 N2 节点。
55+
56+
为了解决这个问题,一致哈希算法引入了虚拟节点。将每一个节点都进行多次 hash,生成多个节点放置在环上称为虚拟节点:
57+
58+
![](https://ws2.sinaimg.cn/large/006tNc79gy1fn8ktzuswkj30ae0abdgb.jpg)
59+
60+
计算时可以在 IP 后加上编号来生成哈希值。
61+
62+
这样只需要在原有的基础上多一步由虚拟节点映射到实际节点的步骤即可让少量节点也能满足均匀性。

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
- [是否为快乐数字](https://github.com/crossoverJie/Java-Interview/blob/master/src/main/java/com/crossoverjie/algorithm/HappyNum.java#L38-L55)
4444
- [链表是否有环](https://github.com/crossoverJie/Java-Interview/blob/master/src/main/java/com/crossoverjie/algorithm/LinkLoop.java#L32-L59)
4545
- [从一个数组中返回两个值相加等于目标值的下标](https://github.com/crossoverJie/Java-Interview/blob/master/src/main/java/com/crossoverjie/algorithm/TwoSum.java#L38-L59)
46+
- [一致 Hash 算法](https://github.com/crossoverJie/Java-Interview/blob/master/MD/Consistent-Hash.md)
4647

4748
### 附加技能
4849

0 commit comments

Comments
 (0)