介绍

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功能

官方示例代码

  1. import com.danga.MemCached.MemCachedClient;
  2. import com.danga.MemCached.SockIOPool;
  3. import com.schooner.MemCached.MemcachedItem;
  4. public class MemcachedForJavaExample {
  5. // create a static client as most installs only need
  6. // a single instance
  7. protected static MemCachedClient mcc = new MemCachedClient();
  8. // set up connection pool once at class load
  9. static {
  10. // server list and weights
  11. String[] servers = { "localhost:11211", "localhost:11212", "localhost:11213" };
  12. Integer[] weights = { , ,  };
  13. // grab an instance of our connection pool
  14. SockIOPool pool = SockIOPool.getInstance();
  15. // set the servers and the weights
  16. pool.setServers(servers);
  17. pool.setWeights(weights);
  18. pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);
  19. // set some basic pool settings
  20. // 5 initial, 5 min, and 250 max conns
  21. // and set the max idle time for a conn
  22. // to 6 hours
  23. pool.setInitConn();
  24. pool.setMinConn();
  25. pool.setMaxConn();
  26. pool.setMaxIdle( *  *  * );
  27. // set the sleep for the maint thread
  28. // it will wake up every x seconds and
  29. // maintain the pool size
  30. pool.setMaintSleep();
  31. // set some TCP settings
  32. // disable nagle
  33. // set the read timeout to 3 secs
  34. // and don't set a connect timeout
  35. pool.setNagle(false);
  36. pool.setSocketTO();
  37. pool.setSocketConnectTO();
  38. // initialize the connection pool
  39. pool.initialize();
  40. }
  41. public static void main(String[] args) {
  42. System.out.println("SET: " + mcc.set("key1", "value1"));
  43. System.out.println("SET: " + mcc.set("key2", "value2"));
  44. System.out.println("SET: " + mcc.set("key3", "value3"));
  45. System.out.println("GET: " + mcc.get("key1"));
  46. MemcachedItem item = mcc.gets("key1");
  47. System.out.println("GETS: value=" + item.getValue() + ",CasUnique:"+item.getCasUnique());
  48. System.out.println("SET: " + mcc.set("key1", "value1_1"));
  49. System.out.println("CAS: " + mcc.cas("key1", "value1_2", item.getCasUnique())); //必须FALSE
  50. System.out.println("getMulti:" + mcc.getMulti(new String[]{"key1","key2","key3"}));
  51. }
  52. }
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进行配置。

我的实现

业务层封装接口

  1. /**
  2. * Memcached 常用功能接口定义,用于业务层直接使用,屏蔽各种客户端实现的API差异,实现解耦客户端与业务系统的目的
  3. * 无过期时间和flags支持,无append,prepend,replace,incr,decr等操作
  4. *
  5. * @author zhangpu
  6. *
  7. */
  8. public interface MemcachedClientService {
  9. String get(String key);
  10. CacheItem gets(String key);
  11. boolean add(String key, String value);
  12. boolean set(String key, String value);
  13. boolean cas(String key, String value, long unique);
  14. boolean delete(String key)
  15. boolean flushAll();
  16. }
/**
 * 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();

}

  1. public class CacheItem {
  2. private String key;
  3. private String value;
  4. private long unique;
  5. public CacheItem() {
  6. super();
  7. }
  8. public CacheItem(String key, String value, long unique) {
  9. super();
  10. this.key = key;
  11. this.value = value;
  12. this.unique = unique;
  13. }
  14. public String getKey() {
  15. return key;
  16. }
  17. public void setKey(String key) {
  18. this.key = key;
  19. }
  20. public String getValue() {
  21. return value;
  22. }
  23. public void setValue(String value) {
  24. this.value = value;
  25. }
  26. public long getUnique() {
  27. return unique;
  28. }
  29. public void setUnique(long unique) {
  30. this.unique = unique;
  31. }
  32. }
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;
	}

}

客户端缓存服务实现

  1. /**
  2. * Memcached for java客户端缓存服务实现
  3. * @author zhangpu
  4. *
  5. */
  6. public class MemcachedClientJava implements MemcachedClientService {
  7. MemCachedClient mmc = MemcachedClientFactory.getInstance();
  8. public boolean add(String key, String value) {
  9. return mmc.add(key, value);
  10. }
  11. public boolean cas(String key, String value, long unique) {
  12. return mmc.cas(key, value, unique);
  13. }
  14. public String get(String key) {
  15. return (String) mmc.get(key);
  16. }
  17. public CacheItem gets(String key) {
  18. MemcachedItem item = mmc.gets(key);
  19. return new CacheItem(key, (String) item.getValue(), item.getCasUnique());
  20. }
  21. public boolean set(String key, String value) {
  22. return mmc.set(key, value);
  23. }
  24. public boolean delete(String key) {
  25. return mmc.delete(key);
  26. }
  27. public boolean flushAll() {
  28. return mmc.flushAll();
  29. }
  30. }
