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