一致性hash算法

一致性hash算法Java demo 

package com.wang.hash;


import java.util.LinkedList;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 一致性hash算法
 */

public class ConsistentHashingWithVirtualNode {

    // 服务器地址
    private static String[] serverNode = {"192.168.0.0:111", "192.167.0.0:111", "192.166.0.0:111", "192.165.0.0:111", "192.158.0.0:111", "192.148.0.0:111"};


    // 虚拟节点数
    private static final int VIRTUAL_NODE = 100;

    // 虚拟节点map
    private static SortedMap<Integer, String> virtualNodeMap = new TreeMap<>();

    // 真实节点链表
    private static LinkedList<String> realServerNodeList = new LinkedList<>();


    /**
     * 创建虚拟节点
     */
    static {
        for (int i = 0; i < serverNode.length; i++) {
            realServerNodeList.add(serverNode[i]);
        }
        for (String realNode : realServerNodeList) {
            for (int j = 0; j < VIRTUAL_NODE; j++) {
                String nodeName = realNode + "&&" + String.valueOf(j);
                Integer hash = getHash(nodeName);
                virtualNodeMap.put(hash, realNode + "&&VN" + j);
                System.out.println("节点是:【" + nodeName + "】加入到虚拟节点节点集合中" + "hash值是:" + hash);
            }
            System.out.println();
        }


    }


    /**
     * 使用FNV1_32_HASH算法计算服务器的Hash值,这里不使用重写hashCode的方法,最终效果没区别
     */
    private static int getHash(String str) {
        final int p = 16777619;
        int hash = (int) 2166136261L;
        for (int i = 0; i < str.length(); i++) {
            hash = (hash ^ str.charAt(i)) * p;
        }
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;

        // 如果算出来的值为负数则取其绝对值
        if (hash < 0) {
            hash = Math.abs(hash);
        }
        return hash;
    }

    /**
     * @param node
     * @return
     */
    public static String getServer(String node) {

        // 计算node 的hash值
        Integer hash = getHash(node);
        // 获取比它hash值大的node集合
        SortedMap<Integer, String> minVirtualNodeMap = virtualNodeMap.tailMap(hash);
        // 获取最小的node
        Integer nodeKey = minVirtualNodeMap.firstKey();
        // 获取虚拟的node节点
        String virtualNode = virtualNodeMap.get(nodeKey);
        return virtualNode.substring(0, virtualNode.lastIndexOf("&&"));
    }


    public static void main(String[] args) {

        for (int i = 0; i < serverNode.length; i++) {
            System.out.println("节点是【" + serverNode[i] + "】存储在【" + getServer(serverNode[i]) + "】节点上");
        }

    }


}
输出:

节点是:【192.168.0.0:111&&0】加入到虚拟节点节点集合中hash值是:1675293881
节点是:【192.168.0.0:111&&1】加入到虚拟节点节点集合中hash值是:589251333
节点是:【192.168.0.0:111&&2】加入到虚拟节点节点集合中hash值是:1714252943
节点是:【192.168.0.0:111&&3】加入到虚拟节点节点集合中hash值是:506543973
节点是:【192.168.0.0:111&&4】加入到虚拟节点节点集合中hash值是:1830535493
节点是:【192.168.0.0:111&&5】加入到虚拟节点节点集合中hash值是:759932604
节点是:【192.168.0.0:111&&6】加入到虚拟节点节点集合中hash值是:1682530966
节点是:【192.168.0.0:111&&7】加入到虚拟节点节点集合中hash值是:1657566804
节点是:【192.168.0.0:111&&8】加入到虚拟节点节点集合中hash值是:1428964732
节点是:【192.168.0.0:111&&9】加入到虚拟节点节点集合中hash值是:145596275

节点是:【192.167.0.0:111&&0】加入到虚拟节点节点集合中hash值是:139440351
节点是:【192.167.0.0:111&&1】加入到虚拟节点节点集合中hash值是:544440280
节点是:【192.167.0.0:111&&2】加入到虚拟节点节点集合中hash值是:361440290
节点是:【192.167.0.0:111&&3】加入到虚拟节点节点集合中hash值是:73550959
节点是:【192.167.0.0:111&&4】加入到虚拟节点节点集合中hash值是:368195106
节点是:【192.167.0.0:111&&5】加入到虚拟节点节点集合中hash值是:612630783
节点是:【192.167.0.0:111&&6】加入到虚拟节点节点集合中hash值是:30366838
节点是:【192.167.0.0:111&&7】加入到虚拟节点节点集合中hash值是:261843626
节点是:【192.167.0.0:111&&8】加入到虚拟节点节点集合中hash值是:929016166
节点是:【192.167.0.0:111&&9】加入到虚拟节点节点集合中hash值是:682057230

