写点什么

架构师训练营 1 期 - 第五周作业 (vaik)

用户头像
行之
关注
发布于: 2020 年 10 月 25 日
架构师训练营 1 期 - 第五周作业(vaik)
  1. 用你熟悉的编程语言实现一致性 hash 算法。


import java.util.*;
//基于虚拟节点的一致性哈希算法public class DistributedConsistentHashingByVirtualNode { //缓存服务器虚拟节点映射列表 private SortedMap<Integer,String> virtualCacheServerKeyList =new TreeMap<>();
//每台缓存服务器映射的虚拟节点数量,默认200 private int cacheServerMappingNumber = 200;
//构建类时提供可设置每台缓存服务器映射的虚拟节点数量 public DistributedConsistentHashingByVirtualNode(int cacheServerMappingNumber) { this.cacheServerMappingNumber = cacheServerMappingNumber; }
//添加缓存服务器 public void AddCacheServer(String serverIp){ for(int i=0;i<cacheServerMappingNumber;i++){ String nodeKey = i*10000+"_"+serverIp+"_"+i*10000; int hashCode = nodeKey.hashCode(); virtualCacheServerKeyList.put(hashCode,serverIp); } }
//删除缓存服务器 public void RemoveCacheServer(String serverIp){ for(int i=0;i<cacheServerMappingNumber;i++){ String nodeKey = i*10000+"_"+serverIp+"_"+i*10000; int hashCode = nodeKey.hashCode(); virtualCacheServerKeyList.remove(hashCode); } }
//根据缓存Key查找缓存所在的缓存服务器IP public String getCacheServerIpByKey(String key){ int hashCode = key.hashCode(); String ip = ""; Iterator<Map.Entry<Integer,String>> entries = virtualCacheServerKeyList.entrySet().iterator(); while(entries.hasNext()){ Map.Entry<Integer, String> entry = entries.next(); int virtualCacheServerKey = entry.getKey(); ip = entry.getValue(); //判断顺时针与hashCode最接近的缓存服务器节点 if(hashCode<=virtualCacheServerKey){ break; } } return ip; }
//打印虚拟结点分布情况 public void printAllVirtualCacheServerKey(){ Iterator<Map.Entry<Integer,String>> entries = virtualCacheServerKeyList.entrySet().iterator(); while(entries.hasNext()){ Map.Entry<Integer, String> entry = entries.next(); int virtualCacheServerKey = entry.getKey(); String ip = entry.getValue(); System.out.println("virtualCacheServerKey:"+virtualCacheServerKey+" ip:"+ip); } }}
复制代码


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

测试结果



import java.util.HashMap;import java.util.Random;
public class TestDistributedConsistentHashingByVirtualNode { public static void main(String[] args){ DistributedConsistentHashingByVirtualNode nodeServer = new DistributedConsistentHashingByVirtualNode(100);
String nodeServerIp1 = "192.168.1.1"; String nodeServerIp2 = "192.168.1.2"; String nodeServerIp3 = "192.168.1.3"; String nodeServerIp4 = "192.168.1.4"; String nodeServerIp5 = "192.168.1.5"; String nodeServerIp6 = "192.168.1.6"; String nodeServerIp7 = "192.168.1.7"; String nodeServerIp8 = "192.168.1.8"; String nodeServerIp9 = "192.168.1.9"; String nodeServerIp10 = "192.168.1.10";
nodeServer.AddCacheServer(nodeServerIp1); nodeServer.AddCacheServer(nodeServerIp2); nodeServer.AddCacheServer(nodeServerIp3); nodeServer.AddCacheServer(nodeServerIp4); nodeServer.AddCacheServer(nodeServerIp5); nodeServer.AddCacheServer(nodeServerIp6); nodeServer.AddCacheServer(nodeServerIp7); nodeServer.AddCacheServer(nodeServerIp8); nodeServer.AddCacheServer(nodeServerIp9); nodeServer.AddCacheServer(nodeServerIp10);
//nodeServer.printAllVirtualCacheServerKey(); HashMap<String,Integer> result = new HashMap<>();
//测试100万随机Key(3到100位长度的Key)在 10个服务器上的分布比例 for (int i=0 ; i<1000000; i++){ Random random=new Random(); int number=random.nextInt(98)+3; String key = getRandomString(number); String nodeServerIp = nodeServer.getCacheServerIpByKey(key); if(result.containsKey(nodeServerIp)){ result.put(nodeServerIp,result.get(nodeServerIp)+1); }else{ result.put(nodeServerIp,1); } }
for (String key: result.keySet()) { int num = result.get(key); double rate = (double) num/1000000; String rateStr = String.format("%.4f",rate*100); System.out.println("ServerIP:"+key+" Key数量:"+num + " 占比:"+rateStr+"% "); } }
//取固定位数的随机字符串 public static String getRandomString(int length){ String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Random random=new Random(); StringBuffer sb=new StringBuffer(); for(int i=0;i<length;i++){ int number=random.nextInt(62); sb.append(str.charAt(number)); } return sb.toString(); }}
复制代码


用户头像

行之

关注

还未添加个人签名 2018.09.18 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 1 期 - 第五周作业(vaik)