写点什么

架构师训练营第 5 周命题作业

用户头像
hifly
关注
发布于: 2020 年 07 月 08 日
架构师训练营第5周命题作业
  1. 用你熟悉的编程语言实现一致性 hash 算法


package algorithm.hash;
import java.util.Collection;import java.util.SortedMap;import java.util.TreeMap;
public class ConsistentHash<T> {
// 虚拟节点的数量 private final int virtualNodeNum;
private final SortedMap<Integer, T> consistenHashCircle = new TreeMap<Integer, T>();
public ConsistentHash(int virtualNodeNum, Collection<T> nodes) { this.virtualNodeNum = virtualNodeNum; for (T node : nodes) { add(node); } }
// 新增一个实际节点 public void add(T node) { for (int i = 0; i < virtualNodeNum; i++) { String nodestr = node.toString() + Math.pow((double) i, (double) 6); int hashcode = nodestr.hashCode(); consistenHashCircle.put(hashcode, node);
} }
// 删除一个实际节点 public void remove(T node) { for (int i = 0; i < virtualNodeNum; i++) { String nodestr = node.toString() + Math.pow((double) i, (double) 6); consistenHashCircle.remove(nodestr.hashCode()); } }
// 获取数据要存放的实际节点 public T get(Object key) { if (consistenHashCircle.isEmpty()) { return null; } int hash = key.hashCode(); if (!consistenHashCircle.containsKey(hash)) { SortedMap<Integer, T> tailMap = consistenHashCircle.tailMap(hash); hash = tailMap.isEmpty() ? consistenHashCircle.firstKey() : tailMap.firstKey(); } return consistenHashCircle.get(hash); }
}
复制代码


  1. 编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性

package algorithm.hash;
import java.util.HashSet;import java.util.Random;import java.util.Set;
public class ConsistentHashTest<T> {
// 求和 static int Sum(int[] data) { int sum = 0; for (int i = 0; i < data.length; i++) sum = sum + data[i]; return sum; }
// 求平均值 static double Mean(int[] data) { int mean = 0; mean = Sum(data) / data.length; return mean; }
// 求总体方差 static double POP_Variance(int[] data) { double variance = 0; for (int i = 0; i < data.length; i++) { variance = variance + (Math.pow((data[i] - Mean(data)), 2)); } variance = variance / data.length; return variance; }
// 求总体标准差 static double POP_STD_dev(int[] data) { double std_dev; std_dev = Math.sqrt(POP_Variance(data)); return std_dev; }
// 求样本方差 static double Sample_Variance(int[] data) { double variance = 0; for (int i = 0; i < data.length; i++) { variance = variance + (Math.pow((data[i] - Mean(data)), 2)); } variance = variance / (data.length - 1); return variance; }
// 求样本标准差 static double Sample_STD_dev(int[] data) { double std_dev; std_dev = Math.sqrt(Sample_Variance(data)); return std_dev; }
public static void main(String[] args) { Set<String> nodes = new HashSet<String>(); int[] countArrays = new int[10]; for (int i = 1; i < 11; i++) { nodes.add("192.168.0." + i); countArrays[i - 1] = 0;
}
ConsistentHash<String> consistentHash = new ConsistentHash<String>(200, nodes);
Random random = new Random(); for (int i = 0; i < 1000000; i++) { String node = consistentHash.get("" + random.nextInt(1000000) + System.currentTimeMillis() % 100); switch (node) { case "192.168.0.1": countArrays[0]++; break; case "192.168.0.2": countArrays[1]++; break; case "192.168.0.3": countArrays[2]++; break; case "192.168.0.4": countArrays[3]++; break; case "192.168.0.5": countArrays[4]++; break; case "192.168.0.6": countArrays[5]++; break; case "192.168.0.7": countArrays[6]++; break; case "192.168.0.8": countArrays[7]++; break; case "192.168.0.9": countArrays[8]++; break; case "192.168.0.10": countArrays[9]++; break; } }
System.out.println("总体标准差为:" + POP_STD_dev(countArrays)); System.out.println("样本标准差为:" + Sample_STD_dev(countArrays)); }
}
复制代码


运行测试程序,5 次测试汇总结果如下


总体标准差为:5798.654309406623样本标准差为:6112.318327225222
总体标准差为:5972.901120895942样本标准差为:6295.99059366797
总体标准差为:5788.0663956108865样本标准差为:6101.157686137207
总体标准差为:5662.06605401244样本标准差为:5968.341664333756
体标准差为:5969.317867227377样本标准差为:6292.21351265903
复制代码


用户头像

hifly

关注

还未添加个人签名 2018.03.08 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第5周命题作业