【一】一致性hash算法,基本实现分布平衡。

 1 package org.ehking.quartz.curator;
 2 
 3 import java.util.SortedMap;
 4 import java.util.TreeMap;
 5 
 6 public class ConsistentHashingWithoutVirtualNode {
 7     /**
 8            * 待添加入Hash环的服务器列表
 9           */
10          private static String[] servers = {"192.168.0.0:111", "192.168.0.1:111", "192.168.0.2:111",
11                 "192.168.0.3:111", "192.168.0.4:111"};
12      
13        /**
14       * key表示服务器的hash值,value表示服务器的名称
15          */
16          private static SortedMap<Integer, String> sortedMap = 
17              new TreeMap<Integer, String>();
18         
19      /**
20       * 程序初始化,将所有的服务器放入sortedMap中
21      */
22      static
23   {
24       for (int i = 0; i < servers.length; i++)
25        {
26           int hash = getHash(servers[i]);
27           System.out.println("[" + servers[i] + "]加入集合中, 其Hash值为" + hash);
28            sortedMap.put(hash, servers[i]);
29        }
30         System.out.println();
31     }
32      
33      /**
34       * 使用FNV1_32_HASH算法计算服务器的Hash值,这里不使用重写hashCode的方法,最终效果没区别 
35      */
36      private static int getHash(String str)
37      {
38          final int p = 16777619;
39          int hash = (int)2166136261L;
40          for (int i = 0; i < str.length(); i++)
41         hash = (hash ^ str.charAt(i)) * p;
42         hash += hash << 13;
43        hash ^= hash >> 7;
44        hash += hash << 3;
45       hash ^= hash >> 17;
46         hash += hash << 5;
47          
48         // 如果算出来的值为负数则取其绝对值
49         if (hash < 0)
50             hash = Math.abs(hash);
51          return hash;
52      }
53    
54      /**
55       * 得到应当路由到的结点
56       */
57      private static String getServer(String node)
58      {
59          // 得到带路由的结点的Hash值
60          int hash = getHash(node);
61         // 得到大于该Hash值的所有Map
62          SortedMap<Integer, String> subMap = 
63                  sortedMap.tailMap(hash);
64          // 第一个Key就是顺时针过去离node最近的那个结点
65         Integer i = subMap.firstKey();
66          // 返回对应的服务器名称
67        return subMap.get(i);
68      }
69     
70      public static void main(String[] args)
71     {
72          String[] nodes = {"127.0.0.1:1111", "221.226.0.1:2222", "10.211.0.1:3333"};
73        for (int i = 0; i < nodes.length; i++)
74            System.out.println("[" + nodes[i] + "]的hash值为" + 
75                     getHash(nodes[i]) + ", 被路由到结点[" + getServer(nodes[i]) + "]");
76     }
77 }
View Code

相关文章: