redis3.2后新增了一个bitfield命令,可以一次对多个位进行操作.这个指令有三个子指令,get,set,incrby,都可以对指定位片段进行读写,但最多只能处理64个连续的位,如超过64位,则要使用多个子指令,bitfield可以一次执行多个子指令.
127.0.0.1:6379> set w hello
OK
以上代码存储的位数据为:
字母 | 数值 | 二进制(高位<-低位) |
h | 104 | 0110 1000 |
e | 101 | 0110 0101 |
l | 108 | 0110 1100 |
l | 108 | 0110 1100 |
o | 111 | 0110 1111 |
127.0.0.1:6379> bitfield w get u4 0 #从w的第一个位开始取4个位(0110),结果为无符号数(u)
1) (integer) 6
127.0.0.1:6379> bitfield w get u3 2 #从w的第三个位开始取3个位(101),结果为无符号数(u)
1) (integer) 5
127.0.0.1:6379> bitfield w get i4 0 #从w的第一个位开始取4个位(0110),结果为有符号数(i)
1) (integer) 6
127.0.0.1:6379> bitfield w get i3 2 #从w的第三个位开始取3个位(101),结果为有符号数(i)
1) (integer) -3
从上可知,有符号数最多可以取64位,无符号数只能取63位.( redis 协议中的integer是有符号数,最大64位).
也可以一次执行多个子指令
127.0.0.1:6379> bitfield w get u4 0 get u3 2 get i4 0 get i3 2
1) (integer) 6
2) (integer) 5
3) (integer) 6
4) (integer) -3
也可以用set修改字符:
127.0.0.1:6379> bitfield w set u8 8 97 #从第9个位开始,将接下来8个位用无符号数97 ( 字母a) 替换
1) (integer) 101
127.0.0.1:6379> get w
"hallo"
incrby对指定范围的位进行自增操作,如操作后有数据溢出,redis的处理是折返,即将益处的符号位丢掉,比如:8位的无符号数255,加1后变为0,而8位的有符号数127,加1后成-128.
127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitfield w incrby u4 2 1 #从第3个位开始,对接下来的4位无符号数+1
1) (integer) 11
127.0.0.1:6379> bitfield w incrby u4 2 1
1) (integer) 12
127.0.0.1:6379> bitfield w incrby u4 2 1
1) (integer) 13
127.0.0.1:6379> bitfield w incrby u4 2 1
1) (integer) 14
127.0.0.1:6379> bitfield w incrby u4 2 1
1) (integer) 15
127.0.0.1:6379> bitfield w incrby u4 2 1 #溢出折返了
1) (integer) 0
也可以选择溢出行为,还可以选择 失败(fail,报错不执行), 折返( wrap ), 饱和截断(sat, 超过了范围就停留在最大或最小值).
127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (integer) 11
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (integer) 12
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (integer) 13
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (integer) 14
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (integer) 15
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1 #保持了最大值
1) (integer) 15
127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 11
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 12
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 13
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 14
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 15
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1 #失败不执行
1) (nil)