分布式缓存架构作业
发布于: 2020 年 07 月 05 日
用你熟悉的编程语言实现一致性 hash 算法。
编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。
代码实现:
package architect.cache;import java.util.*;public class ConsistentHash implements IConsistentHash { /** * 服务器列表 */ private List<String> servers = new ArrayList<String>(); /** * 每个服务器分配的虚拟节点数 */ private int virtualNodesPerServer = 10; /** * 环的最大长度 */ private static final Integer RING_LENGTH = Integer.MAX_VALUE; private TreeMap<Integer, String> serverNodes = new TreeMap<Integer, String>(); public ConsistentHash(int n){ virtualNodesPerServer = n; } public void addServer(String server) { if(server != null && server != "" && !servers.contains(server)){ servers.add(server); initVirtualNodes(); } } public void removeServer(String server) { if(servers.contains(server)){ servers.remove(server); initVirtualNodes(); } } /** * 预设服务器的虚拟节点 * * 虚拟节点的分布采用(环的长度/虚拟节点数)的平均分布的方式 */ private void initVirtualNodes() { serverNodes = new TreeMap<>(); int size = servers.size(); int virtualNodeCount = size * virtualNodesPerServer; int step = RING_LENGTH / virtualNodeCount; int index = 0; int serverindex = 0; while (index <= RING_LENGTH && index >= 0){ String server = servers.get(serverindex%size); serverNodes.put(index, server); serverindex++; index += step; } } /** * 根据key选择服务器 * * @param key * @return */ public String selectServer(Object key) throws Exception { if(serverNodes.isEmpty()){ throw new Exception("There is no available server yes!"); } int index = key.hashCode() < 0? 0-key.hashCode() : key.hashCode(); NavigableMap<Integer, String> tailMap = serverNodes.tailMap(index, true); if(tailMap != null){ return tailMap.get(tailMap.firstKey()); } return serverNodes.get(0); } private static double getStandardDeviation(Collection<Integer> values){ Optional<Integer> sum = values.stream().reduce( (integer, integer2) -> integer+integer2); double avg = sum.get()/values.size(); if(avg == 0){ return 0; } Optional<Double> value = values.stream().map(n -> Math.pow(n - avg, 2)).reduce((n1, n2) -> n1 + n2); if(value.isPresent()){ return Math.sqrt(value.get()/values.size()); } return 0; } public static void main(String[] args) { ConsistentHash hash = new ConsistentHash(200); hash.addServer("server1"); hash.addServer("server2"); hash.addServer("server3"); hash.addServer("server4"); hash.addServer("server5"); hash.addServer("server6"); hash.addServer("server7"); hash.addServer("server8"); hash.addServer("server9"); hash.addServer("server10"); HashMap<String, Integer> records = new HashMap<String, Integer>(); int count = 1000000; try { for (int i = 0; i < count; i++) { UUID uuid = UUID.randomUUID(); String server = hash.selectServer(uuid); int pc = 0; if(records.containsKey(server)){ pc = records.get(server); } records.put(server, pc+1); } } catch (Exception e) { e.printStackTrace(); } System.out.println("keys分布: "+records); System.out.println("keys分布标准差: "+getStandardDeviation(records.values())); }}
划线
评论
复制
发布于: 2020 年 07 月 05 日阅读数: 50
版权声明: 本文为 InfoQ 作者【qihuajun】的原创文章。
原文链接:【http://xie.infoq.cn/article/e7c0815aee29f6cca341ba1b1】。文章转载请联系作者。
qihuajun
关注
还未添加个人签名 2009.05.15 加入
还未添加个人简介
评论