看到點關於一致性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