转自:http://blog.sina.com.cn/s/blog_4c925dca010193sy.html
当ms的hash表满了之后,新的插入数据会替代老的数据,更新的策略是LRU(最近最少使用),以及每个kv对的有效时限。Kv对存储有效时限是在mc端由app设置并作为参数传给ms的。
同时ms采用是偷懒替代法,ms不会开额外的进程来实时监测过时的kv对并删除,而是当且仅当,新来一个插入的数据,而此时又没有多余的空间放了,才会进行清除动作。
缓存数据库查询
现在memcached最流行的一种使用方式是缓存数据库查询,下面举一个简单例子说明:
App需要得到userid=xxx的用户信息,对应的查询语句类似:
“SELECT * FROM users WHERE userid = xxx”
App先去问cache,有没有“user:userid”(key定义可预先定义约束好)的数据,如果有,返回数据;如果没有,App会从数据库中读取数据,并调用cache的add函数,把数据加入cache中。
当取的数据需要更新,app会调用cache的update函数,来保持数据库与cache的数据同步。
从上面的例子我们也可以发现,一旦数据库的数据发现变化,我们一定要及时更新cache中的数据,来保证app读到的是同步的正确数据。
经过上面的描述后,相信网友们应该对 memcached的基本原理有了一个比较深晰的认识了
阿堂为了让网友们对上面的图示案例更好的理解,下面结合代码来说明一下
public class MemCached
{
// 创建全局的唯一实例
protected static MemCachedClient mcc = new MemCachedClient();
protected static MemCached memCached = new MemCached();
// 设置与缓存服务器的连接池
static {
// 服务器列表和其权重
//如下设置了三个ms
String[] servers = {"192.168.7.1:11211","192.168.7.2:11212","192.168.7.3:11213"};
Integer[] weights = {3};
// 获取socke连接池的实例对象
SockIOPool pool = SockIOPool.getInstance();
// 设置服务器信息
pool.setServers( servers );
pool.setWeights( weights );
// 设置初始连接数、最小和最大连接数以及最大处理时间
pool.setInitConn( 5 );
pool.setMinConn( 5 );
pool.setMaxConn( 250 );
pool.setMaxIdle( 1000 * 60 * 60 * 6 );
// 设置主线程的睡眠时间
pool.setMaintSleep( 30 );
// 设置TCP的参数,连接超时等
pool.setNagle( false );
pool.setSocketTO( 3000 );
pool.setSocketConnectTO( 0 );
// 初始化连接池
pool.initialize();
// 压缩设置,超过指定大小(单位为K)的数据都会被压缩
mcc.setCompressEnable( true );
mcc.setCompressThreshold( 64 * 1024 );
}
protected MemCached()
{
}
public static MemCached getInstance()
{
return memCached;
}
public boolean add(String key, Object value)
{
return mcc.add(key, value);
}
public boolean add(String key, Object value, Date expiry)
{
return mcc.add(key, value, expiry);
}
public boolean replace(String key, Object value)
{
return mcc.replace(key, value);
}
public boolean replace(String key, Object value, Date expiry)
{
return mcc.replace(key, value, expiry);
}
public Object get(String key)
{
return mcc.get(key);
}
public static void main(String[] args)
{
MemCached cache = MemCached.getInstance();
cache.add("foo ", "seattle");
//如上这一步经过了这样几个过程
1.对key foo进行哈希
2.选择服务器 (假设根据哈希算法,选择的服务器是 192.168.7.2:11212 MS B)
3. 连接
4.设置 key foo和value seattle
// cache.get("foo")如下一步执行
1.根据key foo进行哈希知道了 key foo是在 192.168.7.2:11212 MS B 上
2.连接 192.168.7.2:11212 MS B
3.在 192.168.7.2:11212 MS B 上根据 key foo得到相应的value seattle了
System.out.print("get value : " + cache.get("foo"));
}
}
至此,想必网友们对memcached技术有了一个比较相对完整的理解和认识了!
由于阿堂对memcached技术也在不断学习中,也算是一个新手了,这里总结分享一下,希望能对朋友们有所帮助!在后一篇文章中,阿堂准备分享一篇memcached的集群技术的实战分享给其它网友,敬请期待。
转自:http://blog.sina.com.cn/s/blog_4c925dca010193sy.html