第五周作业

用户头像
Geek_ac4080
关注
发布于: 2020 年 10 月 25 日



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

package week5;

import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

public class ConsistentHash {

private SortedMap<Long, String> serverMap;

/**
* 构造函数初始化服务器hashCode和ip的映射关系
* @param serverList
*/
public ConsistentHash(List<String> serverList){
serverMap = new TreeMap<Long, String>();
for (String server : serverList) {
serverMap.put(getHash(server), server);
}
}

/**
* 获取hashCode
* @param key
* @return
*/
public Long getHash(String key){
// hashCode值为-21 4748 3648~21 4748 3647,保证hash值为0~2^32-1则加上2^31
Long hashCode = Long.valueOf(key.hashCode() + 2147483647 + 1);
return hashCode;
}

/**
* 获取hash环上最近的一个服务器ip
* @param key
* @return
*/
public String getServer(String key){
// 获取请求key的hashCode
long hashCode = getHash(key);
// 获取大于该hashCode的服务器列表
SortedMap<Long, String> subMap = serverMap.tailMap(hashCode);
if (subMap.isEmpty()){
// 如果为空则取hash环的第一个服务器
return serverMap.get(serverMap.firstKey());
}else {
// 不为空则取大于该hashCode的服务器的第一个服务器
return subMap.get(subMap.firstKey());
}
}
}




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

package week5;

import java.util.*;

public class ConsistentHashTest {
public static void main(String[] args){
List<String> serverList = new ArrayList<String>();
// 记录每个服务器接收到的请求个数
Map<String, Integer> serverMap = new HashMap<String, Integer>();
Random random = new Random(1000);
for (int i = 0; i < 10; i++) {
// 使用随机数代替服务器ip
String ip = String.valueOf(random.nextInt(Integer.MAX_VALUE));
serverList.add(ip);
// 初始化为0
serverMap.put(ip, 0);
}
ConsistentHash consistentHash = new ConsistentHash(serverList);
for (int i = 0; i < 1000000; i++) {
// 使用随机数代替请求id
String server = consistentHash.getServer(String.valueOf(random.nextInt(Integer.MAX_VALUE)));
// 对应服务器记录数加1
serverMap.put(server, serverMap.get(server) + 1);
}
System.out.println(serverMap.toString());
}
}




用户头像

Geek_ac4080

关注

还未添加个人签名 2019.05.09 加入

还未添加个人简介

评论

发布
暂无评论
第五周作业