提示:有关于XMemcached在实际开发中的具体使用,查看"Java企业项目开发实践"系列博客的《第八章 企业项目开发--分布式缓存memcached

注意:本文主要参考自https://code.google.com/p/xmemcached/wiki/User_Guide_zh

1、为什么选用Xmemcached客户端

当下常用的三种memcached Java客户端:

  • Memcached Client for Java:memcached官方提供,基于Java BIO实现
  • SpyMemcached:基于Java NIO
  • XMemcached:基于Java NIO,并发性能优于XMemcached,实际上SpyMemcached性能也很高

三者的实验比较结果:

http://xmemcached.googlecode.com/svn/trunk/benchmark/benchmark.html

所以,我们选用XMemcached来实现客户端的编写。

2、XMemcached的主要特性

  • 高性能(参照上一部分)
  • 支持客户端分布(查看文章开头链接的文章中的代码:根pom.xml+MemcachedUtil类的静态块)
  • 允许设置节点权重(XMemcached允许通过设置节点的权重来调节memcached的负载,设置的权重越高,该memcached节点存储的数据将越多,所承受的负载越大)
  • 动态增删节点(JMX或zookeeper)
  • 客户端连接池
    • 默认为1,在开发中直接使用默认值即可
    • 若要配置多个连接的连接池,需要保证:数据之间是相互独立的或者全部采用CAS更新来保证原子性。
    • 在开发中,发现配置了多个连接后,会发生死锁现象(可能是我的使用方法不对),使用多客户端也是不错的选择,且并发处理的也很好。(具体实现方式查看文章开头链接的文章)

3、使用

具体的实际使用查看文章头部的链接。

3.1、常用类介绍

说明:

  • XMemcachedClientBuilder:XMemcachedClient的构建器,通过该构建器可以配置一系列参数,常用的参数有:

    • hash算法:setSessionLocator

      • 简单求余法(默认):ArrayMemcachedSessionLocator
      • 一致性hash:KetamaMemcachedSessionLocator(true)
        • 注意:这里我配置了一个true,该参数cwNginxUpstreamConsistent用于兼容nginx-upstream-consistent,如果系统用了nginx,最好配成true
    • 序列化协议:setCommandFactory
      • 文本协议(默认):TextCommandFactory,实现了memcached的自定义文本协议
      • 二进制协议:BinaryCommandFactory,减少了文本解析的步骤,有一些方法仅支持二进制协议
    • 序列化转化器:setTranscoder(下面是序列化转换器SerializingTranscoder的一些配置参数)
      • 压缩边界值:setCompressionThreshold,默认为16k,实际使用中根据自己的数据大小来指定,我们指定为1M
      • 压缩算法:setCompressionMode,默认为GZIP,还有一种是ZIP,使用默认值就会
    • 池数量:setConnectionPoolSize,默认为1,实际中采用多客户端的方式可以代替多连接
    • failure模式:setFailureMode(true):设置为true后,当一个memcached节点down掉后,发往该节点的请求将发往备份机,若没有备份机,直接抛出异常,而不会像之前那样,把请求打向下一个节点
    • standby:主从配置
      /*
      * 下面这样是配置主从
      * 其中localhost:11211是主1,localhost:11212是他的从
      * host2:11211是主2,host2:11212是他的从
      *
      * 注意:使用主从配置的前提是builder.setFailureMode(true)
      */
      MemcachedClientBuilder builder =
      new XMemcachedClientBuilder(AddrUtil.getAddressMap("localhost:11211,localhost:11212 host2:11211,host2:11212")); builder.setFailureMode(true);//设置failure模式

其中,两种hash算法的实现与比较、两种序列化的实现与比较、池化的注意点查看《第六章 memcached剖析

  • XMemcachedCient:所有缓存的具体操作(add/set/replace/remove/get等)都在这里
    • SanitizeKeys:当选用URL当key时,MemcachedClient会自动将URL encode后再存储,该参数默认是关闭的,若要开启,如下:

      client.setSanitizeKeys(true);//URL做key

