写点什么

第五周 技术选型(一) 作业 「架构师训练营 3 期」

用户头像
feiyun123
关注
发布于: 2020 年 12 月 26 日



作业一(2 选 1):

  1. 用你熟悉的编程语言实现一致性 hash 算法。

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



代码如下:

package com.hyf.test.hash;

import cn.hutool.core.util.HashUtil;
import cn.hutool.core.util.RandomUtil;

import java.util.*;

/**
* @author hyf
* @date 2020/12/26
*/
public class ConsistencyHash {
private final TreeMap<Integer, Node> circle = new TreeMap<>();
private final int ostensibleNum = 150;
public static Map<String, HashMap> nodeCache = new HashMap();

/**
* 增加节点
*
* @param node
*/
public void addNode(Node node) {
for (int i = 0; i < ostensibleNum; i++) {
String name = node.getIp() + "_" + i;
node.setName(name);
int hash = HashUtil.murmur32(name.getBytes());
circle.put(hash, node);
}
}

/**
* 移除节点
*
* @param node
*/
public void removeNode(Node node) {
for (int i = 0; i < ostensibleNum; i++) {
String name = node.getIp() + "_" + i;
int hash = HashUtil.murmur32(name.getBytes());
circle.remove(hash);
}
}

/**
* key指向的下一个节点
*
* @param key
* @return
*/
public Node get(String key) {
if (this.circle.isEmpty()) {
return null;
}
Integer hashCode = key.hashCode();
SortedMap<Integer, Node> sortedMap = this.circle.tailMap(hashCode);
Integer hash = sortedMap.isEmpty() ? this.circle.firstKey() : sortedMap.firstKey();
Node node = this.circle.get(hash);
return node;
}

/**
* 模拟添加储存数据
*
* @param key
* @param value
*/
public void put(String key, String value) {
Node node = this.get(key);
if (node == null) {
return;
}
if (!ConsistencyHash.nodeCache.containsKey(node.getIp())) {
ConsistencyHash.nodeCache.put(node.getIp(), new HashMap());
}
HashMap hashMap = ConsistencyHash.nodeCache.get(node.getIp());
hashMap.put(key, value);
}

/**
* 模拟删除数据
*
* @param key
*/
public void remove(String key) {
Node node = this.get(key);
if (node == null) {
return;
}
if (!ConsistencyHash.nodeCache.containsKey(node.getIp())) {
return;
}
ConsistencyHash.nodeCache.get(node.getIp()).remove(key);
}

public static void main(String[] args) {
String ip_start = "192.168.168.";
ConsistencyHash consistencyHash = new ConsistencyHash();
//添加11个真实节点
for (int i = 0; i < 11; i++) {
Node node = new Node();
int n = i + 1;
node.setIp(ip_start + n);
consistencyHash.addNode(node);
}
//虚拟节点数
System.out.println("circle size:" + consistencyHash.circle.size());
Node node = new Node();
node.setIp(ip_start + 1);
//测试删除一个真实节点
consistencyHash.removeNode(node);
//插入百万个数据
for (int i = 0; i < 1000000; i++) {
String uuidStr = UUID.randomUUID().toString();
consistencyHash.put(uuidStr, uuidStr);
}

Set<Map.Entry<String, HashMap>> entries = ConsistencyHash.nodeCache.entrySet();
Iterator<Map.Entry<String, HashMap>> it = entries.iterator();
int num = 0;
while (it.hasNext()) {
Map.Entry<String, HashMap> next = it.next();
System.out.println(next.getKey() + "--" + next.getValue().size());
num += next.getValue().size();
}
System.out.println("sum:" + num);
System.out.println("circle size:" + consistencyHash.circle.size());

}
}

class Node {
private String ip;
private String 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;
}

}




测试打印结果如下:



用户头像

feiyun123

关注

还未添加个人签名 2019.09.28 加入

还未添加个人简介

评论

发布
暂无评论
第五周 技术选型(一) 作业 「架构师训练营 3 期」