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

注意

  1. 使用 GET 寻址当前字符串长度之外的位(包括键根本不存在的情况),操作将像所有缺失部分都包含设置为 0 的位一样执行。
  2. 使用 SETINCRBY 寻址当前字符串长度之外的位将扩大字符串,根据触碰的最远位,按需用零填充。

支持的子命令和整型编码

以下是支持的命令列表。

  • GET <encoding> <offset> -- 返回指定的位字段。
  • SET <encoding> <offset> <value> -- 设置指定的位字段并返回其旧值。
  • INCRBY <encoding> <offset> <increment> -- 增加或减少(如果给定负增量)指定的位字段并返回新值。

还有一个子命令仅通过设置连续 INCRBYSET 子命令调用的行为来更改溢出行为

  • 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 语句只影响列表中该语句后面的 INCRBYSET 命令,直到下一个 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 响应

以下之一

  • 数组响应:每个条目都是对应于在相同位置给出的子命令的结果。
  • 空响应:如果给出了 OVERFLOW FAIL 并且检测到溢出或下溢。

RESP3 响应

以下之一

  • 数组响应:每个条目都是对应于在相同位置给出的子命令的结果。
  • 空响应:如果给出了 OVERFLOW FAIL 并且检测到溢出或下溢。

RATE THIS PAGE
Back to top ↑