目前广泛使用的分布式缓存Redis和Memcached均支持对整数型Value值的增减,对应到具体命令中就是incr和decr命令。

incr/decr是原子性操作(memcached 1.2.4及以后版本加入/redis),其被广泛应用于计数器和限速器。

一、分布式缓存Redis和Memcached在这两个命令的具体语法上的不同

Redis的incr命令语法分两种:

1)incr key,即将指定主键key的value值加一;

2)incrby key increment,即将指定主键key的value值加上increment。

Redis的decr命令语法同样分为两种:

1)decr key,即将指定主键key的value值减一;

2)decrby key decrement,即将指定主键key的value值减去decrement。

Memcached的incr命令语法

1)incr key integer,即将指定主键key的value值加上给定的integer,

2)decr命令语法为decr key interger,即将指定主键key的value值减去给定的interger。

二、分布式缓存Redis和Memcached支持的整型数值的不同

Redis支持的整数型Value值的具体类型为字符串(十进制)表示的带符号64-bit整数,

Memcached支持的整数型Value值的具体类型为字符串(十进制)表示的无符号64-bit整数,

这就导致两个系统支持的整数型Value值的取值范围是不一样的。Redis支持的整数型Value值范围是-9223372036854775808~9223372036854775807,而Memcached的范围则是0~18446744073709551615。

1、key内存储的字符串被解释为十进制

    #Server

    Memcached_version: 1.2.6

# Server
redis_version:3.1.999

从上述对Memcached和Redis的实验可以看到,对incr命令保存为字符串。

2、Redis带符号64-bit整数,Memcached无符号64-bit整数

1)先为一个key max赋一个带符号64-bit整数最大值9223372036854775807;
redis 127.0.0.1:6379> set max 9223372036854775807
OK
2)将该主键的值加一,系统提示此加一动作会导致向上溢出,由此可见Redis支持的最大整数型Value值确实为9223372036854775807;
redis 127.0.0.1:6379> incr max
(error) ERR increment or decrement would overflow
3)再为一个key min赋一个带符号64-bit整数最小值-9223372036854775808;
redis 127.0.0.1:6379> set min -9223372036854775808
OK
4)将该主键的值减一,系统提示此减一操作会导致向下溢出,由此可见Redis支持的最小整数型Value值确实为-9223372036854775808;
redis 127.0.0.1:6379> decr min
(error) ERR increment or decrement would overflow

看下Memcached情况又会如何

1)先为一个key max赋一个无符号64-bit整数最大值 18446744073709551615;
set max 0 0 20
18446744073709551615
STORED
2)将该主键的值加一,系统的执行结果为0,即系统自身会自动避免向上溢出,由此可见Memcached支持的最大整数型Value值确实应该为18446744073709551615;
incr max 1
CLIENT_ERROR cannot increment or decrement non-numeric value 
 
疑问:递增1后问什么没有溢出,反而提示了 “对非数字的缓存操作才会返回的错误信息”
 
3)再为一个key min赋一个无符号64-bit整数最小值0;
set min 0 0 1
0
STORED
4)将该主键的值减一,系统的执行结果还是0,即系统自身会自动避免向下溢出,由此可见Memcached支持的最小整数型Value值确实应该为0;
decr min 1
0

三、分布式缓存Redis和Memcached,incr/decr的差异                                    

     1、Redis如果对应的key不存在,incr/decr不会失败,而会从0开始计数

          

      2、Memcached如果对应值不存在,incr/decr会失败,而不会从0开始计数

   上面的测试是基于Memcached 文本协议的做法。因为文本协议不允许incr 设置不存在的key。

        如xmemcached中,memcachedClient.incr("a",5,1),memcachedClient.incr("a",5)

incr和decr都有三个参数的方法,第一个参数指定递增的key名称,第二个参数指定递增的幅度大小,第三个参数指定当key不存在的情况下的初始值。
        两个参数的重载方法省略了第三个参数,默认指定为0。

3、incr/decr操作无法刷新过期时间

Redis,我们知道set、getset命令为键值赋值同时会消除键值的生存时间、persist命令把一个设置过过期时间的键取消过期时间设置,如果需要可以重新使用expire命令为键设置生存时间。而其他对键的操作命令(如incr、lpush、hset、zrem)都不会影响键的生存时间。

Memcached,incr/decr操作无法刷新过期时间,所以过期时间以初始化的时间为准。

因此,如果使用memcached作为长期的计数器,必须用额外的机制定时刷新item。memcached协议提供了touch方法,只刷新时间,不对值作修改。

    如果是二进制协议,则可以直接用incr命令设置初始值,过期时间。

Memcached官方协议看这里 。

参考:http://blog.sina.com.cn/s/blog_48c95a190101772i.html

由于本人经验有限,文章中难免会有错误,请浏览文章的您指正或有不同的观点共同探讨!

最新文章

  1. WinForm------GridControl单元格内容修改外表样式
  2. Power of Four
  3. 构件图(Component Diagram)—UML图(八)
  4. vmware克隆Centos6.7虚拟机网卡无法启动问题
  5. ArrayList排序算法的源码
  6. ZOJ-2965
  7. java操作properties配置文件
  8. day23.面向对象之继承
  9. Go-day01
  10. 《深入浅出 Java Concurrency》目录
  11. Java 雇员管理小练习(理解面向对象编程)
  12. JQuery监听页面滚动总结
  13. hasattr getattr setattr delattr --> (反射)
  14. APP发行渠道
  15. 进程 day36
  16. PowerDesigner的Name和Code不同步设置
  17. 将一个byte[]数组根据大小拆分为若干小byte[]数组方法
  18. document.body、document.documentElement和window获取视窗大小的差别
  19. node 应用集合
  20. SpringCloud学习(3)——Eureka服务注册中心及服务发现

热门文章

  1. eclipse导出Runnable Jar File在Launch Configuration中找不到类
  2. oracle 查看隐含参数脚本
  3. hdu 2680 Choose the best route
  4. Android Service学习之本地服务
  5. 3.Knockout.Js(属性绑定)
  6. java中直接打印对象
  7. JAVA内部类(转)
  8. STL之multimap
  9. Java通过反射机制修改类中的私有属性的值
  10. Spring集成hibernate错误