java客户端调用Memcached的三种方式(整合)

Memcached简介

Memcache是一个高性能的 分布式的内存对象缓存系统,通过在 内存里维护一个统一的巨大的 hash表,它能够用来存储各种 格式的数据,包括 图像、 视频、 文件以及 数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。
Memcache是danga的一个项目,最早是LiveJournal 服务的,最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用。
Memcached是以守护程序方式运行于一个或多个 服务器中,随时会接收 客户端的 连接和操作。

Memcached工作原理

客户端可以由各种语言编写,目前已知的客户端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。客户端在与 memcached 服务建立连接之后,接下来的事情就是存取对象了,每个被存取的对象都有一个唯一的标识符 key,存取操作均通过这个 key 进行,保存到 memcached 中的对象实际上是放置内存中的,并不是保存在 cache 文件中的,这也是为什么 memcached 能够如此高效快速的原因。注意,这些对象并不是持久的,服务停止之后,里边的数据就会丢失。 
与许多 cache 工具类似,Memcached 的原理并不复杂。它采用了C/S的模式,在 server 端启动服务进程,在启动时可以指定监听的 ip,自己的端口号,所使用的内存大小等几个关键参数。一旦启动,服务就一直处于可用状态。Memcached 的目前版本是通过C实现,采用了单进程,单线程,异步I/O,基于事件 (event_based) 的服务方式.使用 libevent 作为事件通知实现。多个 Server 可以协同工作,但这些 Server 之间是没有任何通讯联系的,每个 Server 只是对自己的数据进行管理。Client 端通过指定 Server 端的 ip 地址(通过域名应该也可以)。需要缓存的对象或数据是以 key->value 对的形式保存在Server端。key 的值通过 hash 进行转换,根据 hash 值把 value 传递到对应的具体的某个 Server 上。当需要获取对象数据时,也根据 key 进行。首先对 key 进行 hash,通过获得的值可以确定它被保存在了哪台 Server 上,然后再向该 Server 发出请求。Client 端只需要知道保存 hash(key) 的值在哪台服务器上就可以了。 
其实说到底,memcache 的工作就是在专门的机器的内存里维护一张巨大的 hash 表,来存储经常被读写的一些数组与文件,从而极大的提高网站的运行效率。 

1、三种API的比较

(1)较早推出的memcached JAVA客户端API,应用广泛,运行比较稳定。

(2)A simple, asynchronous, single-threaded memcached client written in java. 支持异步,单线程的memcached客户端,用到了java1.5版本的concurrent和nio,存取速度会高于前者,但是稳定性不好,测试中常 报timeOut等相关异常。

(3)XMemcached同样是基于java nio的客户端,java nio相比于传统阻塞io模型来说,有效率高(特别在高并发下)和资源耗费相对较少的优点。传统阻塞IO为了提高效率,需要创建一定数量的连接形成连接 池,而nio仅需要一个连接即可(当然,nio也是可以做池化处理),相对来说减少了线程创建和切换的开销,这一点在高并发下特别明显。因此 XMemcached与Spymemcached在性能都非常优秀,在某些方面(存储的数据比较小的情况下)Xmemcached比 Spymemcached的表现更为优秀,具体可以看这个Java Memcached Clients Benchmark。


2、建议


由于memcached client for java发布了新版本,性能上有所提高,并且运行稳定,所以建议使用memcached client for java。

XMemcached也使用得比较广泛,而且有较详细的中文API文档,具有如下特点:高性 能、支持完整的协议、支持客户端分布、允许设置节点权重、动态增删节点、支持JMX、与Spring框架和Hibernate-memcached的集 成、客户端连接池、可扩展性好等。


3、示例代码

(1)memcached client for java

https://cloud.github.com/downloads/gwhalin/Memcached-Java-Client/java_memcached-release_2.6.6.zip下载解压后,将里面所有的jar包添加到项目的构建路径里。

import java.util.Date;

import com.danga.MemCached.*;

public class MemcacheManagerForGwhalin {

	// 构建缓存客户端
	private static MemCachedClient cachedClient;
	// 单例模式实现客户端管理类
	private static MemcacheManagerForGwhalin INSTANCE = new MemcacheManagerForGwhalin();

