public interface ServerRouter {
ServerInfo getServer(String key);
}
public class ConsistencyHashServerRouter implements ServerRouter {
private final Map<Integer, ServerInfo> nodeMap = new TreeMap<>();
private final static int DEFAULT_VIRTUAL_NODE = 20;
private int virtualNode ;
public ConsistencyHashServerRouter(List<ServerInfo> servers,int virtualNode) {
this.virtualNode = virtualNode;
init(servers);
}
private void init(List<ServerInfo> servers) {
for(ServerInfo server : servers) {
for(int i = 0 ; i < virtualNode ; i++) {
nodeMap.put(getHash(getVirtualNodeName(server,i)),server);
}
}
}
private String getVirtualNodeName(ServerInfo serverInfo,int index) {
return serverInfo.getHost() + "&VN" + index;
}
private 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 ConsistencyHashServerRouter(List<ServerInfo> servers) {
this(servers,DEFAULT_VIRTUAL_NODE);
}
@Override
public ServerInfo getServer(String key) {
int keyHash = getHash(key);
ServerInfo defaultNode = null;
for(Iterator<Entry<Integer,ServerInfo>> iterator = nodeMap.entrySet().iterator() ; iterator.hasNext() ;) {
Entry<Integer, ServerInfo> current = iterator.next();
if(defaultNode == null) {
defaultNode = current.getValue();
}
if(keyHash < current.getKey()) {
return current.getValue();
}
}
return defaultNode;
}
}
public class Main {
private static final int DATA_NUMBER = 1000000;
private static Map<ServerInfo, Integer> nodeDataMap = new HashMap<ServerInfo, Integer>();
public static void main(String[] args) {
fullData();
/ 打印结果
printResult();
}
private static void printResult() {
nodeDataMap.forEach(new BiConsumer<ServerInfo, Integer>() {
@Override
public void accept(ServerInfo t, Integer u) {
System.out.println("Server : " + t + " total : " + u);
}
});
}
private static void fullData() {
List<ServerInfo> servers = new ArrayList<ServerInfo>();
servers.add(new ServerInfo("192.168.1.111", 8000));
servers.add(new ServerInfo("192.168.1.112", 8000));
servers.add(new ServerInfo("192.168.1.113", 8000));
servers.add(new ServerInfo("192.168.1.114", 8000));
servers.add(new ServerInfo("192.168.1.11", 8000));
servers.add(new ServerInfo("192.168.1.10", 8000));
servers.add(new ServerInfo("192.168.1.115", 8000));
servers.add(new ServerInfo("192.168.1.116", 8000));
servers.add(new ServerInfo("192.168.1.117", 8000));
servers.add(new ServerInfo("192.168.1.118", 8000));
ServerRouter serverRouter = new ConsistencyHashServerRouter(servers);
for (int i = 0; i < DATA_NUMBER; i++) {
ServerInfo serverInfo = serverRouter.getServer("ceshishuju" + i + i + i);
Integer number = nodeDataMap.get(serverInfo);
if (number == null) {
nodeDataMap.put(serverInfo, 1);
} else {
nodeDataMap.put(serverInfo, number + 1);
}
}
}
}
评论