写点什么

分布式缓存架构作业

用户头像
qihuajun
关注
发布于: 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
用户头像

qihuajun

关注

还未添加个人签名 2009.05.15 加入

还未添加个人简介

评论

发布
暂无评论
分布式缓存架构作业