3.2、注意点

  • 多服务器之间必须用空格隔开,用逗号不行。原因参看XMemcached转换多服务器字符串的AddrUtil.getAddress(String s)方法源代码:

         /**
    * 该方法用于将传入的"host1:port1 host2:port2 ..."
    * 这些众多的服务器转换为一个InetSocketAddress集合
    */
    public static List<InetSocketAddress> getAddresses(String s) {
    if (s == null) {
    throw new NullPointerException("Null host list");
    }
    if (s.trim().equals("")) {
    throw new IllegalArgumentException("No hosts in list: ``" + s
    + "''");
    }
    s = s.trim();
    ArrayList<InetSocketAddress> addrs = new ArrayList<InetSocketAddress>(); for (String hoststuff : s.split(" ")) {//这里就是多服务器为什么要用空格隔开的理由
    int finalColon = hoststuff.lastIndexOf(':');
    if (finalColon < 1) {
    throw new IllegalArgumentException("Invalid server ``"
    + hoststuff + "'' in list: " + s); }
    String hostPart = hoststuff.substring(0, finalColon).trim();
    String portNum = hoststuff.substring(finalColon + 1).trim(); addrs
    .add(new InetSocketAddress(hostPart, Integer
    .parseInt(portNum)));
    }
    assert !addrs.isEmpty() : "No addrs found";
    return addrs;
    }
  • 缓存过期参数设置:在API的使用中,有一个缓存过期参数的设置:缓存单位是s,缓存时间最长为1个月(此时参数设为0),所以一定要注意这个时间的设置
  • 等待超时时间:XMemcached是基于Java NIO(yanf4j框架)的,客户端与服务端的通讯本身是异步的,所以MemcachedClient向memcached服务器发送一个请求后,不知道什么时候memcached服务器才能把应答返回,所以在一些需要返回应答的API中我们可以指定超时时间,客户端在这个时间内会一直等待应答,若超出这个时间,就认为操作失败了,抛出TimeoutException,当然若在这些需要返回应答的API中没有指定等待超时时间,则默认的等待超时时间是5秒。
        /**
    * Default operation timeout,if the operation is not returned in 5
    * second,throw TimeoutException.
    */
    public static final long DEFAULT_OP_TIMEOUT = 5000L;
  • 更新缓存过期参数:XMemcached1.3.6之前,若要更新缓存超时时间,需要先缓存缓存,再设置缓存(get-set),两次操作+反序列化/序列化+网络传输,造成开销很大。1.3.6之后,
    public boolean touch(final String key, int exp)

    速度极快。若希望获取缓存并更新缓存过期时间,该方法应该是只有二进制协议支持。

    public <T> T getAndTouch(final String key, int newExp)
  • 增加缓存
    • add:key若已存在,添加缓存失败
    • replace:key若不存在,更换缓存失败
    • set:key不管存在不存在,都成功
  • 缓存缓存所有的key:没有好方法。getKeyIterator接口将会在1.6.x以后取消
  • 命名空间:1.4.2之后,可以将一组缓存项放到同一个命名空间下,如果有这样的需求,我们直接使用redis去做了

疑问:

standby主从模式,当主宕机后,set和get都会从从上边操作;那么,当主没有宕机,set操作是否会同时set到主和从呢?

