一致性哈希算法(Consistent Hashing)
一致性哈希(Consistent Hashing)是在分布式缓存系统中的常用的一种算法。在一个大型的缓存系统中,缓存的内容通常都分布式的存储在多台缓存服务中的,如何更好的定位客户端所需的缓存?
传统哈希算法
哈希是一种信息特征提取的方法,可以将长度的信息映射成固定长度的特征值,映射的过程也就是哈希算法。例如有3台缓存服务器时,可以使用对3取模作为哈希算法,按照哈希的结果0~2将缓存的请求分别定位到3台服务器。
使用传统哈希算法有一个明显的缺陷,就是当缓存服务器发生增减时,用于取模的数发生变化,哈希的结果几乎都发生了变化,缓存定位的结果也相应变化,最终导致大多数缓存不可用。假设在有3台缓存服务器的缓存系统中增加1台服务器,对于信息值0~9,只有0~2保持了原哈希结果,3~9的哈希结果都变了。
一致性哈希算法
一致性哈希算法是David Karger等在论文Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web中提出的。其基本原理是采用一个较大的哈希值域空间,如2^32,将这些值构成一个虚拟的环。缓存服务器也以其id映射到这个环中。为一条缓存寻找缓存服务器时,计算其哈希值并映射环中,然后按瞬时间方向,遇到的第一台服务器即为要寻找的服务器。
如图所示,使用一致性哈希以后,当在有3台服务器的缓存系统增加1台服务器时,仅有标为金色的一段缓存被重新定位,其它缓存的定位不变。
虚拟节点
使用一致性哈希算法分配缓存时,有一个常见的问题,就是当缓存服务器较少时,可能出现缓存分配的严重不均匀。例如在本文第2张图的例子中,如果缓存在哈希值空间环上的分配是均匀的,则在Cache Server 1中的缓存条目要比Server 0和Server2少得多,为了解决这个问题,可以引入虚拟节点。如图所示,Server 0#0和Server 0#1都代表的是Server 0,但其在环上映射的位置不同,可以在一定程度上避免分配不均匀的问题。在本例中,和未增加虚拟节点之前相比,Server 1上分配的缓存条目除了绿色的一段,新增了金色的一段,缓存的分配更加均衡。
参考资料
http://blog.codinglabs.org/articles/consistent-hashing.html