/**
 * 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();
	}

}

获取客户端实例

  1. /**
  2. * MemcachedClient 单例(JDK1.5以上)
  3. * @author zhangpu
  4. *
  5. */
  6. public class MemcachedClientFactory extends ConfigurableConstants{
  7. private static volatile MemCachedClient mmc;
  8. static {
  9. init("memcached-client.properties");
  10. //{ "localhost:11211", "localhost:11212", "localhost:11213" };
  11. String[] servers = getProperty("memcached-servers","").split(",");
  12. Integer[] weights = null;
  13. String weightsCfg = getProperty("memcached-weights","");
  14. if(weightsCfg != null){
  15. String[] wcfg = weightsCfg.split(",");
  16. weights = new Integer[wcfg.length];
  17. for (int i = ; i < weights.length; i++) {
  18. weights[i] = Integer.valueOf(wcfg[i]);
  19. }
  20. }else{
  21. weights = new Integer[servers.length];
  22. for (int i = ; i < weights.length; i++) {
  23. weights[i] = ;
  24. }
  25. }
  26. SockIOPool pool = SockIOPool.getInstance();
  27. pool.setServers(servers);
  28. pool.setWeights(weights);
  29. pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);
  30. pool.setInitConn(getProperty("memcached-initConn",));
  31. pool.setMinConn(getProperty("memcached-minConn",));
  32. pool.setMaxConn(getProperty("memcached-maxConn",));
  33. pool.setMaxIdle( *  *  * );
  34. pool.setMaintSleep();
  35. pool.setNagle(false);
  36. pool.setSocketTO();
  37. pool.setSocketConnectTO();
  38. pool.initialize();
  39. }
  40. private MemcachedClientFactory() {
  41. }
  42. public static MemCachedClient getInstance() {
  43. if (mmc == null) {
  44. synchronized (MemCachedClient.class) {
  45. if (mmc == null) {
  46. mmc = new MemCachedClient();
  47. }
  48. }
  49. }
  50. return mmc;
  51. }
  52. }
/**
 * 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;
	}

}

参数配置

  1. /**
  2. * 通过 properties 文件配置设置常量基类 负责加载和读取 properties 属性文件并提供访问的静态工具方法
  3. *
  4. * @author zhangpu
  5. *
  6. */
  7. public class ConfigurableConstants {
  8. protected static Log logger = LogFactory.getLog(ConfigurableConstants.class);
  9. protected static Properties p = new Properties();
  10. protected static void init(String propertyFileName) {
  11. InputStream in = null;
  12. try {
  13. in = ConfigurableConstants.class.getClassLoader().getResourceAsStream(propertyFileName);
  14. if (in != null)
  15. p.load(in);
  16. } catch (IOException e) {
  17. logger.error("load " + propertyFileName + " into Constants error!");
  18. } finally {
  19. if (in != null) {
  20. try {
  21. in.close();
  22. } catch (IOException e) {
  23. logger.error("close " + propertyFileName + " error!");
  24. }
  25. }
  26. }
  27. }
  28. protected static String getProperty(String key, String defaultValue) {
  29. return p.getProperty(key, defaultValue);
  30. }
  31. protected static int getProperty(String key, int defaultValue) {
  32. try {
  33. return Integer.parseInt(getProperty(key, ""));
  34. } catch (Exception e) {
  35. return defaultValue;
  36. }
  37. }
  38. }
