1.Memcached Client簡要介紹
Memcached Client目前有3種:
html
1.Memcached Client for Java 2.SpyMemcached 3.XMemcachedjava
這三種Client一直存在各類爭議:git
Memcached Client for Java 比 SpyMemcached更穩定、更早、更普遍;SpyMemcached 比 Memcached Client for Java更高效;XMemcached 比 SpyMemcache併發效果更好。github
具體能夠參考官方性能對比: 算法
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特性
spring
高性能;支持完整的memcached文本協議,二進制協議;支持JMX,能夠經過MBean調整性能參數、動態添加/移除server、查看統計等;支持客戶端統計;支持memcached節點的動態增減;支持memcached分佈:餘數分佈和一致性哈希分佈;更多的性能調整選項。緩存
3.XMemcached簡單實現
MemcachedClientBuilder是MemcachedClient核心接口,用來控制Client的構建(build()方法)和關閉(shutdown()方法)。 經過build()方法得到 MemcachedClient ruby
而後就能夠經過Memcached進行set、get、replace、delete等Memcached操做了!
session
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(); } } }
Memcached的Key,要杜絕使用空格,且長度控制在250個字符。
Memcached的Value,要控制體積,必須小於1MB,必要時進行使用壓縮。
失效時間,0爲永久有效,最大值不得超過30天(2592000s),不然從新計算可能緩存只有1秒
Memcached僅支持LRU算法,徹底適用你的須要。
儘可能不要將List這種重體積對象扔到Memcached中,傳輸、存儲都會產生瓶頸。
使用一致性哈希算法實現,提升多個Memcacehd Server利用率。