java memcached incr_Redis与Memcached的incr/decr差异对比

目前广泛使用的分布式缓存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

2fe4218c9f2b1a47c2d319e72278809b.png

# Server

redis_version:3.1.999

93385013041f9e9465852b491d9206c0.png

从上述对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

3150b063fb7a19f6fe14373f155c00a9.png

看下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

66b5b211301cec6c9e8b248aea48dede.png

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

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

6830e947a6f9fe3cf80ba3bf1a32df0d.png

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

2c70eeaf0145f946f140eea98946dfe3.png

上面的测试是基于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命令设置初始值,过期时间。

fd37a80206837fb123e67efddfb4bb25.png

51bf5a310733aa90931d2ab14a0ebbb9.png

Memcached官方协议看这里 。

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值