	private MemcacheManagerForGwhalin() {
		cachedClient = new MemCachedClient();
		
		// 初始化SockIOPool,管理memcached的连接池
		SockIOPool pool = SockIOPool.getInstance();

		// 设置缓存服务器列表,当使用分布式缓存的时,可以指定多个缓存服务器。(这里应该设置为多个不同的服务器)
		String[] servers = { "192.168.163.10:11211", "192.168.163.11:11211"
		// 也可以使用域名 "server3.mydomain.com:1624"
		};

		pool.setServers(servers);
		pool.setFailover(true);
		pool.setInitConn(10); // 设置初始连接
		pool.setMinConn(5);// 设置最小连接
		pool.setMaxConn(250); // 设置最大连接
		pool.setMaxIdle(1000 * 60 * 60 * 3); // 设置每个连接最大空闲时间3个小时
		pool.setMaintSleep(30);
		pool.setNagle(false);
		pool.setSocketTO(3000);
		pool.setAliveCheck(true);
		pool.initialize();
	}

	/**
	 * 获取缓存管理器唯一实例
	 * 
	 * @return
	 */
	public static MemcacheManagerForGwhalin getInstance() {
		return INSTANCE;
	}

	public void add(String key, Object value) {
		cachedClient.set(key, value);
	}

	public void add(String key, Object value, int milliseconds) {
		cachedClient.set(key, value, milliseconds);
	}

	public void remove(String key) {
		cachedClient.delete(key);
	}

	public void remove(String key, int milliseconds) {
		cachedClient.delete(key, milliseconds, new Date());
	}

	public void update(String key, Object value, int milliseconds) {
		cachedClient.replace(key, value, milliseconds);
	}

	public void update(String key, Object value) {
		cachedClient.replace(key, value);
	}

	public Object get(String key) {
		return cachedClient.get(key);
	}

	public static void main(String[] args) {
		//将对象加入到memcached缓存
		cachedClient.add("keke", "This is a test String");
		//从memcached缓存中按key值取对象
		String result  = (String) cachedClient.get("keke");
		System.out.println(result);
	}
	
}

(2) spymemcached

官方下载网址:http://code.google.com/p/spymemcached/
public class MemcacheManagerForSpy implements IMemcacheManager {
	// 缓存客户端
	private MemcachedClient memcacheCient;
	// Manager管理对象,单例模式
	private static MemcacheManagerForSpy INSTANCE = new MemcacheManagerForSpy();

	private MemcacheManagerForSpy() {
		try {
			memcacheCient = new MemcachedClient(new InetSocketAddress(
					"127.0.0.1", 11211));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static MemcacheManagerForSpy getInstance() {
		return INSTANCE;
	}

	@Override
	public void add(String key, Object value, int milliseconds) {
		memcacheCient.add(key, milliseconds, value);
	}

	@Override
	public void add(String key, Object value) {
		memcacheCient.add(key, 3600, value);

	}

	@Override
	public void remove(String key, int milliseconds) {
		memcacheCient.delete(key);
	}

	@Override
	public void remove(String key) {
		memcacheCient.delete(key);
	}

	@Override
	public void update(String key, Object value, int milliseconds) {
		memcacheCient.replace(key, milliseconds, value);
	}

	@Override
	public void update(String key, Object value) {
		memcacheCient.replace(key, 3600, value);
	}

	@Override
	public Object get(String key) {
		return memcacheCient.get(key);
	}
}


(3)xmemcached

Xmemcached的官方网址是:http://code.google.com/p/xmemcached/
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import net.rubyeye.xmemcached.utils.AddrUtil;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.exception.MemcachedException;
public class TestXMemcache {
	
	public static void main(String[] args) {
		MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses("10.11.15.222:10000"));
		MemcachedClient memcachedClient;
		try {
			memcachedClient = builder.build();
			memcachedClient.set("hello", 0, "Hello,xmemcached");
			String value = memcachedClient.get("hello");
			System.out.println("hello=" + value);
			memcachedClient.delete("hello");
			value = memcachedClient.get("hello");
			System.out.println("hello=" + value);
			// close memcached client
			memcachedClient.shutdown();
		} catch (MemcachedException e) {
			System.err.println("MemcachedClient operation fail");
			e.printStackTrace();
		} catch (TimeoutException e) {
			System.err.println("MemcachedClient operation timeout");
			e.printStackTrace();
		} catch (InterruptedException e) {
			// ignore
		} catch (IOException e) {
			System.err.println("Shutdown MemcachedClient fail");
			e.printStackTrace();

		}

	}

}


你可能感兴趣的:(memcached)