在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin)、哈希算法(HASH)、最少连接算法(Least Connection)、响应速度算法(Response Time)、加权法(Weighted )等。其中哈希算法是最为常用的算法.
典型的应用场景是: 有N台服务器提供缓存服务,需要对服务器进行负载均衡,将请求平均分发到每台服务器上,每台机器负责1/N的服务。
常用的算法是对hash结果取余数 (hash() mod N):对机器编号从0到N-1,按照自定义的hash()算法,对每个请求的hash()值按N取模,得到余数i,然后将请求分发到编号为i的机器。但这样的算法方法存在致命问题,如果某一台机器宕机,那么应该落在该机器的请求就无法得到正确的处理,这时需要将当掉的服务器从算法从去除,此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算;如果新增一台机器,会有N /(N+1)的服务器的缓存数据需要进行重新计算。对于系统而言,这通常是不可接受的颠簸(因为这意味着大量缓存的失效或者数据需要转移)。那么,如何设计一个负载均衡策略,使得受到影响的请求尽可能的少呢?
在Memcached、Key-Value Store、Bittorrent DHT、LVS中都采用了Consistent Hashing算法,可以说Consistent Hashing 是分布式系统负载均衡的首选算法。
1、Consistent Hashing算法描述
下面以Memcached中的Consisten Hashing算法为例说明(参考memcached的分布式算法)。
由于hash算法结果一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,232-1]间,如果我们把一个圆环用232 个点来进行均匀切割,首先按照hash(key)函数算出服务器(节点)的哈希值, 并将其分布到0~232的圆上。
用同样的hash(key)函数求出需要存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器(节点)上。
Consistent hashing,memcached,load balancing,负载均衡,算法,key-value store Consistent Hashing原理示意图
新增一个节点的时候,只有在圆环上新增节点逆时针方向的第一个节点的数据会受到影响。删除一个节点的时候,只有在圆环上原来删除节点顺时针方向的第一个节点的数据会受到影响,因此通过Consistent Hashing很好地解决了负载均衡中由于新增节点、删除节点引起的hash值颠簸问题。
Consistent hashing,memcached,load balancing,负载均衡,算法,key-value store Consistent Hashing添加服务器示意图
虚拟节点(virtual nodes):之所以要引进虚拟节点是因为在服务器(节点)数较少的情况下(例如只有3台服务器),通过hash(key)算出节点的哈希值在圆环上并不是均匀分布的(稀疏的),仍然会出现各节点负载不均衡的问题。虚拟节点可以认为是实际节点的复制品(replicas),本质上与实际节点实际上是一样的(key并不相同)。引入虚拟节点后,通过将每个实际的服务器(节点)数按照一定的比例(例如200倍)扩大后并计算其hash(key)值以均匀分布到圆环上。在进行负载均衡时候,落到虚拟节点的哈希值实际就落到了实际的节点上。由于所有的实际节点是按照相同的比例复制成虚拟节点的,因此解决了节点数较少的情况下哈希值在圆环上均匀分布的问题。
Consistent hashing,memcached,load balancing,负载均衡,算法,key-value store
虚拟节点对Consistent Hashing结果的影响
从上图可以看出,在节点数为10个的情况下,每个实际节点的虚拟节点数为实际节点的100-200倍的时候,结果还是很均衡的。
2、Consistent Hashing算法实现:
文章Consistent Hashing中描述了Consistent Hashing的Java实现,很简洁。
import java.util.Collection;
import java.util.SortedMap;
import java.util.TreeMap;
public class ConsistentHash<T> {
private final HashFunction hashFunction;
private final int numberOfReplicas;
private final SortedMap<Integer, T> circle = new TreeMap<Integer, T>();
public ConsistentHash(HashFunction hashFunction, int numberOfReplicas,
Collection<T> 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<Integer, T> tailMap = circle.tailMap(hash);
hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
}
return circle.get(hash);
}
}
文章Consistent hashing implemented simply in Python描述了Consistent Hashing算法的python 实现
3、参考文档
http://weblogs.java.net/blog/2007/11/27/consistent-hashing
http://michaelnielsen.org/blog/consistent-hashing/
http://www.spiteful.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/
http://tech.idv2.com/2008/07/24/memcached-004/
http://amix.dk/blog/viewEntry/19367
http://amix.dk/blog/viewEntry/19369
http://www.javaworld.com/javaworld/jw-10-2008/jw-10-load-balancing-1.html
转自:http://www.yeeach.com/?p=591
分享到:
相关推荐
总之,`ConsistentHashing`是一个用于Python的工具,它实现了高效的一致性哈希算法,有助于构建稳定、可扩展的分布式系统。对于处理大数据量、高并发场景以及需要动态扩展的系统,这个库是十分实用的。
在分布式系统中,常常需要使用缓存,而且通常是集群,访问缓存和添加缓存都需要一个 hash 算法来寻找到合适的 Cache 节点。但,通常不是用取余hash,而是使用我们今天的主角—— 一致性 hash 算法。
“ConsistentHashingandRandomTrees: Distributed Caching Protocols for Relieving Hot Spots on the Worldwide Web”指的是由David Karger等人撰写的关于一致性哈希算法(Consistent Hashing)以及如何运用该算法...
一致性哈希(Consistent Hashing)是一种用于分布式系统的哈希算法,主要应用于分布式缓存、分布式数据库等场景,目的是在节点动态增减时保持哈希表的稳定性,从而最小化数据迁移的影响。它解决了传统哈希取模方法在...
跳跃一致哈希计算 甚至服务器之间的数据分布也非常重要:另一个重要方面是能够... 关于一致性哈希,使用的算法是谷歌的论文“A Fast, Minimal Memory, Consistent Hash Algorithm”中提出的Jump Consistent Hashing。
主要特点: 1 独有的"框架"与"plugins...7 插件SCache(memcache)采用consistent hashing算法,支持分布式服务与依赖KEY,同时也支持file,apc缓存 8 其它更多灵活可定制的插件,请查看wiki或者samples下的例子
为解决这个问题,文章采用了一种高效的Consistent Hashing算法进行分布式部署,该算法能够较为均匀地分配数据到各个缓存节点,即使在节点数量发生变化时也能最小化缓存数据的重分配。 使用Consistent Hashing算法,...
一致性哈希算法(Consistent Hashing)是一种在分布式系统中平衡数据分布的策略,尤其适用于缓存服务如Memcached或Redis。它的核心思想是通过哈希函数将对象映射到一个固定大小的环形空间中,然后将服务器也映射到这个...
而Consistent Hashing算法能够提供一种更均匀的分配策略,以解决分散不均的问题,进一步提高系统的稳定性和可伸缩性。 memcached在实际应用中也表现出色,特别是在需要高并发访问的Web应用程序中。例如,日本的mixi...
此外,它还引入了Consistent Hashing算法来优化分布式缓存的节点管理,减少因节点增减导致的大规模缓存失效问题。 在实际应用中,mixi作为日本的一个社交网络平台,大规模使用memcached来优化其Web应用的性能。他们...
一致性哈希(Consistent Hashing)是一种分布式哈希算法,主要应用于分布式缓存、负载均衡等领域,例如在Redis、Memcached等系统中广泛使用。它解决了传统哈希算法在节点动态增减时导致的大量数据迁移问题。在Java中...
因此,文中提出了Consistent Hashing算法作为改进方案。该算法通过将Memcached服务器和键值哈希到一个虚拟的环(continuum)上,然后顺时针查找第一个服务器节点,从而最小化了服务器变动对缓存命中率的影响。 在...
一致性哈希(Consistent Hashing)是一种在分布式系统中解决数据分片问题的算法,它在Go语言中的实现对于构建可扩展且容错的服务至关重要。在Go开发中,尤其是在涉及分布式缓存、负载均衡等场景下,一致性哈希能够...
#fly-archflylib创立的各种常见的架构技术内容列表cassandra-demo cassandra数据库的入门编程consistent-hash Java implementation of consistent-hashing基于java的一致性hash的实现一致性hash(consistent-hashing)...
主要特点: 1 独有的"框架"与"plugins"分离...7 插件SCache(memcache)采用consistent hashing算法,支持分布式服务与依赖KEY,同时也支持file,apc缓存 8 其它更多灵活可定制的插件,请查看wiki或者samples下的例子
该协议使用一致哈希(Consistent Hashing)算法来将键映射到节点上,并提供了节点加入、离开和故障恢复机制。 一致哈希(Consistent Hashing) 一致哈希是Chord算法的核心组件,它将键 identifier(如IP地址)映射...
一致性哈希算法(Consistent Hashing)是一种在分布式系统中实现负载均衡的算法,尤其在分布式缓存如Memcached和Redis等场景下广泛使用。它解决了传统哈希算法在节点增减时导致的大量数据迁移问题,提高了系统的可用...