一致性hash的Java实现_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 一致性hash的Java实现

一致性hash的Java实现

 2018/4/7 12:11:23  men4661273  程序员俱乐部  我要评论(0)
  • 摘要:关于一致性hash的讲解有很多,也不难理解,具体可以翻看其他人写的这个文章【转】http://limitlee.iteye.com/blog/1961385自己动手写了一个java的实现过程,记录一下。packagecom.xjw.consistent.hash;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjava.util.Map.Entry
  • 标签:has 实现 Hash Java

关于一致性hash的讲解有很多,也不难理解,具体可以翻看其他人写的这个文章

【转】http://limitlee.iteye.com/blog/1961385

自己动手写了一个java的实现过程,记录一下。

class="java" name="code">package com.xjw.consistent.hash;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.apache.commons.codec.digest.DigestUtils;

public class ConsistentHash {
	
	private SortedMap<Integer, String> serverNodeMap = null;
	
	private final static int VIRTUAL_NODE_NUMBER = 5;
	
	
	public void getServerNodeWithoutVirtualNode(List<String> servers) {
		serverNodeMap = new TreeMap<>();
		for (String string : servers) {
			serverNodeMap.put(hash(string), string);
		}
	}
	
	public void getServerNodeWithVirtualNode(List<String> servers) {
		serverNodeMap = new TreeMap<>();
		for (String string : servers) {
			for (int i = 0; i < VIRTUAL_NODE_NUMBER; i++) {
				String virtualNodeName = string + ":" + i;
				serverNodeMap.put(hash(virtualNodeName), string);
			}
			
		}
	}
	
	public String getServerName(String data) {
		int dataHash = hash(data);
		SortedMap<Integer, String> subMap = serverNodeMap.tailMap(dataHash);
		int serverHash = 0;
		if (subMap == null || subMap.size() == 0) {
			serverHash = serverNodeMap.firstKey();
		}else {
			serverHash = subMap.firstKey();
		}
		
		String serverName = serverNodeMap.get(serverHash);
		return serverName;
		
	}
	
	
	/**
	 * hash计算,这里使用md5后取hashcode,这个md5需要依赖apache的codec包
	 * @param str
	 * @return
	 */
	public int hash(String str) {
		return DigestUtils.md5Hex(str).hashCode();
	}
	
	public static void main(String[] args) {
		List<String> servers = new ArrayList<>();
		servers.add("192.168.1.1");
		servers.add("192.168.1.2");
		servers.add("192.168.1.3");
		servers.add("192.168.1.4");
		servers.add("192.168.1.5");
		servers.add("192.168.1.6");
		List<String> datas = new ArrayList<>();
		datas.add("河南");
		datas.add("山东");
		datas.add("天津");
		datas.add("北京");
		datas.add("上海");
		datas.add("广州");
		datas.add("乌海");
		datas.add("武汉");
		datas.add("合肥");
		datas.add("长沙");
		ConsistentHash consistentHash = new ConsistentHash();
		System.out.println("没有虚拟节点的情况:");
		consistentHash.getServerNodeWithoutVirtualNode(servers);
		consistentHash.printDataAndServerNode(servers, datas, consistentHash);
		System.out.println("有虚拟节点的情况:");
		consistentHash.getServerNodeWithVirtualNode(servers);
		consistentHash.printDataAndServerNode(servers, datas, consistentHash);
		
		servers.remove(0);
		System.out.println("移除第一个一个节点后:");
		System.out.println("没有虚拟节点的情况:");
		consistentHash.getServerNodeWithoutVirtualNode(servers);
		consistentHash.printDataAndServerNode(servers, datas, consistentHash);
		System.out.println("有虚拟节点的情况:");
		consistentHash.getServerNodeWithVirtualNode(servers);
		consistentHash.printDataAndServerNode(servers, datas, consistentHash);
		
	}

	public void printDataAndServerNode(List<String> servers, List<String> datas,
			ConsistentHash consistentHash) {
		Map<String, String> result = new HashMap<>();
		for (String data : datas) {
			String serverName = consistentHash.getServerName(data);
			if (!result.containsKey(serverName)) {
				result.put(serverName, data);
			}else {
				result.put(serverName, result.get(serverName) + "," + data);
			}
		}
		
		for (Entry<String, String> entry : result.entrySet()) {
			System.out.println(entry.getKey()+":"+entry.getValue());

		}
		
	}

}

?

?输出结果为:

没有虚拟节点的情况:

192.168.1.1:河南,山东,广州

192.168.1.3:天津,合肥,长沙

192.168.1.4:北京,上海,乌海

192.168.1.6:武汉

有虚拟节点的情况:

192.168.1.1:上海

192.168.1.3:河南,天津,广州

192.168.1.2:山东,北京,乌海,合肥

192.168.1.5:武汉

192.168.1.6:长沙

移除第一个一个节点后:

没有虚拟节点的情况:

192.168.1.3:河南,山东,天津,广州,合肥,长沙

192.168.1.4:北京,上海,乌海

192.168.1.6:武汉

有虚拟节点的情况:

192.168.1.3:河南,天津,广州

192.168.1.2:山东,北京,乌海,合肥

192.168.1.5:上海,武汉

192.168.1.6:长沙

发表评论
用户名: 匿名