因为曾经面试的老是被问到一致性hash的问题。今天看了一些文章,算是对这个问题的一些学习。
1.一致性哈希(consistent hash)简单介绍
一致性哈希(consistent hash)是一种分布式算法,经常使用于负载均衡。通经常常使用的负载均衡的算法有:轮循算法(Round Robin)、哈希算法(HASH)、最少连接算法(Least Connection)、响应速度算法(Response Time)、加权法(Weighted )等
典型的应用场景是: 有N台server提供缓存服务,须要对server进行负载均衡,将请求平均分发到每台server上,每台机器负责1/N的服务。但添加和降低server数量,可以最小影响数据在server之间的迁移。
2.算法的描写叙述
百度一下,就可以得到!
这里写图片描写叙述
3.算法实现(java)

 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);
 }

}   

上面这个java语言的实现。

依据上面的代码实现,採用TreeMap的数据结构保存结点的内容。在初始化的时候。把节点的hash和节点地址保存在TreeMap里。client查找时,依据key的hash值去treeMap得到自己应该查询的节点。往下查找比自己hash值大的。假设有则得到结果返回。

假设没有,则回到treeMap的头,取第一个返回结果。
依据key计算出hash,去treeMap查找比key哈希大的那部分,取出第一个值就是结果。假设没有别key哈希大的部分,则取treeMap的第一个值。
这里写图片描写叙述

虚拟结点的算法:
“虚拟节点”的hash计算可以採用相应节点的IP地址加数字后缀的方式。比如假设NODE1的IP地址为192.168.1.100。

引入“虚拟节点”前,计算 cache A 的 hash 值:
Hash(“192.168.1.100”);
引入“虚拟节点”后,计算“虚拟节”点NODE1-1和NODE1-2的hash值:
Hash(“192.168.1.100#1”); // NODE1-1
Hash(“192.168.1.100#2”); // NODE1-2
4.总结。
事实上说白了,一致性哈希(consistent hash)仅仅是负载均衡中的一种路由算法。