Xmemcached用户指南
一、XMemcached简介
XMemcached是一个新java memcachedclient。也许你还不知道memcached是什么?可以先看看这里。简单来说,Memcached 是一个高性能的分布式内存对象的key-value缓存系统,用于动态Web应用以减轻数据库负载,现在也有很多人将它作为内存式数据库在使用,memcached通过它的自定义协议与客户端交互,而XMemcached就是它的一个java客户端实现。
Memcached的java客户端已经存在两个了:官方提供的基于传统阻塞io由Greg Whalin维护的客户端、Dustin Sallings实现的基于java nio的Spymemcached。另外还有一些在此基础上的改进版本。相比于这些客户端,XMemcached有什么优点呢?或者说,它的主要特性有哪些?
二、XMemcached的主要特性
1、
2、
3、
4、
5、
6、
7、
8、
9、
三、使用指南
在简单介绍完XMemcached的主要特性之后,我们将进入XMemcached的使用环节,这里将按照从简单到复杂的顺序讲解一些例子,以方便用户深入了解XMemcached的使用。
3.1简单例子
对于用户来说,最主要的功能是存取数据,假设我们有一个memcached节点IP地址或者域名是host,端口是11211,一个简单的存取数据的例子如下:
MemcachedClientBuilder builder =new XMemcachedClientBuilder(
MemcachedClient memcachedClient =builder.build();
因为XMemcachedClient的创建有比较多的可选项,因此提供了一个XMemcachedClientBuilder用于构建MemcachedClient。MemcachedClient是主要接口,操作memcached的主要方法都在这个接口里,XMemcachedClient是它的一个实现。传入的memcached节点列表要求是类似”host1:port1host2:port2 …”这样的字符串,通过AddrUtil.getAddresses方法获取实际的IP地址列表。存储数据是通过set方法,它有三个参数,第一个是存储的key名称,第二个是expire时间(单位秒),超过这个时间,memcached将这个数据替换出去,0表示永久存储(默认是一个月),第三个参数就是实际存储的数据,可以是任意的java可序列化类型。获取存储的数据是通过get方法,传入key名称即可。如果要删除存储的数据,这是通过delete方法,它也是接受key名称作为参数。XMemcached由于是基于nio,因此通讯过程本身是异步的,client发送一个请求给memcached,你是无法确定memcached什么时候返回这个应答,客户端此时只有等待,因此还有个等待超时的概念在这里。客户端在发送请求后,开始等待应答,如果超过一定时间就认为操作失败,这个等待时间默认是一秒,上面例子展现的3个方法调用的都是默认的超时时间,这三个方法同样有允许传入超时时间的重载方法,例如
Value=client.get(“hello”,3000);
就是等待3秒超时,如果3秒超时就跑出TimeutException,用户需要自己处理这个异常。因为等待是通过调用CountDownLatch.await(timeout)方法,因此用户还需要处理中断异常InterruptException。最后的MemcachedException表示Xmemcached内部发生的异常,如解码编码错误、网络断开等等异常情况。
3.2CAS操作
GetsResponse<Integer> result= client.gets("a");
long cas = result.getCas();
if (!client.cas("a", 0, 2, cas)) {
}
首先通过gets方法获取一个GetsResponse,此对象包装了存储的数据和cas值,然后通过cas方法尝试原子更新,如果失败打印”cas error”。显然,这样的方式很繁琐,并且如果你想尝试多少次原子更新就需要一个循环来包装这一段代码,因此XMemcached提供了一个CASOpertion接口包装了这部分操作,允许你尝试N次去原子更新某个key存储的数据,无需显式地调用gets获取cas值,上面的代码简化为:
client.cas("a", 0, new CASOperation<Integer>(){
CASOpertion接口只有两个方法,一个是设置最大尝试次数的getMaxTries方法,这里是尝试一次,如果尝试超过这个次数将抛出一个TimeoutException,如果你想无限尝试,可以将返回值设定为Integer.MAX_VALUE;另一个方法是根据当前获得的GetsResponse来决定更新数据的getNewValue方法,如果更新成功,这个方法返回的值将存储成功,这个方法的两个参数是最新一次gets返回的GetsResponse结果。
3.3更全面的例子
MemcachedClientBuilder builder =new XMemcachedClientBuilder(
if (!client.set("hello", 0, "world")) {
首先存储了hello对应的world字符串,然后调用add和replace方法去尝试添加和替换,因为数据已经存在,因此add会失败,同样replace在数据存在的情况才会成功,也就是将hello对应的数据更新为dennis,然后通过append和prepend方法在dennis前后加上了字符串hello和good,因此通过get返回的结果是hello dennisgood。而删除数据则是通过deleteWithNoReply方法,这个方法删除数据并且告诉memcached不用返回应答,因此这个方法不会等待应答直接返回,特别适合于批量处理;同样地,set、add、replace等方法也有相应的withNoReply重载版本,具体请看API文档。
下面这个例子展现了incr/decr操作的使用,两个操作类似java中的原子类如AtomicIntger,用于原子递增或者递减变量数值:
assert(1==this.memcachedClient.incr("a", 5, 1));
assert(6==this.memcachedClient.incr("a", 5));
assert(10==this.memcachedClient.incr("a", 4));
assert(9==this.memcachedClient.decr("a", 1));
assert(7==this.memcachedClient.deccr("a", 2));
Memcached提供了统计协议用于查看统计信息:
Map<InetSocketAddress,Map<String,String>>result=client.getStats();
getStats方法返回一个map,其中存储了所有已经连接并且有效的memcached节点返回的统计信息,你也可以统计具体的项目,如统计items项目:
Map<InetSocketAddress,Map<String,String>>result=client.getStatsByItem(“items”);