![841c3d0a5f4cddce58ce821a8d0d2f88.png](https://img-blog.csdnimg.cn/img_convert/841c3d0a5f4cddce58ce821a8d0d2f88.png)
分布式哈希(Distributed Hashing)
分布式环境中,需要进行分布式哈希来进行负载均衡,减少忙碌服务器的负载。例如,对一个键(key)做了哈希后,需要确定它保存在哪个服务器上面。一致性散列(consistent hash)函数的特点是,当函数范围(例如,服务器的数量)变化,它变化的最少。 一个对一致性哈希的典型应用是Memcached.
对长度做的哈希
假设不使用一致性哈希函数,只是简单地根据服务器的数量进行哈希。
假设有3台服务器A,B,C, 现在采用的策略是hash(key) mod N
。
一般来说,取余(mod)操作比较慢,如果服务器的数量是2^N
,计算mod操作时,可以用hash(key) & (2^N )
来提高速度。
![24cc2c8e8cd0f39b2996bae4ab3c285b.png](https://img-blog.csdnimg.cn/img_convert/24cc2c8e8cd0f39b2996bae4ab3c285b.png)
key在服务器的分布情况如下:
![4b26108c8f27a3c936885ec6f15e4624.png](https://img-blog.csdnimg.cn/img_convert/4b26108c8f27a3c936885ec6f15e4624.png)
再散列问题
这时,如果服务器的数量发生改变,因为策略是hash(key) mod N
。 key在服务器的分布情况会发生较大的变化。假设减少了一台服务器,现在只有服务器A,B。
![97a491323287dc1427456d8f66a27ecf.png](https://img-blog.csdnimg.cn/img_convert/97a491323287dc1427456d8f66a27ecf.png)
分布情况:
![e642273609b259b90dcb5c0c68ee2e0f.png](https://img-blog.csdnimg.cn/img_convert/e642273609b259b90dcb5c0c68ee2e0f.png)
可以看到,hash(key) mod N
, 由于N这个值域发送变化,key的分布全部都变了。这会导致,短时间内,对key的查询失效,增加服务器的负担,减低性能。
解决方法:一致性hash
一致性hash是一个分布式的hash方法,它的hash与服务器的数量无关,因为它将key 映射在一个虚拟的hash环(hash ring),使得服务变得更为可扩展。
假设将hash(key)
映射到一个环,最小值是0,它的角度也为0度,最大值是INT_MAX
,角度是360度。
![4c16b7908232d57fc17bc58754d4eeb4.png](https://img-blog.csdnimg.cn/img_convert/4c16b7908232d57fc17bc58754d4eeb4.png)
![f9d245c60d3c946167ab7a290db11d5b.png](https://img-blog.csdnimg.cn/img_convert/f9d245c60d3c946167ab7a290db11d5b.png)
同样地,将服务器做系统的映射,放到hash ring。
![e53a9a5ea3dde05e12d609e695e2a515.png](https://img-blog.csdnimg.cn/img_convert/e53a9a5ea3dde05e12d609e695e2a515.png)
![028ea98fe24080a853d21bcf890f45d2.png](https://img-blog.csdnimg.cn/img_convert/028ea98fe24080a853d21bcf890f45d2.png)
我们可以设置自己的规则,以逆时针方向,每个key都属于距离它最近的服务器
![a81cb93c0b66981cfd1f5c79e97513c2.png](https://img-blog.csdnimg.cn/img_convert/a81cb93c0b66981cfd1f5c79e97513c2.png)
![597fe170bb6ef187806b0ff38d078612.png](https://img-blog.csdnimg.cn/img_convert/597fe170bb6ef187806b0ff38d078612.png)
从编程的角度,我们可以将服务器的值(角度或者hash值)保存在一个有序列表中,然后去搜索这个列表,找到第一个它的值大于或者等于key值的服务器,如果找不到,就去去列表的第一个服务器。
为了保证key是均匀第分布在服务器中,我们给服务器赋予很多的标签(label),例如A0...A9
, B0...B9
, C0...C9
,然后将其散布到hash ring中。每个服务器的label的数量就是这个服务器的权重(weight), 这是用来调整key落在服务器上的可能性。权重越大,label越多,一个服务器保存的key越多。
例如,给服务器A
,B
, C
相同的权重,10个权重,分布在hash ring中。
![c530453aa04f9988667f5edef54dfcc9.png](https://img-blog.csdnimg.cn/img_convert/c530453aa04f9988667f5edef54dfcc9.png)
![289da696c134bc1c28216f5e5ff745eb.png](https://img-blog.csdnimg.cn/img_convert/289da696c134bc1c28216f5e5ff745eb.png)
使用hash ring的好处是,如果标签C0...C9
被移除, 之前属于C0...C9
标签的key就会落到A0...A1
和B0...B1
上面,其他标签的key没有变化。
![649c70c001e9604bfeac57f2c31a3d41.png](https://img-blog.csdnimg.cn/img_convert/649c70c001e9604bfeac57f2c31a3d41.png)
同样地,当服务器数量增加时,变化也是类似的。
如果有k
个key,N
个服务器,当服务器数量变化时。只有k/N
个key发生变化。
更多内容,访问
一致性哈希算法www.liangyaopei.com![29b3f6567aee10c7ca365f8291839a1e.png](https://img-blog.csdnimg.cn/img_convert/29b3f6567aee10c7ca365f8291839a1e.png)