分布式架构——第6篇:memcache API与分布式缓存

memcache客户端与服务端通过构建在TCP协议之上的memcache协议来通信。官方提供了Memcached-Java-Client工具,包含了对memcache协议的Java封装。与ZooKeeper的zkClient第三方工具类似,请参考《分布式架构——第3篇:ZooKeeper第三方客户端工具包zkClient》,我们首先需要生成memcached.jar包。

memcache 初始化

通过SockIOPool,可以设置与后端缓存服务器的一系列参数,如服务器地址、是否采用容错、初始连接数、最大连接数、最小连接数、线程睡眠时间、是否使用Nagle算法、socket的读取等待超时、是否心跳检测以及Hash算法,等等。
e.g.

public static void main(String[] args) {
String[] servers = {
"192.168.1.102:11211"
};
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(servers);
pool.setFailover(true);
pool.setInitConn(10);
pool.setMinConn(5);
pool.setMaxConn(25);
pool.setMaintSleep(30);
pool.setNagle(false);
pool.setSocketTO(3000);
pool.setAliveCheck(true);
pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);
pool.initialize();
}

memcache API

memcache协议支持通过如下几种方式来读、写、失效数据。

  • set
    如果set的key已经存在,该命令可以更新该key所对应的原来的数据,也就是实现更新的作用。
  • add
    如果 add 的 key 已经存在,则不会更新数据,之前的值将仍然保持相同,并且您将获得响应 NOT_STORED。
  • replace
    如果 key 不存在,则替换失败,并且您将获得响应 NOT_STORED。
    e.g.

    MemCachedClient mcc = new MemCachedClient();
    mcc.add("hello", 1);
    mcc.set("hello", 2);
    mcc.replace("hello", 3);
    Object value = mcc.get("hello");
    System.out.println(value);//3
  • append
    用于向已存在 key(键) 的 value(数据值) 后面追加数据 。

  • prepend
    用于向已存在 key(键) 的 value(数据值) 前面追加数据 。
    e.g.

    mcc.set("str", "BYTE");
    mcc.prepend("str", "Hello");
    mcc.append("str", "PARALLEL");
    value = mcc.get("str");
    System.out.println(value);//HelloBYTEPARALLEL
  • get
    获取存储在 key(键) 中的 value(数据值) ,如果 key 不存在,则返回空。

  • gets
    获取带有 CAS 令牌存 的 value(数据值) ,如果 key 不存在,则返回空。

  • cas
    用于执行一个”检查并设置”的操作。它仅在当前客户端最后一次取值后,该key 对应的值没有被其他客户端修改的情况下,才能够将值写入。检查是通过cas_token参数进行的, 这个参数是Memcach指定给已经存在的元素的一个唯一的64位值。要在 Memcached 上使用 CAS 命令,你需要从 Memcached 服务商通过 gets 命令获取令牌(token)。gets 命令的功能类似于基本的 get 命令。两个命令之间的差异在于,gets 返回的信息稍微多一些:64 位的整型值非常像名称/值对的 “版本” 标识符。
    e.g.

    mcc.set("atom", 1);
    MemcachedItem item = mcc.gets("atom");
    mcc.cas("atom", (Integer)item.getValue()+1, item.getCasUnique());
    value = mcc.get("atom");
    System.out.println(value);//2
  • incr、decr
    incr 与 decr 命令用于对已存在的 key(键) 的数字值进行自增或自减操作。
    特别注意: 值必须设置为字符串(如"100"),不然会出错。

    mcc.add("cr", "100");

    默认自增1

    mcc.incr("cr");
    value = mcc.get("cr");
    System.out.println(value);//101

    这里,自减10试试。

    mcc.decr("cr", 10);
    value = mcc.get("cr");
    System.out.println(value);//91

References:
[1] https://github.com/gwhalin/Memcached-Java-Client
[2] https://www.w3cschool.cn/memcached/
[3] 大型分布式网站架构设计与实践.陈康贤著