1、创建环形hash空间,并依据复制品的个数在hash空间创建实际节点对应的虚拟节点
2、依据key在环形hash空间中,找到其对应的实际节点
import java.util.SortedMap;
import java.util.TreeMap;
public class ConsistentHash {
/**
* hash函数
*/
private final CRC32 hashFunction = new CRC32();
/**
* 虚拟节点是实际节点在 hash 空间的复制品
*/
private final int numberOfReplicas;
/**
* 环形hash空间
*/
private final SortedMap<Long, String> circle = new TreeMap<Long, String>();
public ConsistentHash(int numberOfReplicas, String[] servers) {
this.numberOfReplicas = numberOfReplicas;
for (int i = 0; i < servers.length; i++) {
add(servers[i]);
}
System.out.println("::::"+circle);
}
/**
* 在hash空间添加虚拟节点对应的实际节点
* @param server
*/
public void add(String server) {
for (int i = 0; i < numberOfReplicas; i++) {
circle.put(hashFunction.hash(server.toString() + i), server);
}
}
/**
* 删除hash空间中虚拟节点对应的实际节点
* @param server
*/
public void remove(String server) {
for (int i = 0; i < numberOfReplicas; i++) {
circle.remove(hashFunction.hash(server.toString() + i));
}
}
/**
* 依据key查询对应的实际节点
* @param key
* @return
*/
public String get(Object key) {
if (circle.isEmpty()) {
return null;
}
Long hash = hashFunction.hash(key.toString());
// System.out.println(key+"-->"+hash);
if (!circle.containsKey(hash)) {
SortedMap<Long, String> tailMap = circle.tailMap(hash);
hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
}
return circle.get(hash);
}
}
memcache 实现
static String[] servers = { "172.16.24.203:11211","192.168.1.173:11211" };
public static void main(String[] args) {
// memcached should be running on port 11211 but NOT on 11212
//cmd > memcached.exe -p 2000
BasicConfigurator.configure();
// Integer[] weights = { 3,2 };
SockIOPool pool = SockIOPool.getInstance("test");
pool.setServers( servers );
pool.setFailover( true );
pool.setInitConn( 10 );
pool.setMinConn( 5 );
pool.setMaxConn( 250 );
//pool.setMaintSleep( 30 );
pool.setNagle( false );
pool.setSocketTO( 3000 );
pool.setAliveCheck( true );
// pool.setWeights(weights);
pool.initialize();
MemCachedClient mcc = new MemCachedClient("test");
// turn off most memcached client logging:
//Logger.getLogger( MemCachedClient.class.getName() ).setLevel( com.schooner.MemCached.Logger. );
// System.out.println("flushAll returen : "+mcc.flushAll(servers));
ConsistentHash consistentHash = new ConsistentHash(2,servers);
// consistentHash.remove(servers[0]);
for (int i = 0; i < 10; i++) {
String key = "object" + i;
String obj1Cache = consistentHash.get(key);
System.out.println(key + " node-->" + obj1Cache);
String value1 = key + " Hello!";
boolean success = mcc.set(key, value1, obj1Cache.hashCode());
System.out.println(String.format("set( %s ): %s", key, success));
String result = (String) mcc.get(key, obj1Cache.hashCode());
System.out.println(String.format("get( %s ): %s", key, result));
}