/**

  * 通过 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

  1. memcached-client.properties
  2. memcached-servers=localhost:,localhost:,localhost:
  3. memcached-weights=,,
  4. memcached-initConn=
  5. memcached-minConn=
  6. 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)-介绍及使用的更多相关文章

  1. Java学习笔记(四)——google java编程风格指南(上)

    [前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...

  2. Java学习笔记十四:如何定义Java中的类以及使用对象的属性

    如何定义Java中的类以及使用对象的属性 一:类的重要性: 所有Java程序都以类class为组织单元: 二:什么是类: 类是模子,确定对象将会拥有的特征(属性)和行为(方法): 三:类的组成: 属性 ...

  3. 多线程学习笔记(四)---- Thread类的其他方法介绍

    一.wait和 sleep的区别 wait可以指定时间也可以不指定时间,而sleep必须指定时间: 在同步中时,对cpu的执行权和锁的处理不同: wait:释放执行权,释放锁:释放锁是为了别人noti ...

  4. Memcached 学习笔记(二)——ruby调用

    Memcached 学习笔记(二)——ruby调用 上一节我们讲述了怎样安装memcached及memcached常用命令.这一节我们将通过ruby来调用memcached相关操作. 第一步,安装ru ...

  5. memcached学习笔记——存储命令源码分析下篇

    上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制 ...

  6. memcached学习笔记——存储命令源码分析上篇

    原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...

  7. Java NIO 学习笔记(四)----文件通道和网络通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  8. Java超简明入门学习笔记(四)

    Java编程思想第4版学习笔记(四) 第六章 访问权限控制         访问权限控制是面向对象编程中的重要概念,它划分了类设计者和类使用者的界限.通过设置权限,它一方面告诉类设计者,哪个部分的修改 ...

  9. mybatis 学习笔记(四):mybatis 和 spring 的整合

    mybatis 学习笔记(四):mybatis 和 spring 的整合 尝试一下整合 mybatis 和 spring. 思路 spring通过单例方式管理SqlSessionFactory. sp ...

随机推荐

  1. Spark-SQL之DataFrame操作大全

    Spark SQL中的DataFrame类似于一张关系型数据表.在关系型数据库中对单表或进行的查询操作,在DataFrame中都可以通过调用其API接口来实现.可以参考,Scala提供的DataFra ...

  2. Android简易实战教程--第四十四话《ScrollView和HorizontalScrollView简单使用》

    一.ScrollView 由于手机屏幕的高度有限,当普通布局放不下现实和的内容时,ScrollView视图(滚动视图)就会派上用场,因为数据可以往下滚动显示. 二.HorizontalScrollVi ...

  3. EBS销售订单挑库发放处理程序

    来自:http://blog.csdn.net/cunxiyuan108/article/details/6014769 在EBS实施中,经常遇到从外部传进来一个被登记的销售订单,需要通过程序进行销售 ...

  4. SceneKit:简单的3D游戏场景搭建

    SceneKit是Apple用来开发休闲3D游戏的框架,不同于底层的OpenGL库,你仅仅需要很少的代码就可以快速看到实际的3D场景效果.下面简单的聊聊搭建一个3D游戏场景需要做的事情. 首先你必须用 ...

  5. JAVA面向对象-----面向对象(基础预备知识汇总)

    终于整理好了面向对象基础预备知识,但是有点多,所以你们懂的,贴图,较长的代码我还是会排版出来的,我不想把时间浪费在排版上在word里排版一次已经很浪费时间了,所以请谅解. public class C ...

  6. android view事件分发机制

    首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个MyButton继承Button,然后把跟事件传播有关的方法进行复写,然后添加上日志 ...

  7. 【Unity Shaders】Unity里的雾效模拟

    写在前面 熟悉Unity的都知道,Unity可以进行基本的雾效模拟.所谓雾效,就是在远离我们视角的方向上,物体看起来像被蒙上了某种颜色(通常是灰色).这种技术的实现实际上非常简单,就是根据物体距离摄像 ...

  8. android开发之this.finish()的使用

    在一个Activity用完之后应该将之finish掉,但是,之前在学校里自己摸索着开发时并没有太注意这个问题,因为activity无论是否finish掉对功能的影响貌似都不是那么明显(这是读书时候的观 ...

  9. 【java虚拟机系列】java中类与对象的加载顺序

    首先了解一下Java虚拟机初始化的原理. JVM通过加装.连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用.类型的生命周期如下图所示: 装载和连接必须在初始化之前就要完成. 类 ...

  10. Tapestry: Obtained resource by @Inject is NULL

    Issue: When you inject some resources by @Inject Annotation in Tapestry Page or other components, yo ...