文章目录
- 1. Scan 命令的基本用法
- 1.1 Scan 命令的输入值
- 1.2 Scan 命令的返回值
- 2. Scan 命令与 Keys 命令比较
- 2.1 Keys 命令的缺点
- 2.2 Scan 命令的优点
- 3. Scan 命令的限制
- 3.1 有限保证原则
- 3.2 返回的结果有可能会重复
1. Scan 命令的基本用法
Scan
命令是一个基于游标的迭代器:Scan
命令每次被调用之后,都会向用户返回一个新的游标,用户在下次迭代时需要使用这个新游标作为 Scan
命令的游标参数,以此来延续之前的迭代过程。
当 Scan 命令的游标参数被设置为 0 时,服务器将开始一次新的迭代,而当服务器向用户返回值为 0 的 游标时,表示迭代已经结束。
1.1 Scan 命令的输入值
Scan
命令的语法为:
SCAN cursor [MATCH pattern] [COUNT count] (The default COUNT value is 10)
举例:当需要查找以 keyA
开头的 key
值时,可以使用如下命令进行开始:
SCAN 0 match keyA* count 20
注意,上面的 0
代表第一次遍历,20
是限定服务器单次遍历的字典槽位数量。
1.2 Scan 命令的返回值
Scan
命令的返回值是一个包含两个元素的数组,第一个数组元素是用于下一次迭代的新游标,而第二个数组元素则是一个数组,这个数组中包含了所有被迭代的元素。
以 0 作为游标开始一次新的迭代,一直调用 Scan 命令,直到命令返回游标 0,这个过程称之为一次完整遍历。
2. Scan 命令与 Keys 命令比较
2.1 Keys 命令的缺点
- 没有限制返回结果的参数。由于
Keys
命令只能一次性获取所有符合匹配规则的key
,所以没办法限制返回的结果数量。 keys
命令是遍历来实现的,时间复杂度是O(N)
。
所以结合以上两个缺点,再加上 Redis
是 单线程
的这个性质,在结果集数量非常大时,会造成 Redis
进程被阻塞,导致 Redis 服务卡顿。
2.2 Scan 命令的优点
Scan
命令提供了limit
参数, 可以限制返回的结果数量。Scan
命令时间复杂度也为O(N)
,但是它是分次进行的,即不会阻塞进程。
所以结合以上两个优点, Scan
命令不会导致 Redis
服务卡顿。
3. Scan 命令的限制
3.1 有限保证原则
Scan
命令可以保证:
从完整遍历开始直到完整遍历结束期间,一直存在于数据集内的所有元素都会被完整遍历返回,但是同一个元素可能会被返回多次。如果一个元素是在遍历过程中被添加到数据集或者从数据集中被删除,那么这个元素可能被返回,也可能不被返回。
3.2 返回的结果有可能会重复
Scan
命令每次返回的结果有可能会重复,所以要在应用层进行去重处理。