Skip to content

scan

Bash
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type] -> [cursor, Array[string]]

有一系列 SCAN 相关的命令用于增量迭代元素:

  • SCAN: 迭代当前 Redis 数据库中的键
  • SSCAN: 迭代Set中的成员
  • HSCAN: 迭代 Hash 中的键值对
  • ZSCAN: 迭代 Sorted Set 中的成员和相关分数

由于他们都是增量迭代,这避免了 KEYS 或 SMEMBERS 等命令的缺点(占用内存、阻塞服务器等)。然而阻塞服务器也保证了他们返回的值是当前数据库的所有元素,而 SCAN 系列命令对返回的元素提供有限的保证,因为在迭代过程中数据可能会发生变化。因此如果需要根据实际情况来抉择。

基本使用

SCAN 类方法都是基于游标的迭代器,每次调用该命令,服务器都会返回一个更新的游标,用户需要在下次调用时传入该游标。对于首次开启迭代需要手动传入 0 作为游标,知道服务器重新返回 0 作为游标来表示整个迭代完成:

Bash
redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
   10) "key:7"
   11) "key:1"
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

一些需要注意的点

游标的合法值只有下面两种情况,任何其他无效的游标值不会导致崩溃但是无法在保证返回值的关联性:

  • 开始迭代时的游标值 0
  • 上次调用 SCAN 返回的游标值

可以使用 * ? 这样的通配符来进行模糊搜索匹配到的成员

数据返回并不严格遵循 COUNT 指定的选项,甚至可能返回空数组。但是只要返回的游标不为 0 就表示迭代没有完成

参考