作者:姚星火 个人主页:http://fantasyplace.googlepages.com/index.html
Memcached Client工作原理
static {
String[] serverlist = { “cache0.server.com:12345”,“cache1.server.com:12345” };
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(serverlist);
pool.initialize();
}
执行静态代码后,会把serverlist缓存在List buckets中,备用;
储存对象时,如果是set(key,value,hashcode),根据hashcode除以server数量的余数(如果是负数就乘以-1)首先决定存储在哪台server上,但如果这台server死了,会循环从serverlist中再选一台活着的server;如果是set(key,value),把value的hash值(有几种hash算法可以选择)除以server数量的余数决定储存在那台server上。
获取对象的时候,也是用同样的算法首先决定从哪台server上获取数据。
设置hash算法的代码:
/**
* Sets the hashing algorithm we will use.
*
* The types are as follows.
*
* SockIOPool.NATIVE_HASH (0) - native String.hashCode() - fast (cached) but
* not compatible with other clients SockIOPool.OLD_COMPAT_HASH (1) -
* original compatibility hashing alg (works with other clients)
* SockIOPool.NEW_COMPAT_HASH (2) - new CRC32 based compatibility hashing
* algorithm (fast and works with other clients)
*
* @param alg
* int value representing hashing algorithm
*/
public void setHashingAlg(int alg) {
this.hashingAlg = alg;
}
客户端这样写:
static {
String[] serverlist = { “cache0.server.com:12345”,“cache1.server.com:12345” };
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(serverlist);
pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);
pool.initialize();
}
所以Server之间没有备抄数据,可能它的初衷是为了获得高的性能而牺牲稳定性吧,不过修改Memcached Client的代码,增加一个定时执行daemon,把数据抄到其它的server上,修改存取对象的算法也可以实现。如果不修改Memcached Client代码,在使用的时,一般可以这样做:
String value=null;
if(memcachedClient.get(key)==null){//如果取不到数据,或者数据已经过期
value=getValueFromDB();//从数据库中取出数据,使用
memcachedClient.set(key,value);//把数据存入memcached,备用
} else {
value=memcachedClient.get(key);//如果取到数据
}