摘要
Bitfield 核心详解
• BITFIELD 是 Redis 用于把一个 字符串值视为一个由二进制“位数组”组成的存储区,并对其中任意指定位置的整数域进行读取、写入、自增等操作的命令。
• 这些整数域可以是任意位宽(例如 1 位、4 位、8 位、31 位、63 位等),可指定为有符号(signed)或无符号(unsigned)。
Bitfield 命令
1. BITFIELD 批量操作
• BITFIELD 命令支持在一次调用中执行多个操作,并将结果按操作顺序返回。
1 2 3 4 5
| BITFIELD key [GET encoding offset | [OVERFLOW <WRAP | SAT | FAIL>] <SET encoding offset value | INCRBY encoding offset increment> [GET encoding offset | [OVERFLOW <WRAP | SAT | FAIL>] <SET encoding offset value | INCRBY encoding offset increment> ...]]
|
• 参数说明(核心部分)
| 参数 |
含义 |
| key |
操作的 Redis 字符串键 |
| GET encoding offset |
从指定位偏移量读取一个整数 |
| SET encoding offset value |
在指定位置写入整数 |
| INCRBY encoding offset increment |
在指定位置对整数做增量操作 |
| OVERFLOW WRAP/SAT/FAIL |
配置随后的算数操作溢出行为 |
• 数据类型(encoding):用于指定整数的位宽和符号类型
| 前缀 |
含义 |
示例 |
u<number> |
无符号整数(unsigned),占位 bits = number |
u5 — 5 位无符号整数 |
i<number> |
有符号整数(signed),占位 bits = number |
i10 — 10 位有符号整数 |
• 溢出(OVERFLOW):默认算数操作中可能发生溢出,OVERFLOW 允许你控制处理策略。注意,这部分必须在后续的 SET/INCRBY 操作之前指定。
| 策略 |
行为 |
| WRAP |
环绕(默认)溢出按环形计数处理 |
| SAT |
饱和,在边界值保持最大/最小 |
| FAIL |
溢出时操作失败并返回错误 |
1 2
| BITFIELD key OVERFLOW SAT INCRBY u4 0 1
|
• 返回值: BITFIELD 会为每个子命令返回一个整数数组,数组各元素按操作顺序对应执行结果
1 2 3 4
| BITFIELD mykey INCRBY i5 100 1 GET u4 0
1) (integer) 1 2) (integer) 0
|
2. BITFIELD_RO 批量只读
1
| BITFIELD_RO key [GET encoding offset [GET encoding offset ...]]
|
综合示例
示例 1. 设置并读取简单整数
1 2 3 4 5 6 7 8 9 10 11
| > SET mykey ""
> BITFIELD mykey SET u4 0 7 GET u4 0
1) (integer) 0 2) (integer) 7
> BITFIELD mykey SET i4 0 -2 GET i4 0 1) (integer) 7 2) (integer) -2
|
负数的二进制表示
- 以 -2 为例,先写出 +2 的二进制,以8位为例,就是
00000010,4位就是 0010
- 按位取反(得到反码),例如
00000010,按位取反就是 11111101
- 加 1(得到补码),
11111101 + 1,得到 11111110,这就是 -2 的二进制表示
- 如果是4位,则 -2 就是
1110
示例 2. 自增计数器
1 2 3 4 5 6 7
|
BITFIELD counter INCRBY u8 8 5 GET u8 8
1) (integer) 5 2) (integer) 5
|
示例 3. 带溢出控制的操作
1 2 3 4 5 6 7
|
BITFIELD limits OVERFLOW SAT INCRBY u4 0 20 GET u4 0
1) (integer) 15 2) (integer) 15
|
示例 4. 批量多个操作
1 2 3 4 5 6 7 8 9
|
BITFIELD events GET u4 0 GET u4 4 SET u4 8 3 INCRBY i5 16 1
1) (integer) 0 2) (integer) 0 3) (integer) 0 4) (integer) 1
|
SpringBoot 操作 BitField
注意这里一定要用 StringRedisTemplate 来操作 BitField
| 方法功能 |
方法 |
Redis 原始命令 |
备注 |
| 位字段操作(读/写/自增) |
bitField(K key, BitFieldSubCommands subCommands) |
BITFIELD key ... |
原子执行多个子命令 |
1 2 3 4 5
| BITFIELD limits OVERFLOW SAT SET u4 0 3 INCRBY u4 0 20 GET u4 0
|
1 2 3 4 5 6 7 8 9
| BitFieldSubCommands.BitFieldSet bitFieldSet = BitFieldSubCommands.BitFieldSet.create(BitFieldSubCommands.BitFieldType.unsigned(4), BitFieldSubCommands.Offset.offset(0), 3);
BitFieldSubCommands.BitFieldIncrBy bitFieldIncrBy = BitFieldSubCommands.BitFieldIncrBy.create(BitFieldSubCommands.BitFieldType.unsigned(4), BitFieldSubCommands.Offset.offset(0), 20, BitFieldSubCommands.BitFieldIncrBy.Overflow.SAT);
BitFieldSubCommands.BitFieldGet bitFieldGet = BitFieldSubCommands.BitFieldGet.create(BitFieldSubCommands.BitFieldType.unsigned(4), BitFieldSubCommands.Offset.offset(0));
List<Long> limits = redisTemplate.opsForValue().bitField("limits", BitFieldSubCommands.create(bitFieldSet, bitFieldIncrBy, bitFieldGet));
|