Memcached Client 使用手册
Memcached Client 使用手冊
Author: cenwenchu
Email: wenchu.cenwc@alibaba-inc.com
Blog:http://blog.csdn.net/cenwenchu79/
Project: http://code.google.com/p/memcache-client-forjava/
Cache Client接口定義
?
圖 1 Memcached Cache Client接口類圖
?ICache和IMemcachedCache接口是Cache的基礎接口,定義了基本的Cache操作,詳細地說明參看附錄,使用方式參看Demo和使用注意。ICacheManager是Cache生命周期管理類,一個應用只需要一個ICacheManager來管理所有的Cache,具體介紹參看Cache Demo中的Cache Manager介紹。
Cache Client依賴及配置
Cache Client第三方依賴
commons-logging-1.0.4.jar or high version
log4j-1.2.12.jar or high version
codehaus/woodstox/wstx-asl-3.2.1.jar or high version
codehaus/staxapi/stax-api-1.0.1.jar or high version
?2.5.2版本以后還需要caucho/hessian/hessian-3.2.0.jar or high version
Cache Client支持默認(在Classpath中查找Memcached.xml作為客戶端配置)和指定配置文件。配置文件是Cache Client的正常運行的基礎,系統如果要在運行中使用Cache Client的話,必須在使用前(一般最好是應用啟動時)初始化Cache Client組件(讀取配置文件,創建連接池等等)。具體使用方式可以參看后面章節中的Demo。
Cache Client單客戶端配置
<?xml version="1.0" encoding="UTF-8"?>
<memcached>
??? ??<client name="mclient0" compressEnable="true" defaultEncoding="UTF-8" socketpool="pool0">
??????? ?<errorHandler>com.alisoft.xplatform.asf.cache.memcached.MemcachedErrorHandler</errorHandler>??? ??</client>
<socketpool name="pool0" failover="true" initConn="5" minConn="5" maxConn="250" maintSleep="5000"
??????? ???nagle="false" socketTO="3000" aliveCheck="true">
??????? ??<servers>10.2.224.36:33001,10.2.224.46:33001</servers>
???<weights>3,7</weights>
?? ?? </socketpool>
</memcached>
創建memcached的標簽。
創建 client的標簽。
注意:
name 屬性是程序中使用Cache的唯一標識。
socketpool 屬性將會關聯到后面的socketpool配置。
errorHandler 可選,用來處理出錯情況。注意在Tag中不要使用空格或者Tab鍵。
創建socketpool的標簽。
注意:
name 屬性和client 配置中的socketpool 屬性相關聯。
maintSleep屬性是后臺線程管理SocketIO池的檢查間隔時間,如果設置為0,則表明不需要后臺線程維護SocketIO線程池,默認需要管理。
socketTO 屬性是Socket操作超時配置,單位ms。
aliveCheck 屬性表示在使用Socket以前是否先檢查Socket狀態。
創建 servers 標簽作為socketPool的子標簽.設置memcache服務端實例地址,支持多個地址設置,例如“10.2.224.36:33001” 或 “10.2.224.36:33001, 10.2.224.46:33002”.
創建 weights 標簽作為socketPool的子標簽(可選),它表明了上面設置的服務器實例的Load權重. 例如 <weights>3,7</weights> 表示30% load 在 10.2.224.36:33001, 70% load 在 10.2.224.46:33001
好了,基礎的配置就如上。現在可以直接到后面章節去學習使用Memcache客戶端,或者繼續看如何配置Cluster。
Cache Client集群配置
<?xml version="1.0" encoding="UTF-8"?>
<memcached>
??? ??<client name="mclient0" compressEnable="true" defaultEncoding="UTF-8" socketpool="pool0">
??????? ?<errorHandler>com.alisoft.xplatform.asf.cache.memcached.MemcachedErrorHandler</errorHandler>
??? ??</client>
??<client name="mclient0-bck" compressEnable="true" defaultEncoding="UTF-8" socketpool="pool0-bck">
??????? ?<errorHandler>com.alisoft.xplatform.asf.cache.memcached.MemcachedErrorHandler</errorHandler>
??? ??</client>
<socketpool name="pool0" failover="true" initConn="5" minConn="5" maxConn="250" maintSleep="5000"
??????? ???nagle="false" socketTO="3000" aliveCheck="true">
??????? ??<servers>10.2.224.36:33001,10.2.224.46:33001</servers>
?? ?? </socketpool>
<socketpool name="pool0-bck" failover="true" initConn="5" minConn="5" maxConn="250" maintSleep="5000" nagle="false" socketTO="3000" aliveCheck="true">
??????? ??<servers>10.2.224.36:33002,10.2.224.46:33002</servers>
?? ?? </socketpool>
<cluster name="cluster1" mode="active">//mode = active,standby
?????? ? ?<memCachedClients> mclient0, mclient0-bck</memCachedClients>
?? ?? </cluster>
</memcached>
?
?Memcache是集中式的Cache,因此它存在單點問題(雖然數據可以分散到多臺服務器上,但是還會丟失部分數據)。為了解決單點問題,Memcache客戶端支持配置集群。
?集群配置很簡單. 1.創建cluster標簽 2. 創建memCachedClients 標簽作為cluster的子標簽,然后將客戶端配置到memCachedClients 標簽中。3.可以配置cluster mode(如果沒有設置mode屬性,默認采用active)。
?集群當前的特性:
集群中多節點軟負載均衡。(當前采用簡單的Hash算法加取余來分發數據)
數據在多節點上異步冗余存儲。(防止數據丟失最基本要求)
節點不可用切換功能。(當根據算法分發到某一失敗節點時可以轉向到其他可用節點)
節點恢復可用后數據Lazy復制。(當A,B兩臺機器作為集群的時候,如果A出現了問題,系統會去B獲取數據,當A正常以后,如果應用在A中沒有拿到數據可以去B獲取數據,并且復制到A上,這種方式也是一種lazy的復制。)
?
Cache Client Demo
?在Google項目中有sample包,內部包含了測試用例和測試所需要的配置文件(配置文件中的具體服務器端口和地址需要自己修改)。
下載地址為:http://memcache-client-forjava.googlecode.com/files/alisoft-xplatform-asf-cache-sample%282.5version%29.zip
類IMemcachedCacheTest是Cache功能單元測試類。
類StressCacheTest是Cache壓力測試類。
類MemcachedClusterTest是Cache集群測試類。
Cache Manager
?在使用Cache Client的應用中都需要有一個Cache Manager來管理各個Cache Client的生命周期。Cache Manager通過讀取配置初始化各個Cache Client,應用通過Cache Manager獲取到Cache Client進行數據交互。Cache Manager結束后,Cache Client也就被結束并釋放。Cache Manager也可以動態的重新載入配置文件,實現動態擴容。
?建議一個應用只需要設置一個Cache Manager,在應用啟動時將Cache Manager啟動,在應用結束時將Cache Manager結束。測試用例代碼如下:
static ICacheManager<IMemcachedCache> manager;//可以直接設定為靜態的單例
?@BeforeClass
?public static void setUpBeforeClass() throws Exception
?{
??manager = CacheUtil.getCacheManager(IMemcachedCache.class,
???MemcachedCacheManager.class.getName());//manager初始化,可以通過配置來替換CacheManager實現
??manager.setConfigFile("memcached1.xml");//設置Cache Client配置文件
??manager.setResponseStatInterval(5*1000);//設置Cache響應統計間隔時間,不設置則不進行統計
??manager.start();//Manager啟動
?}
?@AfterClass
?public static void tearDownAfterClass() throws Exception
?{
??manager.stop();//manager結束
?}
通過manager.reload("memcached_cluster2.xml");可以實現動態擴容,同時支持將memcached_cluster2.xml為http://10.2.226.41/sip/memcached_cluster2.xml,實現遠程獲取配置。具體使用,請參看集群測試用例中的代碼。(請注意測試用例中的sleep代碼,這些是系統在關閉和啟動時的延時)
使用注意
使用Clear方法時,如果立即去獲取數據可能會因為回收速度問題導致獲取到被刪除的數據,需要有部分的延時,采用sleep來避免問題發生。
Manager的reload會重新載入配置,但是對于服務端的數據不會刪除,因此需要注意新的配置中集群數據相互拷貝問題。同時reload以后對于cache client需要重新獲取對象,否則保留的還是原來的cache client,將無法使用。(數據復制采用lazy的方式,如果需要立即全部重新分配,可以采用Manager的ClusterCopy接口實現)
對于get,put聯合操作的一些場景,建議采用計數器來實現原子操作。(計數器需要通過getCounter,storeCounter,incr,decr等等接口來操作,不是普通的get,put操作)
可以使用add,replace來滿足一些需要對內容是否存儲有不同策略的場景。
使用本地Cache和Memcached Cache組合的情況中,在緩存數據到本地以后,如果對此數據作了修改,會讓本地緩存失效,但是無法通知到其他應用或者其他服務器的本地緩存。
集群的active和standby兩種模式,前者速度可能在某些情況下稍慢(當key的確沒有存在于集群任何一節點時,active模式會去嘗試兩個節點獲取數據),但是具有數據恢復功能,后者速度比較快,但是沒有數據恢復功能。
附錄:
接口定義說明:
/**
?* Cache統一接口
?* @author wenchu.cenwc
?*
?*/
public interface ICache<K,V>
{
?/**
? * 保存數據
? * @param key
? * @param value
? * @return
? */
?public V put(K key,V value);?
?
?/**
? * 保存有有效期的數據
? * @param key
? * @param value
? * @param 有效期(取的是客戶端時間)
? * @return
? */
?public V put(K key,V value, Date expiry);
?
?/**
? * 保存有有效期的數據
? * @param key
? * @param value
? * @param 設置有效期為距離當前時間后TTL秒。
? * @return
? */
?public V put(K key,V value, int TTL);
?
?/**
? * 獲取緩存數據
? * @param key
? * @return
? */
?public V get(K key);
?
?/**
? * 移出緩存數據
? * @param key
? * @return
? */
?public V remove(K key);?
?
?/**
? * 刪除所有緩存內的數據
? * @return
? */
?public boolean clear();
?
?/**
? * 緩存數據數量(Memcached接口當前不支持)
? * @return
? */
?public int size();
?
?/**
? * 緩存所有的key的集合
? * @return
? */
?public Set<K> keySet();
?
?/**
? * 緩存的所有value的集合
? * @return
? */
?public Collection<V> values();
?
?/**
? * 是否包含了指定key的數據
? * @param key
? * @return
? */
?public boolean containsKey(K key);
?
?/**
? * 釋放Cache占用的資源
? */
?public void destroy();
}
/**
?* Memcached Cache的接口定義
?* @author wenchu.cenwc<wenchu.cenwc@alibaba-inc.com>
?*/
public interface IMemcachedCache extends ICache<String,Object>
{
?/**
? * 降低memcache的交互頻繁造成的性能損失,因此采用本地cache結合memcache的方式
? * @param key
? * @param 本地緩存該數據有效秒數
? * @return
? */
?public Object get(String key,int localTTL);
?
?/**
? * 獲取多個keys對應的值
? * @param keys
? * @return
? */
?public Object[] getMultiArray(String[] keys);
?/**
? * 獲取多個keys對應的key&value Entrys
? * @param keys
? * @return
? */
?public Map<String,Object> getMulti(String[] keys);
?
?
?/**
? * key所對應的是一個計數器,實現增加inc的數量
? * @param key
? * @param inc
? * @return
? */
?public long incr(String key,long inc);
?
?/**
? * key所對應的是一個計數器,實現減少decr的數量
? * @param key
? * @param decr
? * @return
? */
?public long decr(String key,long decr);
?
?/**
? * key所對應的是一個計數器,實現增加inc的數量
? * @param key
? * @param inc
? * @return
? */
?public long addOrIncr(String key,long inc);
?
?/**
? * key所對應的是一個計數器,實現減少decr的數量
? * @param key
? * @param decr
? * @return
? */
?public long addOrDecr(String key,long decr);
?
?/**
? * 存儲計數器
? * @param key
? * @param count
? */
?public void storeCounter(String key,long count);
?
?/**
? * 獲取寄存器,-1表示不存在
? * @param key
? */
?public long getCounter(String key);
?
?
?/**
? * 這個接口返回的Key如果采用fast模式,
? * 那么返回的key可能已經被清除或者失效,但是在內存中還有痕跡,如果是非fast模式,那么就會精確返回,但是效率較低
? * @param 是否需要去交驗key是否存在
? * @return
? */
?public Set<String> keySet(boolean fast);
?
?/**
? * 統計服務器的Slab的情況
? * @return
? */
?public MemcacheStatsSlab[] statsSlabs();
?
?/**
? * 統計Memcache使用的情況
? * @return
? */
?public MemcacheStats[] stats();
?
?/**
? * 統計Items的存儲情況
? * @param servers
? * @return
? */
?@SuppressWarnings("unchecked")
?public Map statsItems();
?
?/**
? * 統計Cache的響應時間(必需設置statisticsInterval大于0才會開始統計)
? * @return
? */
?public MemcachedResponse statCacheResponse();
?
?/**
? * 設置統計時間,單位為秒
? * @param checkInterval
? */
?public void setStatisticsInterval(long checkInterval);
?
?/**
? * 保存數據,前提是key不存在于memcache中,否則保存不成功
? * @param key
? * @param value
? * @return
? */
?public boolean add(String key,Object value);?
?
?/**
? * 保存有有效期的數據,前提是key不存在于memcache中,否則保存不成功
? * @param key
? * @param value
? * @param 有效期
? * @return
? */
?public boolean add(String key,Object value, Date expiry);
?
?
?/**
? * 保存數據,前提是key必須存在于memcache中,否則保存不成功
? * @param key
? * @param value
? * @return
? */
?public boolean replace(String key,Object value);?
?
?/**
? * 保存有有效期的數據,前提是key必須存在于memcache中,否則保存不成功
? * @param key
? * @param value
? * @param 有效期
? * @return
? */
?public boolean replace(String key,Object value, Date expiry);?
?/**
? * 異步存入數據,當前立即返回,稍后存入數據
? * @param key
? * @param value
? */
?public void asynPut(String key,Object value);
?
?
?/**
? * 異步累減計數器,不保證累減成功
? * @param key
? * @param decr
? */
?public void asynAddOrDecr(String key,long decr);
?
?/**
? * 異步累加計數器,不保證累加成功
? * @param key
? * @param incr
? */
?public void asynAddOrIncr(String key,long incr);
?
?/**
? * 異步累減計數器,不保證累減成功
? * @param key
? * @param decr
? */
?public void asynDecr(String key,long decr);
?
?/**
? * 異步累加計數器,不保證累加成功
? * @param key
? * @param incr
? */
?public void asynIncr(String key,long incr);
?
?/**
? * 異步存儲計數器,不保證保存成功
? * @param key
? * @param count
? */
?public void asynStoreCounter(String key,long count);
}
轉載于:https://www.cnblogs.com/yangkai-cn/p/4016750.html
總結
以上是生活随笔為你收集整理的Memcached Client 使用手册的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [译]GLUT教程 - 每秒帧数
- 下一篇: URAL-1982 Electrific