介紹
Memcached java client是官方推薦的最早的memcached java客戶端。最新版本:java_memcached-release_2.6.1。
官方下載地址:https://github.com/gwhalin/Memcached-Java-Client 采用阻塞式SOCKET通訊,據說目前版本進行了很多優化,性能有所提高(只看過1.5的源代碼,還沒來及看最新的) 提供key方式的連接池,默認連接池key為default。(老版本了)。2.6.1版本支持apache-commoms-pool作為連接池。 支持權重配置。 后期的版本提增加了cas支持和getMutl功能
官方示例代碼 Java代碼 ?
import ?com.danga.MemCached.MemCachedClient;??import ?com.danga.MemCached.SockIOPool;??import ?com.schooner.MemCached.MemcachedItem;???? public ?class ?MemcachedForJavaExample?{???? ?????? ?????? ????protected ?static ?MemCachedClient?mcc?=?new ?MemCachedClient();?? ?? ?????? ????static ?{?? ?? ?????????? ????????String[]?servers?=?{?"localhost:11211" ,?"localhost:11212" ,?"localhost:11213" ?};?? ?? ????????Integer[]?weights?=?{?3 ,?3 ,?2 ?};?? ?? ?????????? ????????SockIOPool?pool?=?SockIOPool.getInstance();?? ?? ?????????? ????????pool.setServers(servers);?? ????????pool.setWeights(weights);?? ????????pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);?? ?? ?????????? ?????????? ?????????? ?????????? ????????pool.setInitConn(5 );?? ????????pool.setMinConn(5 );?? ????????pool.setMaxConn(250 );?? ????????pool.setMaxIdle(1000 ?*?60 ?*?60 ?*?6 );?? ?? ?????????? ?????????? ?????????? ????????pool.setMaintSleep(30 );?? ?? ?????????? ?????????? ?????????? ?????????? ????????pool.setNagle(false );?? ????????pool.setSocketTO(3000 );?? ????????pool.setSocketConnectTO(0 );?? ?? ?????????? ????????pool.initialize();?? ????}?? ?? ????public ?static ?void ?main(String[]?args)?{?? ????????System.out.println("SET:?" ?+?mcc.set("key1" ,?"value1" ));?? ????????System.out.println("SET:?" ?+?mcc.set("key2" ,?"value2" ));?? ????????System.out.println("SET:?" ?+?mcc.set("key3" ,?"value3" ));?? ????????System.out.println("GET:?" ?+?mcc.get("key1" ));?? ????????MemcachedItem?item?=?mcc.gets("key1" );?? ????????System.out.println("GETS:?value=" ?+?item.getValue()?+?",CasUnique:" +item.getCasUnique());?? ????????System.out.println("SET:?" ?+?mcc.set("key1" ,?"value1_1" ));?? ????????System.out.println("CAS:?" ?+?mcc.cas("key1" ,?"value1_2" ,?item.getCasUnique()));??? ????????System.out.println("getMulti:" ?+?mcc.getMulti(new ?String[]{"key1" ,"key2" ,"key3" }));?? ????}?? ?? }?? import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
import com.schooner.MemCached.MemcachedItem;public class MemcachedForJavaExample {// create a static client as most installs only need// a single instanceprotected static MemCachedClient mcc = new MemCachedClient();// set up connection pool once at class loadstatic {// server list and weightsString[] servers = { "localhost:11211", "localhost:11212", "localhost:11213" };Integer[] weights = { 3, 3, 2 };// grab an instance of our connection poolSockIOPool pool = SockIOPool.getInstance();// set the servers and the weightspool.setServers(servers);pool.setWeights(weights);pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);// set some basic pool settings// 5 initial, 5 min, and 250 max conns// and set the max idle time for a conn// to 6 hourspool.setInitConn(5);pool.setMinConn(5);pool.setMaxConn(250);pool.setMaxIdle(1000 * 60 * 60 * 6);// set the sleep for the maint thread// it will wake up every x seconds and// maintain the pool sizepool.setMaintSleep(30);// set some TCP settings// disable nagle// set the read timeout to 3 secs// and don't set a connect timeoutpool.setNagle(false);pool.setSocketTO(3000);pool.setSocketConnectTO(0);// initialize the connection poolpool.initialize();}public static void main(String[] args) {System.out.println("SET: " + mcc.set("key1", "value1"));System.out.println("SET: " + mcc.set("key2", "value2"));System.out.println("SET: " + mcc.set("key3", "value3"));System.out.println("GET: " + mcc.get("key1"));MemcachedItem item = mcc.gets("key1");System.out.println("GETS: value=" + item.getValue() + ",CasUnique:"+item.getCasUnique());System.out.println("SET: " + mcc.set("key1", "value1_1"));System.out.println("CAS: " + mcc.cas("key1", "value1_2", item.getCasUnique())); //必須FALSESystem.out.println("getMulti:" + mcc.getMulti(new String[]{"key1","key2","key3"}));}}
?
?
我的代碼 這個標題不好取,因為是我自己的想法,還需要大家多提意見,一起討論。想叫“建議代碼”或者“推薦代碼”,覺得不合適,還是先叫“我的代碼”吧,呵呵。
?
我的思路 1. 在原始客戶端上層,根據業務需求封裝MemcachedService(或叫MemcachedClient),負責緩存功能的包裝。如:你的業務只需要add,set,get,gets,cas,delete業務,那就只封裝這幾個功能。這樣做的好處是,屏蔽了各種客戶端的API差異,讓你的業務系統與客戶端實現解耦合,如果你以后需要換客戶端實現,對你的業務系統不會照成影響。 2.? 一般不要直接采用new的方式在你的代碼中顯示使用memcached客戶端實現,應該采用單例的方式使用memcached客戶端實現,或者使用Spring的singleton方式配置。Memcached客戶端實現是線程安全的。 3. memcached客戶端一般都需要大量的配置,考慮擴展和配置修改,應該把參數設置設計為可配置的,可以寫到propertis配置文件中或是使用Spring進行配置。
我的實現 業務層封裝接口 Java代碼 ?
? ? ? ? ? ? ?? public ?interface ?MemcachedClientService?{???? ????String?get(String?key);?? ?? ????CacheItem?gets(String?key);?? ?? ????boolean ?add(String?key,?String?value);?? ?? ????boolean ?set(String?key,?String?value);?? ?? ????boolean ?cas(String?key,?String?value,?long ?unique);?? ?????? ????boolean ?delete(String?key)?? ?? ????boolean ?flushAll();?? ?? }?? /*** Memcached 常用功能接口定義,用于業務層直接使用,屏蔽各種客戶端實現的API差異,實現解耦客戶端與業務系統的目的* 無過期時間和flags支持,無append,prepend,replace,incr,decr等操作* * @author zhangpu* */
public interface MemcachedClientService {String get(String key);CacheItem gets(String key);boolean add(String key, String value);boolean set(String key, String value);boolean cas(String key, String value, long unique);boolean delete(String key)boolean flushAll();}
? Java代碼 ?
public ?class ?CacheItem?{???? ????private ?String?key;?? ????private ?String?value;?? ????private ?long ?unique;?? ?? ????public ?CacheItem()?{?? ????????super ();?? ????}?? ?? ????public ?CacheItem(String?key,?String?value,?long ?unique)?{?? ????????super ();?? ????????this .key?=?key;?? ????????this .value?=?value;?? ????????this .unique?=?unique;?? ????}?? ?? ????public ?String?getKey()?{?? ????????return ?key;?? ????}?? ?? ????public ?void ?setKey(String?key)?{?? ????????this .key?=?key;?? ????}?? ?? ????public ?String?getValue()?{?? ????????return ?value;?? ????}?? ?? ????public ?void ?setValue(String?value)?{?? ????????this .value?=?value;?? ????}?? ?? ????public ?long ?getUnique()?{?? ????????return ?unique;?? ????}?? ?? ????public ?void ?setUnique(long ?unique)?{?? ????????this .unique?=?unique;?? ????}?? ?? }?? public class CacheItem {private String key;private String value;private long unique;public CacheItem() {super();}public CacheItem(String key, String value, long unique) {super();this.key = key;this.value = value;this.unique = unique;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}public long getUnique() {return unique;}public void setUnique(long unique) {this.unique = unique;}}
?
客戶端緩存服務實現 ?
Java代碼 ?
? ? ? ? ?? public ?class ?MemcachedClientJava?implements ?MemcachedClientService?{???? ????MemCachedClient?mmc?=?MemcachedClientFactory.getInstance();?? ????public ?boolean ?add(String?key,?String?value)?{?? ????????return ?mmc.add(key,?value);?? ????}?? ?? ????public ?boolean ?cas(String?key,?String?value,?long ?unique)?{?? ????????return ?mmc.cas(key,?value,?unique);?? ????}?? ?? ????public ?String?get(String?key)?{?? ????????return ?(String)?mmc.get(key);?? ????}?? ?? ????public ?CacheItem?gets(String?key)?{?? ????????MemcachedItem?item?=?mmc.gets(key);?? ????????return ?new ?CacheItem(key,?(String)?item.getValue(),?item.getCasUnique());?? ????}?? ?? ????public ?boolean ?set(String?key,?String?value)?{?? ????????return ?mmc.set(key,?value);?? ????}?? ?? ????public ?boolean ?delete(String?key)?{?? ????????return ?mmc.delete(key);?? ????}?? ?? ?? ????public ?boolean ?flushAll()?{?? ????????return ?mmc.flushAll();?? ????}?? ?????? }?? /*** Memcached for java客戶端緩存服務實現* @author zhangpu**/
public class MemcachedClientJava implements MemcachedClientService {MemCachedClient mmc = MemcachedClientFactory.getInstance();public boolean add(String key, String value) {return mmc.add(key, value);}public boolean cas(String key, String value, long unique) {return mmc.cas(key, value, unique);}public String get(String key) {return (String) mmc.get(key);}public CacheItem gets(String key) {MemcachedItem item = mmc.gets(key);return new CacheItem(key, (String) item.getValue(), item.getCasUnique());}public boolean set(String key, String value) {return mmc.set(key, value);}public boolean delete(String key) {return mmc.delete(key);}public boolean flushAll() {return mmc.flushAll();}}
?
獲取客戶端實例 Java代碼 ?
? ? ? ? ?? public ?class ?MemcachedClientFactory?extends ?ConfigurableConstants{???? ????private ?static ?volatile ?MemCachedClient?mmc;?? ?? ????static ?{?? ????????init("memcached-client.properties" );?? ?????????? ?????????? ????????String[]?servers?=?getProperty("memcached-servers" ,"" ).split("," );?? ?? ????????Integer[]?weights?=?null ;?? ????????String?weightsCfg?=?getProperty("memcached-weights" ,"" );?? ????????if (weightsCfg?!=?null ){?? ????????????String[]?wcfg?=?weightsCfg.split("," );?? ????????????weights?=?new ?Integer[wcfg.length];?? ????????????for ?(int ?i?=?0 ;?i?<?weights.length;?i++)?{?? ????????????????weights[i]?=?Integer.valueOf(wcfg[i]);?? ????????????}?? ????????}else {?? ????????????weights?=?new ?Integer[servers.length];?? ????????????for ?(int ?i?=?0 ;?i?<?weights.length;?i++)?{?? ????????????????weights[i]?=?1 ;?? ????????????}?? ????????}?? ?????????? ????????SockIOPool?pool?=?SockIOPool.getInstance();?? ?? ????????pool.setServers(servers);?? ????????pool.setWeights(weights);?? ????????pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);?? ?? ????????pool.setInitConn(getProperty("memcached-initConn" ,5 ));?? ????????pool.setMinConn(getProperty("memcached-minConn" ,5 ));?? ????????pool.setMaxConn(getProperty("memcached-maxConn" ,250 ));?? ????????pool.setMaxIdle(1000 ?*?60 ?*?60 ?*?6 );?? ?? ????????pool.setMaintSleep(30 );?? ?? ????????pool.setNagle(false );?? ????????pool.setSocketTO(3000 );?? ????????pool.setSocketConnectTO(0 );?? ?? ????????pool.initialize();?? ????}?? ?? ????private ?MemcachedClientFactory()?{?? ?? ????}?? ?? ????public ?static ?MemCachedClient?getInstance()?{?? ????????if ?(mmc?==?null )?{?? ????????????synchronized ?(MemCachedClient.class )?{?? ????????????????if ?(mmc?==?null )?{?? ????????????????????mmc?=?new ?MemCachedClient();?? ????????????????}?? ????????????}?? ????????}?? ????????return ?mmc;?? ????}?? ?? }?? /*** MemcachedClient 單例(JDK1.5以上)* @author zhangpu**/
public class MemcachedClientFactory extends ConfigurableConstants{private static volatile MemCachedClient mmc;static {init("memcached-client.properties");//{ "localhost:11211", "localhost:11212", "localhost:11213" };String[] servers = getProperty("memcached-servers","").split(",");Integer[] weights = null;String weightsCfg = getProperty("memcached-weights","");if(weightsCfg != null){String[] wcfg = weightsCfg.split(",");weights = new Integer[wcfg.length];for (int i = 0; i < weights.length; i++) {weights[i] = Integer.valueOf(wcfg[i]);}}else{weights = new Integer[servers.length];for (int i = 0; i < weights.length; i++) {weights[i] = 1;}}SockIOPool pool = SockIOPool.getInstance();pool.setServers(servers);pool.setWeights(weights);pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);pool.setInitConn(getProperty("memcached-initConn",5));pool.setMinConn(getProperty("memcached-minConn",5));pool.setMaxConn(getProperty("memcached-maxConn",250));pool.setMaxIdle(1000 * 60 * 60 * 6);pool.setMaintSleep(30);pool.setNagle(false);pool.setSocketTO(3000);pool.setSocketConnectTO(0);pool.initialize();}private MemcachedClientFactory() {}public static MemCachedClient getInstance() {if (mmc == null) {synchronized (MemCachedClient.class) {if (mmc == null) {mmc = new MemCachedClient();}}}return mmc;}}
?
參數配置 ?
Java代碼 ?
? ? ? ? ? ? ? ? ? ? ?? ?? public ?class ?ConfigurableConstants?{???? ??????protected ?static ?Log?logger?=?LogFactory.getLog(ConfigurableConstants.class );?? ?? ??????protected ?static ?Properties?p?=?new ?Properties();?? ?? ??? ?? ??????protected ?static ?void ?init(String?propertyFileName)?{?? ?? ??????????????InputStream?in?=?null ;?? ?? ??????????????try ?{?? ?? ?????????????????????in?=?ConfigurableConstants.class .getClassLoader().getResourceAsStream(propertyFileName);?? ?? ?????????????????????if ?(in?!=?null )?? ?? ?????????????????????????????p.load(in);?? ?? ??????????????}?catch ?(IOException?e)?{?? ?? ?????????????????????logger.error("load?" ?+?propertyFileName?+?"?into?Constants?error!" );?? ?? ??????????????}?finally ?{?? ?? ?????????????????????if ?(in?!=?null )?{?? ?? ?????????????????????????????try ?{?? ?? ????????????????????????????????????in.close();?? ?? ?????????????????????????????}?catch ?(IOException?e)?{?? ?? ????????????????????????????????????logger.error("close?" ?+?propertyFileName?+?"?error!" );?? ?? ?????????????????????????????}?? ?? ?????????????????????}?? ?? ??????????????}?? ?? ??????}?? ?? ??? ?? ??????protected ?static ?String?getProperty(String?key,?String?defaultValue)?{?? ?? ??????????????return ?p.getProperty(key,?defaultValue);?? ?? ??????}?? ?? ??? ?? ??????protected ?static ?int ?getProperty(String?key,?int ?defaultValue)?{?? ?? ??????????????try ?{?? ?? ?????????????????????return ?Integer.parseInt(getProperty(key,?"" ));?? ?? ??????????????}?catch ?(Exception?e)?{?? ?? ?????????????????????return ?defaultValue;?? ?? ??????????????}?? ?? ??? ?? ??????}?? ?? }?? /*** 通過 properties 文件配置設置常量基類 負責加載和讀取 properties 屬性文件并提供訪問的靜態工具方法** @author zhangpu**/public class ConfigurableConstants {protected static Log logger = LogFactory.getLog(ConfigurableConstants.class);protected static Properties p = new Properties();protected static void init(String propertyFileName) {InputStream in = null;try {in = ConfigurableConstants.class.getClassLoader().getResourceAsStream(propertyFileName);if (in != null)p.load(in);} catch (IOException e) {logger.error("load " + propertyFileName + " into Constants error!");} finally {if (in != null) {try {in.close();} catch (IOException e) {logger.error("close " + propertyFileName + " error!");}}}}protected static String getProperty(String key, String defaultValue) {return p.getProperty(key, defaultValue);}protected static int getProperty(String key, int defaultValue) {try {return Integer.parseInt(getProperty(key, ""));} catch (Exception e) {return defaultValue;}}}?
配置文件 memcached-client.properties
Properties代碼 ?
memcached-client.properties?? memcached-servers=localhost:11211 ,localhost:11212 ,localhost:11213 ?? memcached-weights=3 ,3 ,2 ?? memcached-initConn=5 ?? memcached-minConn=5 ?? memcached-maxConn=250 ?? memcached-client.properties
memcached-servers=localhost:11211,localhost:11212,localhost:11213
memcached-weights=3,3,2
memcached-initConn=5
memcached-minConn=5
memcached-maxConn=250
?
后續提供性能測試,spring整合,版本差異測試,及其它客戶端對比。
與50位技術專家面對面 20年技術見證,附贈技術全景圖
總結
以上是生活随笔 為你收集整理的Memcached学习笔记 — 第四部分:Memcached Java 客户端-gwhalin(1)-介绍及使用 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。