我最近一段时间在研究 consistent hash。介绍它的paper(Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web
byDavid Karger
et al) 十年前就出现了,不过直到最近才悄悄的有越来越多的service开始使用consistent hash,这些service包括Amazon’s Dynamo
,以及memcached
(向Last.fm敬
礼)。那么到底什么是consistent hash呢?大家为什么要关注它呢?
consistent
hash的需求来自于运行一个cache集群(例如web
cache)时遇到的一些限制。如果你拥有一个由n台cache机器组成的集群,那么最普通的load
balance方式就是把进来的对象o放在编号为hash(o) mod
n的那一台上。你会觉得这个方案简介优美,直到有一天,由于种种原因你不得不增加或者移除一些cache机器,这时,集群的机器数目n变了,每个对象都被
hash求余到了新的机器。这将是一场灾难,因为真正存放内容的server会被来自于cache集群的request拖垮。这时整个系统看起来就像没有
cache一样。这就是大家为什么关心consistent hash,因为大家需要使用它来避免系统被拖垮。
情
况如果是这样的就好了:当集群添加了一台cache机器,该机器只从其他cache机器中读取应得的那些对象;相应的,当一个cache机器从集群中移
除,最好是它cache住的对象被分配给其他的cache机器(而没有更多的数据移动)。这种理想的情境就是consistent
hash所追求并实现的:如果可能的话,始终将同一组对象分配给相同的机器。
consistent
hash算法背后最基础的思想就是:对object和cache
machine使用相同的hash函数。这样做的好处是能够把cache机器映射到一段interval上,而这段interval就会包含一定数目的对
象的hash值。如果某台cache机器被移除了,那么它映射到的interval被和它相邻的一个cache机器托管,其他所有的cache机器都不用
变。
描述
让我们来更深入的来了解一下consistent hash。Hash的作用就是把object和cache映射到一个数值范围上。Java程序员对hash应该很熟悉了–每个对象的hashCode方法会返回一个在[-231
, 231
-1]的int型整数。我们把这个数值范围首尾相接的映射到一个环上。下图描述了一组object(1, 2, 3, 4)和一组cache(A, B, C)分别映射在Hash环上。(图片源于Web Caching with Consistent Hashing
by David Karger et al
)
图1
要
确定某个object会缓存在哪个cache,我们从这个object开始顺时针前进,知道我们遇到一个cache点。这样,从上图的例子我们看到
object 1和4 归cache A,object 2归cache B,而cache C缓存的事object 3。考虑一下,当cache
C被移除了,会发生什么?在这种情况下,object 3被cache
A缓存住,所有其他object都不用移动。如果如图2,cache集群添加了cache D,那么D会缓存object 3和4,把object
1留给A。
图2
一
切都很好,除了一点:指派给每个cache的间距大小太随机了,这样就会object的分配也极度的不均匀。
为了解决这个问题,我们引入”virtual
nodes”这个概念:即每个cache在hash环上有多个副本,也就是说,每当我们加入一个cache,在环上都会为这个cache增加多个点。
我
下面的代码做了一个仿真实验,将10,000个object存入10个cache,你会在下面的plot图中看到virtual
nodes的影响。x轴上是每个cache的副本数(对数刻度)。当x值较小时,我们看到objects在caches中的分布是不平衡的(y轴是以百分
比形式表示objects在caches中分布的标准差)。随着cache的replica的增加,objects的分布趋向于更加平衡。这个实验说明了
每个cache大概100-200的replica能够使object的分布较为平衡(标准差在5%-10%)
experiment result
实现
下
面是使用Java的一个简单实现。要使consistent
hash的效果明显,很重要的一点是使用一个mix的很好的hash函数。Java中object的hashCode方法的大多数实现都没有提供很好的
mix性能。所以我们提供一个HashFunction接口,以便于定制使用的hash函数。在这里推荐MD5.
import java.util.Collection;
import java.util.SortedMap;
import java.util.TreeMap;
public class ConsistentHash {
private final HashFunction hashFunction;
private final int numberOfReplicas;
private final SortedMap circle =
new TreeMap();
public ConsistentHash(HashFunction hashFunction,
int numberOfReplicas, Collection nodes) {
this.hashFunction = hashFunction;
this.numberOfReplicas = numberOfReplicas;
for (T node : nodes) {
add(node);
}
}
public void add(T node) {
for (int i = 0; i < numberOfReplicas; i++) {
circle.put(hashFunction.hash(node.toString() + i),
node);
}
}
public void remove(T node) {
for (int i = 0; i < numberOfReplicas; i++) {
circle.remove(hashFunction.hash(node.toString() + i));
}
}
public T get(Object key) {
if (circle.isEmpty()) {
return null;
}
int hash = hashFunction.hash(key);
if (!circle.containsKey(hash)) {
SortedMap tailMap =
circle.tailMap(hash);
hash = tailMap.isEmpty() ?
circle.firstKey() : tailMap.firstKey();
}
return circle.get(hash);
}
}
上面的代码用一个integer的
sorted map
来表示hash circle。当
ConsistentHash
创建时,每个node都被添加到circle map中(添加的次数由
numberOfReplicas
控制)。每个replica的位置,由node的名字加上一个数字后缀所对应的hash值来决定。
要为一个object找到它应该去的node(
get
方法),我们把object的hash值放入map中查找。大多数情况下,不会恰好有一个node和这个object重合(即使每个node都有一定量的replica,hash的值空间也比node数要多得多),所以用
tailMap
方法找到map中的下一个key。如果tail map为空,那么我们转一圈,找到circle中的第一个key。
相关推荐
一致性哈希算法是一种分布式哈希(Distributed Hash Table, DHT)技术,它解决了在分布式环境中数据分片和负载均衡的问题。在传统的哈希算法中,如果增加或减少服务器节点,会导致大量数据重新分配,而一致性哈希...
一致性哈希算法最初由麻省理工学院的K等人提出,并被广泛应用于分布式系统中,以解决节点动态变化时数据一致性问题。其核心思想是通过引入哈希环,将数据对象均匀分布在哈希环上的不同节点中,以此降低节点变更对...
一致性哈希算法是一种在分布式系统中解决数据分片和负载均衡问题的算法,它主要解决了在动态添加或移除节点时,尽可能少地改变已经存在的数据分布。在云计算和大数据处理领域,一致性哈希被广泛应用,例如在分布式...
一致性哈希(Consistent Hashing)是一种分布式哈希算法,主要应用于分布式缓存、负载均衡等领域,例如Memcached和Redis等系统。它解决了在分布式环境中数据分片与节点动态增减时,尽量减少数据迁移的问题。带虚拟...
一致性哈希算法通过将哈希值空间组织成一个虚拟的环状结构,使得每个存储节点仅负责环上的一段区域,从而有效减少了节点变化时的数据迁移量。然而,一致性哈希算法也存在一些问题,比如在节点数量较少时,节点间的...
【摘要】中的“高效扩展”和“分布式数据库”是本文的核心话题,研究的是如何利用一致性哈希算法在大数据时代高效地扩展分布式数据库。一致性哈希算法最初由Karger等人提出,目的是解决分布式缓存的问题,它弥补了...
【一致性哈希与Chord1】是一篇关于分布式哈希算法的文章,主要讨论了一致性哈希和普通哈希的区别,以及如何通过引入虚拟节点来优化一致性哈希的分布问题。 1. **普通哈希算法**: - Java中的`HashMap`类是一个典型...
一致性哈希算法是一种分布式哈希表(DHT)中用于解决数据分片和负载均衡问题的算法。在大型分布式系统中,例如缓存系统、分布式数据库等,一致性哈希能够确保当节点加入或离开时,尽可能少的数据需要迁移,从而保持...
一致性哈希算法是一种分布式哈希(Distributed Hash Table, DHT)技术,旨在解决在分布式环境中数据分布不均匀的问题。Ketama算法是基于一致性哈希的一种优化实现,由Last.fm公司的Simon Willison提出,其目标是在...
一致性哈希(Consistent Hashing)是一种特殊的哈希算法,它在分布式缓存和负载均衡等场景中被广泛应用。它通过将数据和服务器节点映射到一个哈希环上,提供了一种在节点增减时能够最小化数据重新分配的机制。本文将...
《Mycat一致性哈希分片算法详解》 在分布式数据库系统中,数据分片是实现高可用性和可扩展性的重要手段。Mycat作为一款开源的分布式数据库中间件,其核心特性之一就是数据分片策略,而一致性哈希分片算法在其中扮演...
一致性哈希算法是一种在分布式系统中用于解决数据分发和负载均衡问题的算法。随着互联网技术的快速发展,分布式系统已经成为支撑大规模服务的关键技术之一。在分布式系统中,多个节点通过网络协同工作,提供高可用性...
### 一致性哈希算法及其在分布式系统中的应用 #### 摘要 一致性哈希算法是一种用于解决分布式系统中节点动态变化导致的数据重新分布问题的关键技术。它通过将哈希空间映射到一个循环的空间中,实现了数据节点的高效...
一致性哈希算法是一种在分布式系统中解决负载均衡和数据分布问题的有效方法。在传统的哈希算法中,当添加或移除服务器节点时,大部分数据需要重新映射,导致大规模的数据迁移。而一致性哈希算法通过特定的设计,能够...
一致性哈希算法应用及优化是IT领域中分布式系统设计的核心技术之一,特别是在处理大规模数据分布与缓存系统中,其重要性不言而喻。本文将深入探讨一致性哈希算法的基本概念、工作原理以及在实际场景中的应用和优化...
Mycat 一致性哈希分片算法 Mycat是一款开源的数据库中间件,支持各种数据库管理系统,包括 MySQL、 PostgreSQL、Oracle 等。Mycat 的核心功能之一是分片(Sharding),它可以将大量数据分布式存储在多个数据库节点...
一致性哈希算法的php版,希望能帮到phper了解一致性哈希
一致性哈希算法(Consistent Hashing)是一种在分布式系统中实现负载均衡的算法,尤其在分布式缓存如Memcached和Redis等场景下广泛使用。它解决了传统哈希算法在节点增减时导致的大量数据迁移问题,提高了系统的可用...
一致性哈希算法作为解决这一问题的重要手段之一,近些年来得到了广泛关注和应用。 一致性哈希算法由David Karger等人在1997年提出,它是一种特殊的哈希算法,主要用于分布式系统中实现负载均衡。与传统的哈希算法...