killme2008 / xmemcached

High performance, easy to use multithreaded memcached client in java.
http://fnil.net/xmemcached
Apache License 2.0
757 stars 280 forks source link

when one memcached node Dns Change to new IP then the HashAlgorithm.KETAMA_HASH always use the old IP to calc getSessionByKey #121

Open junefsh opened 4 years ago

junefsh commented 4 years ago

Hi,author: in my case ,i use KetamaMemcachedSessionLocator init MemcacheClient code like: MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(hostList)); builder.setFailureMode(false); builder.setSessionLocator(new KetamaMemcachedSessionLocator()); the hostList use domain,like this: host1.test.com:11211 host2:test.com:11211 host3.test.com:11211,and the dns like: 192.168.1.11 host1.test.com 192.168.1.12 host2.test.com 192.168.1.13 host4.test.com

when the host2.test.com(192.168.1.12) was down,i use another ip to host2.test.com like 192.168.1.14 host2.test.com

xmemcached can auto connnect to the new ip,and update InetSocketAddressWrapper.inetSocketAddress but it does not refresh InetSocketAddressWrapper.remoteAddressStr,code in : // updated resolve addr addrWrapper.setResolvedSocketAddress(remoteSocketAddress); if we have more than one client , and some nodes has restart and use the new IP init ,then the same key come from diff client has diffrent hash key,this is not we want it.

Maybe you would suggest use gwhalinMemcachedJavaClientCompatibiltyConsistent = true to solve this problem code like this: MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(hostList)); //when fail ,fast remove unable node builder.setFailureMode(false); // Using consistent hash algorithm builder.setSessionLocator(new KetamaMemcachedSessionLocator(HashAlgorithm.KETAMA_HASH,false,true)); but we must think that : on line product environment,the memcached distribute node has all init data and only small amount request will miss and load from db,if we change the init hash algorithm,we must rebuild the data.

so the best way to solve this case,use can fix the code like this: MemcachedConnector.addMainSession // updated resolve addr addrWrapper.setResolvedSocketAddress(remoteSocketAddress); // fix when same dns name point to diff ip addrWrapper.setRemoteAddressStr(String.valueOf(remoteSocketAddress)); this like add a new memcached node ,and the behavior of reconnect and restart is consistent