一致性哈希

一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。

定义**: “Consistent hashing is schema that provides hash table functionlity in a way that the addition or removal of one slot does not significantly change the mapping of keys to the slots.(wiki)”;

就是说,“一致性哈希,就是提供一个hashtable,它能在节点的加入和离开时不会导致映射关系的重大变化”。


一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义:
  • 平衡性(Balance):平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
  • 单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
  • 分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。
  • 负载(Load):负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同 的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。

为了解决平衡性问题, consistent hashing 引入了“虚拟节点”的概念,它可以如下定义:

“虚拟节点”( virtual node )是实际节点在 hash 空间的复制品( replica ),一实际个节点对应了若干个“虚拟节点”,这个对应个数也成为“复制个数”,“虚拟节点”在 hash 空间中以 hash 值排列。


Ketama是一致性哈希算法的一种实现:

  • 把Server的IP地址和端口进行MD5哈希,MD5的结果为一个160bit的数字,取其前32为作为一个整数。
  • 把缓存对象的Key做MD5哈希,同样得到一个整数。
  • 可以设想,Server的整数会根据大小形成一个数字环,而Key的哈希则分布在这些数字上或中间。
  • 如果Server的哈希等于Key的哈希,则把Key放在该Server上;否则,寻找第一个大于Key哈希的Server,用于存放Key
  • 在Server增加或删除时,只要变动周边的Server映射关系即可,不用全部重新哈希。之所以有这样优良的特性是因为,Server和Key采用了同样的值域。

一致性哈希的应用

在分布式缓冲集群的客户端使用一致性哈希算法,可用很好的实现系统的伸缩性。

References

每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)

Consistent hashing with Memcached or Redis, and a patch to libketama

Programmer’s Toolbox Part 3: Consistent Hashing

Dynamo: Amazon’s Highly Available Key-value Store

results matching ""

    No results matching ""