第五周 技术选型(一) 作业 「架构师训练营 3 期」
发布于: 2020 年 12 月 26 日
作业一(2 选 1):
用你熟悉的编程语言实现一致性 hash 算法。
编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。
代码如下:
package com.hyf.test.hash;import cn.hutool.core.util.HashUtil;import cn.hutool.core.util.RandomUtil;import java.util.*;/** * @author hyf * @date 2020/12/26 */public class ConsistencyHash { private final TreeMap<Integer, Node> circle = new TreeMap<>(); private final int ostensibleNum = 150; public static Map<String, HashMap> nodeCache = new HashMap(); /** * 增加节点 * * @param node */ public void addNode(Node node) { for (int i = 0; i < ostensibleNum; i++) { String name = node.getIp() + "_" + i; node.setName(name); int hash = HashUtil.murmur32(name.getBytes()); circle.put(hash, node); } } /** * 移除节点 * * @param node */ public void removeNode(Node node) { for (int i = 0; i < ostensibleNum; i++) { String name = node.getIp() + "_" + i; int hash = HashUtil.murmur32(name.getBytes()); circle.remove(hash); } } /** * key指向的下一个节点 * * @param key * @return */ public Node get(String key) { if (this.circle.isEmpty()) { return null; } Integer hashCode = key.hashCode(); SortedMap<Integer, Node> sortedMap = this.circle.tailMap(hashCode); Integer hash = sortedMap.isEmpty() ? this.circle.firstKey() : sortedMap.firstKey(); Node node = this.circle.get(hash); return node; } /** * 模拟添加储存数据 * * @param key * @param value */ public void put(String key, String value) { Node node = this.get(key); if (node == null) { return; } if (!ConsistencyHash.nodeCache.containsKey(node.getIp())) { ConsistencyHash.nodeCache.put(node.getIp(), new HashMap()); } HashMap hashMap = ConsistencyHash.nodeCache.get(node.getIp()); hashMap.put(key, value); } /** * 模拟删除数据 * * @param key */ public void remove(String key) { Node node = this.get(key); if (node == null) { return; } if (!ConsistencyHash.nodeCache.containsKey(node.getIp())) { return; } ConsistencyHash.nodeCache.get(node.getIp()).remove(key); } public static void main(String[] args) { String ip_start = "192.168.168."; ConsistencyHash consistencyHash = new ConsistencyHash(); //添加11个真实节点 for (int i = 0; i < 11; i++) { Node node = new Node(); int n = i + 1; node.setIp(ip_start + n); consistencyHash.addNode(node); } //虚拟节点数 System.out.println("circle size:" + consistencyHash.circle.size()); Node node = new Node(); node.setIp(ip_start + 1); //测试删除一个真实节点 consistencyHash.removeNode(node); //插入百万个数据 for (int i = 0; i < 1000000; i++) { String uuidStr = UUID.randomUUID().toString(); consistencyHash.put(uuidStr, uuidStr); } Set<Map.Entry<String, HashMap>> entries = ConsistencyHash.nodeCache.entrySet(); Iterator<Map.Entry<String, HashMap>> it = entries.iterator(); int num = 0; while (it.hasNext()) { Map.Entry<String, HashMap> next = it.next(); System.out.println(next.getKey() + "--" + next.getValue().size()); num += next.getValue().size(); } System.out.println("sum:" + num); System.out.println("circle size:" + consistencyHash.circle.size()); }}class Node { private String ip; private String name; public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getName() { return name; } public void setName(String name) { this.name = name; }}
测试打印结果如下:
划线
评论
复制
发布于: 2020 年 12 月 26 日阅读数: 16
feiyun123
关注
还未添加个人签名 2019.09.28 加入
还未添加个人简介
评论