一致性hash算法

简介

先构造一个长度为2^32的整数环(这个环被称为一致性Hash环),根据节点名称的Hash值(其分布为[0, 2^32 - 1])将服务器节点放置在这个Hash环上,然后根据数据的Key值计算得到其Hash值(其分布也为[0, 2^32 - 1]),接着在Hash环上顺时针查找距离这个Key值的Hash值最近的服务器节点,完成Key到服务器的映射查找。

FNV1_32_HASH

分布相对均匀、效率中等

private static int getHash(String str)
    {
          final int p = 16777619;
          int hash = (int)2166136261L;
          for (int i = 0; i  < str.length();i ++)
               hash = (hash ^ str.charAt(i)) * p;
          hash += hash ;
          hash ^= hash >> 7;
          hash += hash ;
          hash ^= hash >> 17;
          hash += hash ;
    if (hash ) {
       hash = Math.abs(hash);
    }
    return hash;
  }

实现

为了保证即使增删节点也能均匀分布,增加虚拟节点的概念,虚拟节点需要映射到真实节点上
一种实现方式是:比如真实节点为192.168.1.1:9527,配置3个虚拟节点,那么需要向hash环添加的节点为

192.168.1.1:9527#1
192.168.1.1:9527#2
192.168.1.1:9527#3

数据结构存储使用TreeMap,红黑树实现,查询效率高,代码如下:

private static String getServer(String node) {
     int hash = getHash(node);
     # >= hash
     int firstKey = sortedMap.tailMap(hash).firstKey();
     String vNode = subMap.get(firstKey);
     return vNode.subString(0,  vNode.indexOf("#"));
  }

你可能感兴趣的:(一致性hash算法)