节点是:【192.166.0.0:111&&0】加入到虚拟节点节点集合中hash值是:755314198
节点是:【192.166.0.0:111&&1】加入到虚拟节点节点集合中hash值是:494606552
节点是:【192.166.0.0:111&&2】加入到虚拟节点节点集合中hash值是:1238666724
节点是:【192.166.0.0:111&&3】加入到虚拟节点节点集合中hash值是:1493512675
节点是:【192.166.0.0:111&&4】加入到虚拟节点节点集合中hash值是:105358628
节点是:【192.166.0.0:111&&5】加入到虚拟节点节点集合中hash值是:969326055
节点是:【192.166.0.0:111&&6】加入到虚拟节点节点集合中hash值是:804741711
节点是:【192.166.0.0:111&&7】加入到虚拟节点节点集合中hash值是:758329520
节点是:【192.166.0.0:111&&8】加入到虚拟节点节点集合中hash值是:402804487
节点是:【192.166.0.0:111&&9】加入到虚拟节点节点集合中hash值是:578927400

节点是:【192.165.0.0:111&&0】加入到虚拟节点节点集合中hash值是:1673788001
节点是:【192.165.0.0:111&&1】加入到虚拟节点节点集合中hash值是:1835552614
节点是:【192.165.0.0:111&&2】加入到虚拟节点节点集合中hash值是:1990694038
节点是:【192.165.0.0:111&&3】加入到虚拟节点节点集合中hash值是:1310987770
节点是:【192.165.0.0:111&&4】加入到虚拟节点节点集合中hash值是:2019534440
节点是:【192.165.0.0:111&&5】加入到虚拟节点节点集合中hash值是:1200390317
节点是:【192.165.0.0:111&&6】加入到虚拟节点节点集合中hash值是:984938106
节点是:【192.165.0.0:111&&7】加入到虚拟节点节点集合中hash值是:1957193416
节点是:【192.165.0.0:111&&8】加入到虚拟节点节点集合中hash值是:699987518
节点是:【192.165.0.0:111&&9】加入到虚拟节点节点集合中hash值是:2112580768

节点是:【192.158.0.0:111&&0】加入到虚拟节点节点集合中hash值是:821236798
节点是:【192.158.0.0:111&&1】加入到虚拟节点节点集合中hash值是:1827208141
节点是:【192.158.0.0:111&&2】加入到虚拟节点节点集合中hash值是:44693840
节点是:【192.158.0.0:111&&3】加入到虚拟节点节点集合中hash值是:567385565
节点是:【192.158.0.0:111&&4】加入到虚拟节点节点集合中hash值是:296326993
节点是:【192.158.0.0:111&&5】加入到虚拟节点节点集合中hash值是:570379445
节点是:【192.158.0.0:111&&6】加入到虚拟节点节点集合中hash值是:343443391
节点是:【192.158.0.0:111&&7】加入到虚拟节点节点集合中hash值是:58380255
节点是:【192.158.0.0:111&&8】加入到虚拟节点节点集合中hash值是:1538393729
节点是:【192.158.0.0:111&&9】加入到虚拟节点节点集合中hash值是:1850414955

节点是:【192.148.0.0:111&&0】加入到虚拟节点节点集合中hash值是:222531453
节点是:【192.148.0.0:111&&1】加入到虚拟节点节点集合中hash值是:1398803220
节点是:【192.148.0.0:111&&2】加入到虚拟节点节点集合中hash值是:1805765854
节点是:【192.148.0.0:111&&3】加入到虚拟节点节点集合中hash值是:1419686318
节点是:【192.148.0.0:111&&4】加入到虚拟节点节点集合中hash值是:1583766768
节点是:【192.148.0.0:111&&5】加入到虚拟节点节点集合中hash值是:334794917
节点是:【192.148.0.0:111&&6】加入到虚拟节点节点集合中hash值是:54764593
节点是:【192.148.0.0:111&&7】加入到虚拟节点节点集合中hash值是:1974928667
节点是:【192.148.0.0:111&&8】加入到虚拟节点节点集合中hash值是:558831114
节点是:【192.148.0.0:111&&9】加入到虚拟节点节点集合中hash值是:1946349852

节点是【192.168.0.0:111】存储在【192.166.0.0:111】节点上
节点是【192.167.0.0:111】存储在【192.148.0.0:111】节点上
节点是【192.166.0.0:111】存储在【192.165.0.0:111】节点上
节点是【192.165.0.0:111】存储在【192.158.0.0:111】节点上
节点是【192.158.0.0:111】存储在【192.148.0.0:111】节点上
节点是【192.148.0.0:111】存储在【192.167.0.0:111】节点上

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值