架构师第 5 周 - 作业
发布于: 2020 年 07 月 05 日
用你熟悉的编程语言实现一致性 hash 算法。
public class HashVirtualNode {    // 服务器列表10台服务器    private static String[] servers = {"server0", "server1", "server2",            "server3", "server4", "server5", "server6", "server7", "server8","server9"};    // 每个服务器节点对应的虚拟节点个数    private static final int VIRTUAL_NODES = 1;    private static List<String> realNodes = new LinkedList<String>();    private static SortedMap<Integer, String> virtualNodes = new TreeMap<Integer, String>();    static{        for(int i=0; i<servers.length; i++)            realNodes.add(servers[i]);        for(String str : realNodes) {            for(int i=0; i<VIRTUAL_NODES; i++){                String virtualNodeName = str + "_VN" + String.valueOf(i);                int hash = getHash(virtualNodeName);                virtualNodes.put(hash, virtualNodeName);            }        }    }    /**     * 计算Hash值     * @param str     * @return     */    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;    }    /**     * 根据key得到应当路由到的结点     * @param key     * @return     */    private static String getServer(String key) {        int hash = getHash(key);        SortedMap<Integer, String> subMap = virtualNodes.tailMap(hash);        String virtualNode;        if (subMap.isEmpty()) {            Integer i = virtualNodes.firstKey();            virtualNode = virtualNodes.get(i);        } else {            Integer i = subMap.firstKey();            virtualNode = subMap.get(i);        }        if(StringUtils.isNotBlank(virtualNode)) {            return virtualNode.substring(0, virtualNode.indexOf("_"));        }        return null;    }}
编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。
public static void main(String[] args) {        int[] serverNum = new int[10];        for(int i=1; i<=1000000; i++) {            switch (getServer(String.valueOf(i))) {                case "server0" :                    serverNum[0]++;                    break;                case "server1" :                    serverNum[1]++;                    break;                case "server2" :                    serverNum[2]++;                    break;                case "server3" :                    serverNum[0]++;                    break;                case "server4" :                    serverNum[0]++;                    break;                case "server5" :                    serverNum[0]++;                    break;                case "server6" :                    serverNum[0]++;                    break;                case "server7" :                    serverNum[0]++;                    break;                case "server8" :                    serverNum[0]++;                    break;                case "server9" :                    serverNum[0]++;                    break;                default:                    return;            }        }       double result = getStandardDevition(serverNum);       System.out.println("标准方差结果为:" + result);    }    /**     * 根据标准方差计算方式计算     * @param arr     * @return     */    public static double getStandardDevition(int[] arr) {        double sum = 0;        // 平均应是每个服务器存放10万个KV值        double avgValue = 100000;        int number = arr.length;        for (int i = 0; i < number; i++) {            System.out.println("server" + i + "存放KV 数据个数: " + arr[i]);            sum += Math.pow((arr[i] - avgValue), 2);        }        return Math.sqrt((sum / (number - 1)));    }
输出结果为:

 划线
   评论
  复制
发布于: 2020 年 07 月 05 日 阅读数: 39
上山砍柴
  关注 
还未添加个人签名 2018.02.28 加入
还未添加个人简介
 
 
  
  
 
 
 
 
 
 
 
 
 
 
    
评论