Memcached学习笔记 — 第四部分:Memcached Java 客户端-gwhalin(1)-介绍及使用
介绍
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功能
官方示例代码
- 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 instance
- protected static MemCachedClient mcc = new MemCachedClient();
- // set up connection pool once at class load
- static {
- // server list and weights
- String[] servers = { "localhost:11211", "localhost:11212", "localhost:11213" };
- Integer[] weights = { , , };
- // grab an instance of our connection pool
- SockIOPool pool = SockIOPool.getInstance();
- // set the servers and the weights
- pool.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 hours
- pool.setInitConn();
- pool.setMinConn();
- pool.setMaxConn();
- pool.setMaxIdle( * * * );
- // set the sleep for the maint thread
- // it will wake up every x seconds and
- // maintain the pool size
- pool.setMaintSleep();
- // set some TCP settings
- // disable nagle
- // set the read timeout to 3 secs
- // and don't set a connect timeout
- pool.setNagle(false);
- pool.setSocketTO();
- pool.setSocketConnectTO();
- // initialize the connection pool
- 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())); //必须FALSE
- 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 instance
protected static MemCachedClient mcc = new MemCachedClient();
// set up connection pool once at class load
static {
// server list and weights
String[] servers = { "localhost:11211", "localhost:11212", "localhost:11213" };
Integer[] weights = { 3, 3, 2 };
// grab an instance of our connection pool
SockIOPool pool = SockIOPool.getInstance();
// set the servers and the weights
pool.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 hours
pool.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 size
pool.setMaintSleep(30);
// set some TCP settings
// disable nagle
// set the read timeout to 3 secs
// and don't set a connect timeout
pool.setNagle(false);
pool.setSocketTO(3000);
pool.setSocketConnectTO(0);
// initialize the connection pool
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())); //必须FALSE
System.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进行配置。
我的实现
业务层封装接口
- /**
- * 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();
- }
/**
* 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();
}
- 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;
}
}
客户端缓存服务实现
- /**
- * 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();
- }
- }
/**
* 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();
}
}
获取客户端实例
- /**
- * 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 = ; i < weights.length; i++) {
- weights[i] = Integer.valueOf(wcfg[i]);
- }
- }else{
- weights = new Integer[servers.length];
- for (int i = ; i < weights.length; i++) {
- weights[i] = ;
- }
- }
- SockIOPool pool = SockIOPool.getInstance();
- pool.setServers(servers);
- pool.setWeights(weights);
- pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);
- pool.setInitConn(getProperty("memcached-initConn",));
- pool.setMinConn(getProperty("memcached-minConn",));
- pool.setMaxConn(getProperty("memcached-maxConn",));
- pool.setMaxIdle( * * * );
- pool.setMaintSleep();
- pool.setNagle(false);
- pool.setSocketTO();
- pool.setSocketConnectTO();
- 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;
}
}
参数配置
- /**
- * 通过 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;
- }
- }
- }
/**
* 通过 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
- memcached-client.properties
- memcached-servers=localhost:,localhost:,localhost:
- memcached-weights=,,
- memcached-initConn=
- memcached-minConn=
- memcached-maxConn=
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整合,版本差异测试,及其它客户端对比。
Memcached学习笔记 — 第四部分:Memcached Java 客户端-gwhalin(1)-介绍及使用的更多相关文章
- Java学习笔记(四)——google java编程风格指南(上)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
- Java学习笔记十四:如何定义Java中的类以及使用对象的属性
如何定义Java中的类以及使用对象的属性 一:类的重要性: 所有Java程序都以类class为组织单元: 二:什么是类: 类是模子,确定对象将会拥有的特征(属性)和行为(方法): 三:类的组成: 属性 ...
- 多线程学习笔记(四)---- Thread类的其他方法介绍
一.wait和 sleep的区别 wait可以指定时间也可以不指定时间,而sleep必须指定时间: 在同步中时,对cpu的执行权和锁的处理不同: wait:释放执行权,释放锁:释放锁是为了别人noti ...
- Memcached 学习笔记(二)——ruby调用
Memcached 学习笔记(二)——ruby调用 上一节我们讲述了怎样安装memcached及memcached常用命令.这一节我们将通过ruby来调用memcached相关操作. 第一步,安装ru ...
- memcached学习笔记——存储命令源码分析下篇
上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制 ...
- memcached学习笔记——存储命令源码分析上篇
原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...
- Java NIO 学习笔记(四)----文件通道和网络通道
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- Java超简明入门学习笔记(四)
Java编程思想第4版学习笔记(四) 第六章 访问权限控制 访问权限控制是面向对象编程中的重要概念,它划分了类设计者和类使用者的界限.通过设置权限,它一方面告诉类设计者,哪个部分的修改 ...
- mybatis 学习笔记(四):mybatis 和 spring 的整合
mybatis 学习笔记(四):mybatis 和 spring 的整合 尝试一下整合 mybatis 和 spring. 思路 spring通过单例方式管理SqlSessionFactory. sp ...
随机推荐
- Scala:函数式编程之下划线underscore
http://blog.csdn.net/pipisorry/article/details/52913548 python参考[python函数式编程:apply, map, lambda和偏函数] ...
- python数据挖掘orange
http://blog.csdn.net/pipisorry/article/details/52845804 orange的安装 linux下的安装 先安装依赖pyqt4[PyQt教程 - pyth ...
- Android线性布局
线性布局 LinearLayout 是一个视图组,用于使所有子视图在单个方向(垂直或水平)保持对齐. 您可以使用 android:orientation 属性指定布局方向. LinearLayout ...
- WmS详解(一)之token到底是什么?基于Android7.0源码
做Android有些年头了,Framework层三大核心View系统,WmS.AmS最近在研究中,这三大块,每一块都够写一个小册子来介绍,其中View系统的介绍,我之前有一个系列的博客(不过由于时间原 ...
- 类型转换异常处理java.lang.RuntimeException
前几天在做一个安卓项目的时候一直报java.lang.RuntimeException错,一直调试不出来,今天突然又灵感是不是文件配置出错了,果然在清单文件中少了一句 android:name=&qu ...
- JSP简单隔行变色和日期格式化
以前好像在找,都没找到简单点的,所以后面就自己写了一个,感觉超级简单又好理解,分享给大家 <%@ page language="java" import="java ...
- 后端分布式系列:分布式存储-MySQL 数据库事务与复制
好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适.最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类.结合实际工作中碰到的问题,以寻找答案的方式来剖 ...
- Linux内核编译时会遇到的问题--缺少mkimage
由于各大平台所带的内核不同,所以编译方式也不同,但方法都是大同小异. 但是,编译内核有时候会提示缺少mkimage这个命令,如何解决? 供应商提供内核的同时也会提供其它的一些,比如Uboot,root ...
- JAVA之旅(二十八)——File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤
JAVA之旅(二十八)--File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤 我们可以继续了,今天说下File 一.File概述 文件的操作是非常 ...
- Java EE 之 过滤器入门学习与总结(1)
使用Filter技术来配合开发会使得开发变得简单起来.简单的一个例子就表现在"乱码问题"上.不使用Filter的话,我们有可能需要为每一个网页设置字符编码集,如request.se ...