您的位置:首页 > 数据库 > Memcache

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

2014-08-20 15:44 363 查看


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 J***A客户端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();

		}

	}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: