一致性hash演示

看到点关于一致性hash的说明,觉得挺有意思,就想体验一下。

上代码看看,体会一下在一致性hash环境下的cache和获取。

因为是小代码演示,没有很细致,包括hash函数就是用取余操作,但活生生的显示出来一致性hash环境下,增减服务器对hash分布的影响(关于这个演示,要靠手工尝试)。

  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函数,可以推荐哈。

posted on 2013-06-27 22:56  eric_chen  阅读(898)  评论(0编辑  收藏  举报