博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一致性哈希算法的java实现
阅读量:7076 次
发布时间:2019-06-28

本文共 2745 字,大约阅读时间需要 9 分钟。

hot3.png

之前的文章当中,我们学习了一致性哈希算发的原理。今天我们用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 方法当中,在圆环内,为他们寻找各自所属的服务节点。

转载于:https://my.oschina.net/dongtianxi/blog/707093

你可能感兴趣的文章
我是一个线程(修订版) 转
查看>>
numpy二分查找
查看>>
DevExpress第三方控件使用实例之ASPxPopupControl弹出子窗体
查看>>
【视频】ASP.NET Core MVC 2.* 入门
查看>>
有关java中static关键的重写问题
查看>>
【Android】使用SearchView时软键盘不支持actionSearch的问题
查看>>
url请求返回结果测试工具(CURL)
查看>>
虚拟机安装教程
查看>>
java对文件的检索
查看>>
Marquee滚动字幕设置(转)
查看>>
linux系统下调度数据库类型资源库中的kettle job
查看>>
8UFTP
查看>>
VC 2005 解决方案的目录结构设置和管理
查看>>
吾爱论坛浏览器分享
查看>>
java内存模型优化建议
查看>>
解决Ubuntu Kylin 1610安装ANSYS17.2的NVIDIA显卡驱动问题
查看>>
Linux下如何修改Apache根目录
查看>>
JAVA入门[2]-安装Maven
查看>>
什么是回调函数
查看>>
HDU 2588 GCD &amp;&amp; GCD问题总结
查看>>