架构师训练营 week5 课后作业
发布于: 2020 年 11 月 22 日
作业一(2 选 1):
用你熟悉的编程语言实现一致性 hash 算法。
编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
public class ConsistentHashingExample {
// 服务器总数
private static final int SERVERS_NUM = 100;
// 每台服务器需要设置的虚拟节点数
private static final int VIRTUAL_NODES = 10;
// HASH环
private static SortedMap<Integer, String> treeMapHash;
// 待加入 Hash 环的服务器列表
private static ArrayList<String> serverList = new ArrayList<>();
private static void init() {
// 构造服务器数据
for (int i = 0; i < SERVERS_NUM; i++) {
String s = new StringBuilder().append("192.168.0.").append(String.valueOf(i)).toString();
serverList.add(s);
}
// 构建 Hash 环
treeMapHash = buildHash(new TreeMap<Integer, String>());
// 将服务器的虚拟节点添加到 Hash 环中
for (String s : serverList) {
for (int i = 0; i < VIRTUAL_NODES; i++) {
String VNNode = s + "&&VN" + String.valueOf(i);
addServerNode(VNNode);
}
}
}
// 构建 Hash 环
private static SortedMap<Integer, String> buildHash(TreeMap<Integer, String> treeMap) {
treeMapHash = treeMap;
return treeMapHash;
}
private static String[] getIPAddress(int num) {
String[] res = new String[num];
Random random = new Random();
for (int i = 0; i < num; i++) {
res[i] = String.valueOf(random.nextInt(256)) + "." + String.valueOf(random.nextInt(256)) + "."
+ String.valueOf(random.nextInt(256)) + "." + String.valueOf(random.nextInt(256)) + ":"
+ String.valueOf(random.nextInt(9999));
}
return res;
}
private static void addServerNode(String serverNodeName) {
int hash = new GetHashCode().getHashCode(serverNodeName);
treeMapHash.put(hash, serverNodeName);
System.out.println("上线服务器节点:" + serverNodeName);
}
private static void delServerNode(String serverNodeName) {
int hash = new GetHashCode().getHashCode(serverNodeName);
treeMapHash.remove(hash);
System.out.println("下线服务器节点:" + serverNodeName);
}
private static String selectServerNode(String requestURL) {
int hash = new GetHashCode().getHashCode(requestURL);
// 向右寻找第一个 key
Map.Entry<Integer, String> subEntry = ((TreeMap<Integer, String>) treeMapHash).ceilingEntry(hash);
// 设置成一个环,如果超过尾部,则取第一个点
subEntry = subEntry == null ? ((TreeMap<Integer, String>) treeMapHash).firstEntry() : subEntry;
String VNNode = subEntry.getValue();
return VNNode.substring(0, VNNode.indexOf("&&"));
}
public static void main(String[] args) {
init();
// 请求节点
String[] nodes = getIPAddress(100);
// <节点,服务器>
for (int i = 0; i < nodes.length; i++) {
// 选择服务器
String serverIP = selectServerNode(nodes[i]);
System.out.println("请求节点:["+nodes[i] + "]选择的服务器节点是:" + serverIP);
}
}
}
复制代码
划线
评论
复制
发布于: 2020 年 11 月 22 日阅读数: 23
版权声明: 本文为 InfoQ 作者【花果山】的原创文章。
原文链接:【http://xie.infoq.cn/article/c444f74ffa1ff8b215e08bdd6】。未经作者许可,禁止转载。
花果山
关注
还未添加个人签名 2019.05.09 加入
还未添加个人简介
评论