架构师训练营 第五周 【作业】
发布于: 2020 年 07 月 08 日
作业一:
- 用你熟悉的编程语言实现一致性 hash 算法。 
- 编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。 
代码实现如下:
/**服务器实体类**/class ServerEntity {	String ip;//服务器地址	List<String> data = new ArrayList<>();//数据	public ServerEntity(String ip) {		this.ip = ip;	}}public class ConsensusAlg {	/**		* 使用FNV1_32_HASH算法计算服务器的Hash值	*/	public static int getHash(String str) {		final int p = 16777619;		int hash = (int) 2166136261L;		for (int i = 0; i < str.length(); i++)		hash = (hash ^ str.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 static String getRandomString(int stringLength) {		String string = "abcdefghijklmnopqrstuvwxyz0123456789";		StringBuffer sb = new StringBuffer();		for (int i = 0; i < stringLength; i++) {			int index = (int) Math.floor(Math.random() * string.length());			sb.append(string.charAt(index));		}		return sb.toString();	}  	/**	 * 一致性hash测试方法	 */  public static void mainTest() {		// 创建服务器集群		ServerEntity[] servers = new ServerEntity[] { 				new ServerEntity("192.168.0.1"), 				new ServerEntity("192.168.0.2"),				new ServerEntity("192.168.0.3"), 				new ServerEntity("192.168.0.4"), 				new ServerEntity("192.168.0.5"),				new ServerEntity("192.168.0.6"), 				new ServerEntity("192.168.0.7"), 				new ServerEntity("192.168.0.8"),				new ServerEntity("192.168.0.9"), 				new ServerEntity("192.168.0.10") 		};		int virtualCount = 150;// 每台服务器的虚拟节点数量		int dataNum = 100 * 10000;// 测试数据量    System.out.println("数据量为"+dataNum+"。服务器数量:"+servers.length+"。单个服务器虚拟节点数为:"+virtualCount);		// 创建一致性hash节点环		TreeMap<Integer, ServerEntity> tr = new TreeMap<>();		for (ServerEntity se : servers) {			tr.put(getHash(se.ip), se);			for (int i = 1; i <= virtualCount; i++) {				tr.put(getHash(se.ip + "#" + i), se);			}		}		// 放入100万数据		Entry<Integer, ServerEntity> tempEntry;//临时变量,用于获取对应的服务器节点		String dataTemp;		for (int i = 0; i < dataNum; i++) {			dataTemp = getRandomString(20);//生成随机字符串			tempEntry = tr.ceilingEntry(getHash(dataTemp));			if (tempEntry == null)				tempEntry = tr.firstEntry();			tempEntry.getValue().data.add(dataTemp);		}		// 分别显示每个服务器的数据量		for (ServerEntity se : servers) {			System.out.println(se.ip + "--->" + se.data.size());		}		// 计算方差		long avg = dataNum / servers.length;		long variance = 0;		for (ServerEntity se : servers) {			variance += (se.data.size() - avg) * (se.data.size() - avg);		}		System.out.println("方差为:" + variance);		// 计算标准差		double standardDeviation = Math.sqrt(variance / servers.length);		System.out.println("标准差为:" + standardDeviation);  }  }运行 mainTest() 方法即可,结果如下:
数据量为1000000。服务器数量:10。单个服务器虚拟节点数为:150192.168.0.1--->105216192.168.0.2--->103090192.168.0.3--->95222192.168.0.4--->96683192.168.0.5--->88238192.168.0.6--->87705192.168.0.7--->109047192.168.0.8--->103438192.168.0.9--->102266192.168.0.10--->109095方差为:541620032标准差为:7359.48388136016
 划线
   评论
  复制
发布于: 2020 年 07 月 08 日 阅读数: 33
 
 小K
  关注 
还未添加个人签名 2019.11.08 加入
还未添加个人简介
 
 
  
  
 
 
 
  
  
  
  
  
  
  
  
    
评论