//mc client//hashingAlg 默认是0
private final long getHash(String key, Integer hashCode) {
if (hashCode != null) {
if (hashingAlg == CONSISTENT_HASH)
return hashCode.longValue() & 0xffffffffL;
else return hashCode.longValue();
} else {
switch (hashingAlg) {
case NATIVE_HASH:// 0
return (long) key.hashCode();
case OLD_COMPAT_HASH:
return origCompatHashingAlg(key);
case NEW_COMPAT_HASH:
return newCompatHashingAlg(key);
case CONSISTENT_HASH:
return md5HashingAlg(key);
default:
// use the native hash as a default
hashingAlg = NATIVE_HASH;
return (long) key.hashCode();
}
}
}
private boolean set(String cmdname, String key, Object value, Date expiry, Integer hashCode, Long casUnique,
boolean asString) {
//... ...
SchoonerSockIO sock = pool.getSock(key, hashCode);//获取服务节点
//... ...
}
public boolean set(String key, Object value) {
return set("set", key, value, null, null, 0L, primitiveAsString);
}
public boolean set(String key, Object value, Integer hashCode) {
return set("set", key, value, null, hashCode, 0L, primitiveAsString);
}
从以上代码可以看出如果用set(key, value);方法设置缓存的话,根据key的hash值来分配存储节点的;
如果用set(key, value, hashcode);会优先按照指定的hash值分配节点,就是说只要hashcode值一样就存在同一个mc节点服务器。
说完的存储再来看看multiGet,跟set类似
public Map<String, Object> getMulti(String[] keys, Integer[] hashCodes, boolean asString) {
......
SchoonerSockIO sock = pool.getSock(cleanKeys[i], hash);//同样是用getHash方法
......
}
public Map<String, Object> getMulti(String[] keys) {
return getMulti(keys, null);
}
public Map<String, Object> getMulti(String[] keys, Integer[] hashCodes) {
return getMulti(keys, hashCodes, false);
}
可以看出优先也是根据hashcode判断从哪个节点取数据。
看下面带hashCode例子
@Test
public void testSetMcWithHash() {
for(int i = 1; i <= 20; i++) {
memCachedClient.set("test-hash-"+i, "test hash value " + i,
"EntityName".hashCode());
}
}
@Test
public void testGetMultiWithHash() {
String keyPrefix = "test-hash-";
String[] keys = new String[20];
Integer[] hashs = new Integer[20];
for(int i = 0; i < 20; i++) {
keys[i] = keyPrefix + (i+1);
hashs[i] = "EntityName".hashCode();
}
Object[] values = memCachedClient.getMultiArray(keys, hashs);
if(values != null) {
for(Object o : values) {
logger.debug("value: {}", o);
}
}
}
//mc命令 ,只要建立一次网络io连接
get test-1 test-2 test-3 test-4 test-5 test-6 test-7 test-8 test-9 test-10 test-11 test-12 test-13 test-14 test-15 test-16 test-17 test-18 test-19 test-20
1 -> loadMulti before: java.nio.HeapByteBuffer[pos=907 lim=8192 cap=8192]
ret(20): {test-hash-5=test hash value 5, test-hash-4=test hash value 4, test-hash-7=test hash value 7, test-hash-6=test hash value 6, test-hash-9=test hash value 9, test-hash-8=test hash value 8, test-hash-10=test hash value 10, test-hash-20=test hash value 20, test-hash-14=test hash value 14, test-hash-13=test hash value 13, test-hash-12=test hash value 12, test-hash-11=test hash value 11, test-hash-18=test hash value 18, test-hash-17=test hash value 17, test-hash-16=test hash value 16, test-hash-15=test hash value 15, test-hash-1=test hash value 1, test-hash-2=test hash value 2, test-hash-19=test hash value 19, test-hash-3=test hash value 3}
1 -> loadMulti after: java.nio.HeapByteBuffer[pos=0 lim=8192 cap=8192]