第七章 Xmemcached客户端介绍的更多相关文章

  1. 第七章 : Git 介绍 (上)[Learn Android Studio 汉化教程]

    Learn Android Studio 汉化教程 [翻译]Git介绍 Git版本控制系统(VCS)快速成为Android应用程序开发以及常规的软件编程领域内的事实标准.有别于需要中心服务器支持的早期 ...

  2. Laxcus大数据管理系统2.0(9)- 第七章 分布任务组件

    第七章 分布任务组件 Laxcus 2.0版本的分布任务组件,是在1.x版本的基础上,重新整合中间件和分布计算技术,按照新增加的功能,设计的一套新的.分布状态下运行的数据计算组件和数据构建组件,以及依 ...

  3. (转)iOS Wow体验 - 第七章 - 操作图例与触屏人机工学

    本文是<iOS Wow Factor:Apps and UX Design Techniques for iPhone and iPad>第七章译文精选,其余章节将陆续放出.上一篇:Wow ...

  4. ROS机器人程序设计(原书第2版)补充资料 (柒) 第七章 3D建模与仿真 urdf Gazebo V-Rep Webots Morse

    ROS机器人程序设计(原书第2版)补充资料 (柒) 第七章 3D建模与仿真 urdf Gazebo V-Rep Webots Morse 书中,大部分出现hydro的地方,直接替换为indigo或ja ...

  5. <自动化测试方案_7>第七章、PC端UI自动化测试

    第七章.PC端UI自动化测试 UI自动化测试又分为:Web自动化测试,App自动化测试.微信小程序.微信公众号UI层的自动化测试工具非常多,比较主流的是UFT(QTP),Robot Framework ...

  6. 精通Web Analytics 2.0 (9) 第七章:失败更快:爆发测试与实验的能量

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第七章:失败更快:爆发测试与实验的能量 欢迎来到实验和测试这个棒极了的世界! 如果Web拥有一个超越所有其他渠道的巨大优势,它就 ...

  7. 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7  标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...

  8. Getting Started With Hazelcast 读书笔记(第七章)

    第七章 部署策略 Hazelcast具有适应性,能根据不同的架构和应用进行特定的部署配置,每个应用可以根据具体情况选择最优的配置: 数据与应用紧密结合的模式(重点,of就是这种) 胖客户端模式(最好用 ...

  9. apue第七章学习总结

    apue第七章学习总结 1.main函数 程序是如何执行有关的c程序的? C程序总是从main函数开始执行.main函数的原型是 int main(int argc,char *argv[]); 其中 ...

随机推荐

  1. MongoDB入门教程一[文档与集合]

    MongoDB 是面向集合存储的文档型数据库,其涉及到的基本概念与关系型数据库相比有所不同.举个例子,在关系型数据库中,我们记录一个订单的信息,通常是这样设计表结构的: 设计一个订单基本信息表和一个订 ...

  2. modCount干嘛的

    在ArrayList.LinkedList.HashMap等等的内部增删改中我们总能看到modCount的身影,modCount字面意思就是修改次数,但为什么要记录modCount的修改次数呢? 大家 ...

  3. 洛谷P4623 [COCI2012-2013#6] BUREK [模拟]

    题目传送门 BUREK 格式难调,题面就不放了. 分析: 一道比较有思维难度的模拟题. 首先我们可以想到,对于一个三角形,可以画出一个最小矩形使得这个三角形被完全包围,并且这个矩形的边平行于坐标轴(图 ...

  4. Netty堆外内存泄露排查与总结

    导读 Netty 是一个异步事件驱动的网络通信层框架,用于快速开发高可用高性能的服务端网络框架与客户端程序,它极大地简化了 TCP 和 UDP 套接字服务器等网络编程. Netty 底层基于 JDK ...

  5. windows下thrift的使用(python)

    1.下载thrift,下载地址:http://archive.apache.org/dist/thrift/0.9.3/ 2.在编写python的thrift代码时,需要先安装thrift modul ...

  6. django定时任务

    1.celery流程图: Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成 2.使用 ...

  7. Git 入门使用

    Git是什么? Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制 ...

  8. [CodeChef-QTREE]Queries on tree again!

    题目大意: 给定一个环长为奇数的带权基环树,支持以下两种操作: 1.两点间最短路取反: 2.两点间最短路求最大子段和. 思路: 首先找出环,然后对每一个外向树轻重链剖分, 用线段树维护每一个区间的和. ...

  9. [SimpleOJ229]隧道

    题目大意: 有10个格子,初始状态a和b分别在5和6上. 现在有n个任务,每个任务都有特定的位置. 在每个单位时间,a和b可以分别进行以下事件中的任意一件: 1.向左(右)移动一个格子: 2.锁定在当 ...

  10. px em rem 字体单位问题

    px:相对长度单位,相对于屏幕分辨率 em:相对长度单位,相对于body而言 rem:相对长度单位,相对于html根元素 注意:浏览器默认大小:16px;