架构师训练营 - 第五周作业
发布于: 2020 年 07 月 08 日
作业一:
用你熟悉的编程语言实现一致性 hash 算法。
编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。
public class HashFunction {
public Integer hash(String key) {
final int p = 16777619;
int hash = (int)2166136261L;
for (int i = 0; i < key.length(); i++)
hash = (hash ^ key.charAt(i)) * p;
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
// 如果算出来的值为负数则取其绝对值
if (hash < 0)
hash = Math.abs(hash);
return hash;
}
}
public class Node {
private String ip;
private String name;
public Node(String ip, String name) {
this.ip = ip;
this.name = 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;
}
}
import java.util.Collection;
import java.util.SortedMap;
import java.util.TreeMap;
public class ConsistentHash {
private final HashFunction hashFunction;
private final int numberOfReplicas;
private final SortedMap<Integer, Node> circle = new TreeMap<>();
public ConsistentHash(HashFunction hashFunction, int numberOfReplicas, Collection<Node> nodes) {
this.hashFunction = hashFunction;
this.numberOfReplicas = numberOfReplicas;
for (Node node : nodes) {
add(node);
}
}
public void add(Node node) {
for (int i = 0; i < this.numberOfReplicas; i++) {
circle.put(this.hashFunction.hash(node.getIp() + i), node);
}
}
public void remove(Node node) {
for (int i = 0; i < this.numberOfReplicas; i++) {
circle.remove(this.hashFunction.hash(node.getIp() + i));
}
}
public Node get(String key) {
if (circle.isEmpty()) {
return null;
}
Integer hash = hashFunction.hash(key);
if (!circle.containsKey(hash)) {
SortedMap<Integer, Node> tailMap = circle.tailMap(hash);
hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
}
return circle.get(hash);
}
}
import java.util.*;
public class Test {
private static final String IP_PREFIX = "192.168.1.";
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
HashFunction hashFunction = new HashFunction();
List<Node> realNodes = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
map.put(IP_PREFIX + i, 0);
Node node = new Node(IP_PREFIX + i, "node" + i);
realNodes.add(node);
}
ConsistentHash consistentHash = new ConsistentHash(hashFunction,100,realNodes);
for (int i = 0; i < 1000000; i++) {
String data = UUID.randomUUID().toString() + i;
Node node = consistentHash.get(data);
map.put(node.getIp(), map.get(node.getIp()) + 1);
}
for (int i = 1; i <= 10; i++) {
System.out.println(IP_PREFIX + i + "节点记录条数:" + map.get("192.168.1." + i));
}
}
}
复制代码
划线
评论
复制
发布于: 2020 年 07 月 08 日阅读数: 51
版权声明: 本文为 InfoQ 作者【teslə】的原创文章。
原文链接:【http://xie.infoq.cn/article/317f9baa7881da865d27e14fb】。未经作者许可,禁止转载。
teslə
关注
还未添加个人签名 2018.08.09 加入
还未添加个人简介
评论