架构师训练营第五周作业 - 命题作业
环上的初始化节点数量一个亿,windows 电脑,2^32-1 超限了没办法
节点: 192.168.1.107 数据量: 97401
节点: 192.168.1.108 数据量: 108681
节点: 192.168.1.109 数据量: 119137
节点: 192.168.1.103 数据量: 91535
节点: 192.168.1.104 数据量: 105282
节点: 192.168.1.105 数据量: 101553
节点: 192.168.1.106 数据量: 89822
节点: 192.168.1.110 数据量: 97040
节点: 192.168.1.101 数据量: 106017
节点: 192.168.1.102 数据量: 83532
标准差:9849.159791576132
package com.example.demo;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class KefuClientApplicationTests {
@Test
void contextLoads() {
HashCycle.addNodes("192.168.1.101");
HashCycle.addNodes("192.168.1.102");
HashCycle.addNodes("192.168.1.103");
HashCycle.addNodes("192.168.1.104");
HashCycle.addNodes("192.168.1.105");
HashCycle.addNodes("192.168.1.106");
HashCycle.addNodes("192.168.1.107");
HashCycle.addNodes("192.168.1.108");
HashCycle.addNodes("192.168.1.109");
HashCycle.addNodes("192.168.1.110");
for(int i=0;i<1000000;i++) {
String testStr=UUID.randomUUID().toString();
HashCycle.addValue(testStr, testStr);
}
HashCycle.printStatistics();
}
}
package com.example.demo;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class HashCycle{
private static final int initial_Capacity=100000000;
//使用 string 数组构建 hash 环,方便进行随机访问
private static final String[] cycle=new String[initial_Capacity];
//模拟集群节点
private static final Map<String,Map<String,Object>> nodes=new HashMap<String,Map<String,Object>>();
//读写锁
private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
//随机数生成器
private static final Random random = new Random();
/**
* 添加集群节点
*/
public static void addNodes(String ip) {
readWriteLock.writeLock().lock();
nodes.put(ip, new HashMap<String,Object>());
for(int i=0;i<150;i++) {
int num=random.nextInt(initial_Capacity);
while(cycle[num]!=null) {
num=random.nextInt(initial_Capacity);
}
cycle[num]= ip;
}
readWriteLock.writeLock().unlock();
}
/**
* 插入数据
* @param key
* @param value
*/
public static void addValue(String key ,Object value) {
if(nodes.size()==0) {
throw new RuntimeException("未找到集群节点");
}
readWriteLock.writeLock().lock();
int hash=((initial_Capacity-1)&key.hashCode());
System.out.print("初始 hash:"+hash);
int i=0;
while(cycle[hash]==null) {
hash++;
i++;
if(hash==initial_Capacity) {
hash=0;
}
}
System.out.print(" 查找次数:"+i);
System.out.print(" 节点:"+cycle[hash]);
System.out.println();
nodes.get(cycle[hash]).put(key, value);
readWriteLock.writeLock().unlock();
}
/**
* 获取数据
* @param key
* @return
*/
public static Object getValue(String key) {
if(nodes.size()==0) {
throw new RuntimeException("未找到集群节点");
}
readWriteLock.readLock().lock();
int hash=(initial_Capacity&key.hashCode());
while(cycle[hash]==null) {
hash++;
}
Object value=nodes.get(cycle[hash]).get(key);
readWriteLock.readLock().unlock();
return value;
}
/**
* 打印统计信息
*/
public static void printStatistics() {
Iterator<Map.Entry<String,Map<String,Object>>> it=nodes.entrySet().iterator();
int[] nums=new int[nodes.entrySet().size()];
int i=0;
while (it.hasNext()) {
Map.Entry<String,Map<String,Object>> entry = it.next();
System.out.println("节点: " + entry.getKey() + " 数据量: " + entry.getValue().size());
nums[i]=entry.getValue().size();
i++;
}
System.out.println("标准差:"+standardDiviation(nums));
}
//标准差σ=sqrt(s^2)
public static double standardDiviation(int[] x) {
int m=x.length;
double sum=0;
for(int i=0;i<m;i++){//求和
sum+=x[i];
}
double dAve=sum/m;//求平均值
double dVar=0;
for(int i=0;i<m;i++){//求方差
dVar+=(x[i]-dAve)*(x[i]-dAve);
}
return Math.sqrt(dVar/m);
}
}
评论