您好,登录后才能下订单哦!
这篇文章给大家介绍一致性哈希算法的java实现是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
今天我们用java来实现一下,一致性哈希算法,重点还是一致性和虚拟节点2个方面。
废话少说,直接上代码:
public class ConsistencyHash {
     private TreeMap<Long, String> nodes = null;
     
     private List<String> shards = new ArrayList<String>();
     
     private int VIRTUAL_NUM = 4;
    
     public void init() {
         shards.add("10.10.0.0-服务器0");
         shards.add("10.10.0.1-服务器1");
         shards.add("10.10.0.2-服务器2");
         shards.add("10.10.0.3-服务器3");
         shards.add("10.10.0.4-服务器4");
        nodes = new TreeMap<Long, String>();
         for (int i = 0; i < shards.size(); i++) {
             String shardInfo = shards.get(i);
             for (int j = 0; j < VIRTUAL_NUM; j++) {
                 byte[] md5Value = computeMd5("SHARD-" + i + "-NODE-" + j);
                 long hashCode = hash(md5Value, j);
                 System.out.println(hashCode);
                 nodes.put(hashCode, shardInfo);
             }
         }
         
         Iterator<Long> iter = nodes.keySet().iterator();
         while(iter.hasNext()){
             Long key = iter.next();
             String obj = (String)nodes.get(key);
             System.out.println(String.valueOf(key) + ":" + obj);
         }
     }
    
     public Object getShardInfo(long hash) {
         Long key = hash;
         SortedMap<Long, String> tailMap = nodes.tailMap(key);
         if (tailMap.isEmpty()) {
             key = nodes.firstKey();
         } else {
             key = tailMap.firstKey();
         }
         return nodes.get(key);
     }
    
     public void printMap() {
         System.out.println(nodes);
     }
    
     public long hash(byte[] digest, int nTime) {
         long rv = ((long) (digest[3 + nTime * 4] & 0xFF) << 24) | ((long) (digest[2 + nTime * 4] & 0xFF) << 16)
                 | ((long) (digest[1 + nTime * 4] & 0xFF) << 8) | (digest[0 + nTime * 4] & 0xFF);
        return rv & 0xffffffffL; /* Truncate to 32-bits */
     }
    /**
      * Get the md5 of the given key. 计算MD5值
      */
     public byte[] computeMd5(String k) {
         MessageDigest md5;
         try {
             md5 = MessageDigest.getInstance("MD5");
         } catch (NoSuchAlgorithmException e) {
             throw new RuntimeException("MD5 not supported", e);
         }
         md5.reset();
         byte[] keyBytes = null;
         try {
             keyBytes = k.getBytes("UTF-8");
         } catch (UnsupportedEncodingException e) {
             throw new RuntimeException("Unknown string :" + k, e);
         }
        md5.update(keyBytes);
         byte[] res = md5.digest();
         return res;
     }
    public static void main(String[] args) {
         Random ran = new Random();
         ConsistencyHash hash = new ConsistencyHash();
         hash.init();
         hash.printMap();
        for (int i = 0; i < 256; i++) {
             int randomVirtualServer = ran.nextInt(hash.VIRTUAL_NUM);
             byte[] md5Value = hash.computeMd5(String.valueOf(i));
             long hashValue = hash.hash(md5Value, randomVirtualServer);
             String serverInfo = (String)hash.getShardInfo(hashValue);
             System.out.println(serverInfo);
         }
     }
 }
环境:假定为5台真实服务器,每台真实服务器对应4个虚拟节点,这样就是20个服务节点。
首先是init()方法,该方法就是把20个服务节点,分布在一个2^32的圆环上。这里分为2步,首先根据形如“ SHARD-2-NODE-3 ”这样的字符串得到一个16个长度的byte数组;之后根据这个byte数组获得2^32范围内的哈希值。
然后假定256个数据对象,我们需要为他们分别找到一个服务节点。
根据一致性的定义,我们需要根据这256个数据对象,分别一个 2^32范围内的哈希值 ,为了方便起见,我们采取和服务节点一致的方法。
之后,在 getShardInfo 方法当中,在圆环内,为他们寻找各自所属的服务节点。
关于一致性哈希算法的java实现是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。