【一】一致性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 }