BITFIELD
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> ...]]
- 可用时间
- 3.2.0
- 时间复杂度
- 每个指定的子命令为 O(1)
- ACL 类别
-
@write
,@bitmap
,@slow
,
该命令将 Redis 字符串视为一个位数组,并且能够寻址不同位宽和任意非(必要)对齐偏移的特定整型字段。实际上使用该命令,您可以设置例如位偏移量为 1234 的一个有符号 5 位整型为特定值,从偏移量 4567 获取一个 31 位无符号整型。类似地,该命令处理指定整型的增量和减量,提供用户可以配置的保证和良好定义的溢出和下溢行为。
BITFIELD
能够在同一命令调用中操作多个位字段。它接受一个要执行的操作列表,并返回一个回复数组,其中每个数组与操作列表中的对应操作匹配。
例如,以下命令将位偏移量为 100 的有符号 5 位整型增量 1,并获取位偏移量为 0 的无符号 4 位整型的值
> BITFIELD mykey INCRBY i5 100 1 GET u4 0
1) (integer) 1
2) (integer) 0
注意
- 使用
GET
寻址当前字符串长度之外的位(包括键根本不存在的情况),操作将像所有缺失部分都包含设置为 0 的位一样执行。 - 使用
SET
或INCRBY
寻址当前字符串长度之外的位将扩大字符串,根据触碰的最远位,按需用零填充。
支持的子命令和整型编码
以下是支持的命令列表。
- GET
<encoding>
<offset>
-- 返回指定的位字段。 - SET
<encoding>
<offset>
<value>
-- 设置指定的位字段并返回其旧值。 - INCRBY
<encoding>
<offset>
<increment>
-- 增加或减少(如果给定负增量)指定的位字段并返回新值。
还有一个子命令仅通过设置连续 INCRBY
和 SET
子命令调用的行为来更改溢出行为
- OVERFLOW
[WRAP|SAT|FAIL]
在需要整型编码的地方,它可以通过在有符号整型前面加上 i
,在无符号整型前面加上 u
以及我们的整型编码的位数来组成。例如,u8
是一个 8 位无符号整型,i16
是一个 16 位有符号整型。
支持的编码对于有符号整型最多 64 位,对于无符号整型最多 63 位。无符号整型的这个限制是由于目前 Redis 协议无法将 64 位无符号整型作为回复返回。
位和位置偏移量
在 bitfield 命令中指定偏移量有两种方法。如果指定一个没有前缀的数字,它将被用作字符串内部的基于零的位偏移量。
但是,如果偏移量以 #
字符为前缀,则指定的偏移量将乘以整型编码的宽度,因此例如
BITFIELD mystring SET i8 #0 100 SET i8 #1 200
将设置偏移量为 0 的第一个 i8 整型和偏移量为 8 的第二个整型。这样,如果要的是给定大小的整型数组,就不必在客户端自己进行计算。
溢出控制
使用 OVERFLOW
命令,用户可以通过指定以下行为之一来微调增量或减量溢出(或下溢)的行为
- WRAP: 循环绕回,适用于有符号和无符号整数。对于无符号整数,循环绕回就像对整数可容纳的最大值执行模运算(C 标准行为)。对于有符号整数,循环绕回意味着溢出将从最负值重新开始,而下溢将从最正值重新开始。例如,如果将一个
i8
整数设置为 127,则将其增加 1 将产生-128
。 - SAT: 使用饱和运算,即在下溢时将值设置为最小整数值,在上溢时将值设置为最大整数值。例如,将一个
i8
整数从 120 开始,每次增加 10,将得到值 127,而进一步的增加将始终保持值为 127。下溢也是如此,但值会被阻塞在最负值。 - FAIL: 在此模式下,对检测到的溢出或下溢不执行任何操作。相应的返回值将设置为 NULL 以向调用者发出信号。
请注意,每个 OVERFLOW
语句只影响列表中该语句后面的 INCRBY
和 SET
命令,直到下一个 OVERFLOW
语句。
默认情况下,如果未另行指定,则使用 WRAP。
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 1
2) (integer) 1
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 2
2) (integer) 2
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 3
2) (integer) 3
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 0
2) (integer) 3
以下是一个 OVERFLOW FAIL
返回 NULL 的示例。
> BITFIELD mykey OVERFLOW FAIL incrby u2 102 1
1) (nil)
动机
此命令的动机是能够将许多小整数存储为单个大的位图(或在几个键上进行分段,以避免出现巨大的键)非常节省内存,并为 Redis 打开了新的应用场景,特别是在实时分析领域。这些用例得到了在受控方式下指定溢出的能力的支持。
趣事:Reddit 2017 年的愚人节项目 r/place 是 使用 Redis BITFIELD 命令构建的,以便为协作画布提供一个内存中的表示。
性能注意事项
通常,BITFIELD
是一个快速命令,但请注意,对当前较短字符串的远位进行寻址将触发一个分配,该分配可能比在已存在的位上执行命令成本更高。
位的顺序
BITFIELD
使用的表示方式将位图视为位号从 0 开始,0 是第一个字节的最高有效位,依此类推。因此,例如,将一个 5 位无符号整数设置为 23,偏移量为 7,放入一个以前设置为全零的位图中,将产生以下表示
+--------+--------+
|00000001|01110000|
+--------+--------+
当偏移量和整数大小与字节边界对齐时,这与大端序相同,但是当这种对齐不存在时,了解字节内的位是如何排序的也很重要。
RESP2 响应
以下之一
RESP3 响应
以下之一