看到点关于一致性hash的说明,以为挺有意思,就想体验一下。java
上代码看看,体会一下在一致性hash环境下的cache和获取。服务器
由于是小代码演示,没有很细致,包括hash函数就是用取余操做,但活生生的显示出来一致性hash环境下,增减服务器对hash分布的影响(关于这个演示,要靠手工尝试)。ide
1 package com.test.algorithms; 2 3 import java.util.Arrays; 4 import java.util.HashSet; 5 import java.util.Set; 6 7 8 public class ConsistentHash { 9 10 private static final int CYCLE_SIZE = 128; 11 12 public static void main(String[] args){ 13 Machine[] machines = new Machine[]{//new Machine("cache-server-1", "192.168.10.10"), 14 new Machine("cache-server-2", "192.168.10.11"), 15 new Machine("cache-server-3", "192.168.10.12"), 16 new Machine("cache-server-4", "192.168.10.13") 17 }; 18 19 for(Machine m : machines){ 20 m.setHashOrder(hash(m.hashCode())); 21 } 22 Arrays.sort(machines); 23 24 for(int j=1; j<10000; j+=17){ 25 String cacheThing = "cache"+j; 26 int hash = hash(cacheThing.hashCode()); 27 if(hash < 0 ){ 28 hash = -1 * hash; 29 } 30 // System.out.println(cacheThing+" == "+hash+" == "+cacheThing.hashCode()); 31 for(int i=0, size = machines.length;i<size;i++){ 32 if(hash <= machines[i].getHashOrder()){ 33 machines[i].addToCache(cacheThing); 34 break; 35 } else if(i == size-1){ 36 machines[0].addToCache(cacheThing); 37 break; 38 } 39 } 40 } 41 42 for(Machine m : machines){ 43 System.out.println(m); 44 } 45 } 46 47 public static int hash(int input){ 48 return input % CYCLE_SIZE; 49 } 50 51 public static class Machine implements Comparable<Machine>{ 52 private String ip; 53 private String name; 54 private int hashOrder; 55 56 private Set<String> cache = new HashSet<String>(); 57 58 public Machine(String name, String ip){ 59 this.name = name; 60 this.ip = ip; 61 } 62 63 public void setHashOrder(int hashOrder){ 64 this.hashOrder = hashOrder; 65 } 66 67 public void addToCache(String thing){ 68 this.cache.add(thing); 69 } 70 71 public Set<String> getCache(){ 72 return this.cache; 73 } 74 75 @Override 76 public int compareTo(Machine o) { 77 return this.hashOrder - o.hashOrder; 78 } 79 80 public int getHashOrder(){ 81 return this.hashOrder; 82 } 83 84 @Override 85 public int hashCode(){ 86 int rs = 17; 87 rs = 31*rs + ip.hashCode(); 88 rs = 31*rs + name.hashCode(); 89 return rs; 90 } 91 92 @Override 93 public String toString() { 94 return "Machine{" + 95 "ip='" + ip + '\'' + 96 ", name='" + name + '\'' + 97 ", hashOrder=" + hashOrder + 98 ", cache size=" + this.cache.size()+ 99 // ", cache=" + cache + 100 '}'; 101 } 102 } 103 104 }
运行以后,能够看到各个machine里面有多少个cache值,也就是看看分布状况,若是分布不理想,能够经过调整cycle_size来影响。函数
我测试了128,256,512,1024,发现128最均匀。其实这个东西的关键就是hash函数。测试
有好的hash函数,能够推荐哈。this