XMemcached实例及与spring的集成

1.Memcached Client简要介绍
Memcached Client目前有3种: 

1.Memcached Client for Java  2.SpyMemcached   3.XMemcached

这三种Client一直存在各种争议:

Memcached Client for Java 比 SpyMemcached更稳定、更早、更广泛;SpyMemcached 比 Memcached Client for Java更高效;XMemcached 比 SpyMemcache并发效果更好。

具体可以参考官方性能对比: 

Memcached Client for Java: https://github.com/gwhalin/Memcached-Java-Client/wiki/PERFORMANCE 
XMemcached: http://xmemcached.googlecode.com/svn/trunk/benchmark/benchmark.html 

2.XMemcached特性 

高性能;支持完整的memcached文本协议,二进制协议;支持JMX,可以通过MBean调整性能参数、动态添加/移除server、查看统计等;支持客户端统计;支持memcached节点的动态增减;支持memcached分布:余数分布和一致性哈希分布;更多的性能调整选项。

3.XMemcached简单实现

MemcachedClientBuilder是MemcachedClient核心接口,用来控制Client的构建(build()方法)和关闭(shutdown()方法)。 通过build()方法获得 MemcachedClient 

然后就可以通过Memcached进行set、get、replace、delete等Memcached操作了! 

import static junit.framework.Assert.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.utils.AddrUtil;

import org.junit.Test;

public class MemcachedClientTest {
	@Test
	public void test() {
		MemcachedClientBuilder builder = new XMemcachedClientBuilder(
		    AddrUtil.getAddresses("192.168.1.110:11211 192.168.1.111:11211"),new int[] { 1, 1});
		// 设置连接池大小,即客户端个数
		builder.setConnectionPoolSize(50);
		// 宕机报警
		builder.setFailureMode(true);
		// 使用二进制文件
		builder.setCommandFactory(new BinaryCommandFactory());
		// 使用一致性哈希算法(Consistent Hash Strategy)
		builder.setSessionLocator(new KetamaMemcachedSessionLocator());
		// 使用序列化传输编码
		builder.setTranscoder(new SerializingTranscoder());
		// 进行数据压缩,大于1KB时进行压缩
		builder.getTranscoder().setCompressionThreshold(1024);
		MemcachedClient memcachedClient = null;
		try {
			memcachedClient = builder.build();
			try {
				// 设置/获取
				memcachedClient.set("aa", 36000, "set/get");
				assertEquals("set/get", memcachedClient.get("aa"));
				// 替换
				memcachedClient.replace("aa", 36000, "replace");
				assertEquals("replace", memcachedClient.get("aa"));
				// 移除
				memcachedClient.delete("aa");
				assertNull(memcachedClient.get("aa"));
			} catch (TimeoutException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (MemcachedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (memcachedClient != null) {
				try {
					memcachedClient.shutdown();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}


4.XMemcached与Spring集成
XMemcached与Spring集成可以参考http://code.google.com/p/xmemcached/wiki/Spring_Integration,这里只说最常用的方法。 
memcached.properties做基本配置: 

#连接池大小即客户端个数
memcached.connectionPoolSize=50
memcached.failureMode=true
#server1
memcached.server1.host=192.168.1.110
memcached.server1.port=11211
memcached.server1.weight=1
#server2
memcached.server2.host=192.168.1.111
memcached.server2.port=11211
memcached.server2.weight=2

XML配置文件: 

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- http://code.google.com/p/xmemcached/wiki/Spring_Integration -->
	<context:property-placeholder location="memcached.properties" />
	<bean
		id="memcachedClientBuilder"
		class="net.rubyeye.xmemcached.XMemcachedClientBuilder"
		p:connectionPoolSize="${memcached.connectionPoolSize}"
		p:failureMode="${memcached.failureMode}">
		<!-- XMemcachedClientBuilder have two arguments.First is server list,and 
			second is weights array. -->
		<constructor-arg>
			<list>
				<bean class="java.net.InetSocketAddress">
					<constructor-arg>
						<value>${memcached.server1.host}</value>
					</constructor-arg>
					<constructor-arg>
						<value>${memcached.server1.port}</value>
					</constructor-arg>
				</bean>
				<bean class="java.net.InetSocketAddress">
					<constructor-arg>
						<value>${memcached.server2.host}</value>
					</constructor-arg>
					<constructor-arg>
						<value>${memcached.server2.port}</value>
					</constructor-arg>
				</bean>
			</list>
		</constructor-arg>
		<constructor-arg>
			<list>
				<value>${memcached.server1.weight}</value>
				<value>${memcached.server2.weight}</value>
			</list>
		</constructor-arg>
		<property name="commandFactory">
			<bean class="net.rubyeye.xmemcached.command.TextCommandFactory" />
		</property>
		<property name="sessionLocator">
			<bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator" />
		</property>
		<property name="transcoder">
			<bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
		</property>
	</bean>
	<!-- Use factory bean to build memcached client -->
	<bean
		id="memcachedClient"
		factory-bean="memcachedClientBuilder"
		factory-method="build"
		destroy-method="shutdown" />
</beans>

这里的 memcachedClientBuilder节点完成 MemcachedClientBuilder,然后通过 memcachedClient节点配置 factory-method,调用 MemcachedClientBuilder的build()方法产生 MemcachedClient,并配置 destroy-method进行关闭。 
有了Spring容器支持,我们不需要在代码中进行配置,也不需要重复调用build()跟shutdown()方法,这些操作交给Spring来完成。 

import static junit.framework.Assert.*;

import java.util.concurrent.TimeoutException;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MemcachedSpringTest {
	private ApplicationContext app;
	private MemcachedClient memcachedClient;
	@Before
	public void init() {
		app = new ClassPathXmlApplicationContext("applicationContext.xml");
		memcachedClient = (MemcachedClient) app.getBean("memcachedClient");
	}
	@Test
	public void test() {
		try {
			// 设置/获取
			memcachedClient.set("aa", 36000, "set/get");
			assertEquals("set/get", memcachedClient.get("aa"));

			// 替换
			memcachedClient.replace("aa", 36000, "replace");
			assertEquals("replace", memcachedClient.get("aa"));

			// 移除
			memcachedClient.delete("aa");
			assertNull(memcachedClient.get("aa"));
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

5.总结

  • Memcached的Key,要杜绝使用空格,且长度控制在250个字符。

  • Memcached的Value,要控制体积,必须小于1MB,必要时进行使用压缩。

  • 失效时间,0为永久有效,最大值不得超过30天(2592000s),否则重新计算可能缓存只有1秒

  • Memcached仅支持LRU算法,完全适用你的需要。

  • 尽量不要将List这种重体积对象扔到Memcached中,传输、存储都会产生瓶颈。

  • 使用一致性哈希算法实现,提高多个Memcacehd Server利用率。


你可能感兴趣的:(XMemcached实例及与spring的集成)