`

详解Consistent Hashing算法

    博客分类:
  • java
 
阅读更多

 

在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(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原理示意图

 

1. 新增一个节点:只有在圆环上新增节点到逆时针方向的第一个节点之间的数据会受到影响(增加节点顺时针的第一个节点的信息需要迁移到增加节点上)。

2. 删除一个节点:只有在圆环上原来删除节点到 逆时针 方向的第一个节点之间的数据会受到影响(删除节点的信息需要迁移到顺时针的第一个节点上) ,因此通过Consistent Hashing很好地解决了负载均衡中由于新增节点、删除节点引起的hash值颠簸问题。

 

Consistent Hashing添加服务器示意图

 

虚拟节点(virtual nodes): 之所以要引进虚拟节点是因为在服务器(节点)数较少的情况下(例如只有3台服务器),通过hash(key)算出节点的哈希值在圆环上并不是均匀分布的(稀疏的),仍然会出现各节点负载不均衡的问题。虚拟节点可以认为是实际节点的复制品(replicas),本质上与实际节点实际上是一样的(key并不相同)。引入虚拟节点后,通过将每个实际的服务器(节点)数按照一定的比例(例如200倍)扩大后并计算其hash(key)值以均匀分布到圆环上。在进行负载均衡时候,落到虚拟节点的哈希值实际就落到了实际的节点上。由于所有的实际节点是按照相同的比例复制成虚拟节点的,因此解决了节点数较少的情况下哈希值在圆环上均匀分布的问题。

 

虚拟节点对Consistent Hashing结果的影响

从上图可以看出,在节点数为10个的情况下,每个实际节点的虚拟节点数为实际节点的100-200倍的时候,结果还是很均衡的。

2、Consistent Hashing算法实现:

文章Consistent Hashing 中描述了Consistent Hashing的Java实现,很简洁。

 

  1. importjava.util.Collection;
  2. importjava.util.SortedMap;
  3. importjava.util.TreeMap;
  4. publicclassConsistentHash<T>{
  5. privatefinalHashFunctionhashFunction;
  6. privatefinalintnumberOfReplicas;
  7. privatefinalSortedMap<Integer,T>circle=newTreeMap<Integer,T>();
  8. publicConsistentHash(HashFunctionhashFunction,intnumberOfReplicas,
  9. Collection<T>nodes){
  10. this.hashFunction=hashFunction;
  11. this.numberOfReplicas=numberOfReplicas;
  12. for(Tnode:nodes){
  13. add(node);
  14. }
  15. }
  16. publicvoidadd(Tnode){
  17. for(inti=0;i<numberOfReplicas;i++){
  18. circle.put(hashFunction.hash(node.toString()+i),node);
  19. }
  20. }
  21. publicvoidremove(Tnode){
  22. for(inti=0;i<numberOfReplicas;i++){
  23. circle.remove(hashFunction.hash(node.toString()+i));
  24. }
  25. }
  26. publicTget(Objectkey){
  27. if(circle.isEmpty()){
  28. returnnull;
  29. }
  30. inthash=hashFunction.hash(key);
  31. if(!circle.containsKey(hash)){
  32. SortedMap<Integer,T>tailMap=circle.tailMap(hash);
  33. hash=tailMap.isEmpty()?circle.firstKey():tailMap.firstKey();
  34. }
  35. returncircle.get(hash);
  36. }
  37. }

原文地址http://developer.51cto.com/art/201104/254419.htm

分享到:
评论

相关推荐

    chord算法ppt详解

    该协议使用一致哈希(Consistent Hashing)算法来将键映射到节点上,并提供了节点加入、离开和故障恢复机制。 一致哈希(Consistent Hashing) 一致哈希是Chord算法的核心组件,它将键 identifier(如IP地址)映射...

    PHP实现的一致性Hash算法详解【分布式算法】

    本文实例讲述了PHP实现的一致性Hash算法。分享给大家供大家参考,具体如下: 一致性哈希算法是分布式系统中常用的算法,为...因此,引入了一致性Hash(Consistent Hashing)分布算法 把数据用hash函数(如md5,sha1

    chord算法(经典论文)

    Chord协议是Chord系统的基础,它采用了一种变体的**一致性哈希**(Consistent Hashing)技术来分配键到Chord服务器节点上。在一致性哈希中,负载趋于平衡——所有节点接收的键值对的数量最多不超过平均数的\(1 + \...

    Memcached原理和使用详解

    常见的策略包括一致性哈希(Consistent Hashing),它可以确保即使在网络拓扑发生变化时也能保持良好的负载均衡。 #### 技巧与最佳实践 - **选择合适的键名**:合理地命名键值对于提升效率至关重要,应尽可能避免...

    大规模分布式框架fourinone-4.05.06

    fourinone是一款基于Java开发的分布式协调服务框架,旨在为分布式应用提供一致性哈希(Consistent Hashing)、分布式锁、分布式计数器等关键功能。在4.05.06这个版本中,它引入了全新的分布式数据库引擎——CoolHash...

    redis40-cluster-config.zip

    在 Redis 4.0 中,集群通过一致性哈希(Consistent Hashing)算法来分配数据,并利用主从复制保证数据的冗余和故障恢复。 二、集群的组成 Redis 集群由多个节点组成,每个节点既是服务提供者也是服务消费者。每个...

    memcache集群安装

    常见的有哈希一致性(Consistent Hashing)算法,通过计算键的哈希值来决定其所在的节点,保证在添加或删除节点时,只有少量键受到影响。 ### 6. 客户端配置 在应用程序中,你需要配置memcache客户端库以使用集群...

    codis-3.2.2.zip

    Codis使用一致性哈希算法(Consistent Hashing)进行数据分片,保证了数据迁移时的影响范围最小。每个键被映射到特定的Redis实例,当增加或减少实例时,只需要少量键的位置发生变化。 3. 源代码学习价值: Codis...

    libmemcached

    2. **分布策略**:通过一致性哈希(Consistent Hashing)等算法,libmemcached 可以将数据智能地分发到多个 memcached 服务器,确保在添加或移除服务器时尽量减少数据迁移。 3. **内存管理**:libmemcached 能够...

    Nginx反向代理与负载均衡

    - **一致性哈希(Consistent Hashing)**:将用户的请求 URI 或者指定字符串进行计算,之后的所有相同请求都将被分发到同一台服务器上。 #### 六、http_proxy_module 模块 http_proxy_module 模块是 Nginx 中用于...

    rocc:键值存储

    这可能涉及到分布式系统的设计,如一致性哈希(Consistent Hashing)算法来平衡数据负载,以及故障检测和恢复机制。 最后,`rocc`的API设计是其易用性的一个关键方面。简洁而直观的API可以让开发者更轻松地集成`...

    bosstomDB

    - 通过一致性哈希(Consistent Hashing)算法进行节点间的负载均衡,确保数据分布的均匀性。 - 支持自动故障切换,当某个节点出现故障时,系统能迅速将流量导向其他正常节点,保障服务的连续性。 2. **事务支持**...

    计算机基础精华

    - **Consistent Hashing** - 一致性哈希是一种分布式哈希技术,用于解决分布式系统中的负载均衡问题。 **7. 查找元素** - **一般二分查找** - 二分查找是一种在有序数组中查找特定元素的高效算法。 - **循环升序...

Global site tag (gtag.js) - Google Analytics