目录
SCAN 介绍
SCAN 命令基本用法
MATCH 选项用法
COUNT 选项用法
TYPE 选项用法
补充
并发执行多个迭代
中途停止迭代
使用错误的游标进行增量式迭代
迭代终结的保证
SCAN cursor [MATCH pattern] [COUNT count][TYPE type]:SCAN 命令及其相关的 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都用于增量地迭代(incrementally iterate)一集元素(a collection of elements)
增量式迭代命令:
以上命令每次执行均返回少量元素,而不像keys或smembers命令被用于处理大量数据是极有可能导致阻塞服务器。
SCAN 0:SCAN 命令是一个基于游标的迭代器: SCAN 命令每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程
127.0.0.1:6379> mset a 1 b 1 c 1 d 1 e 1 f 1 g 1 h 1 i 1 j 1 k 1 l 1 m 1 n 1 o 1 p 1 q 1 r 1 s 1 t 1 u 1 v 1 w 1 x 1 y 1 z 1 # 初始化键值对
OK
127.0.0.1:6379> scan 0
1) "1" # 返回下次换代的新游标
2) 1) "b"
2) "t"
3) "m"
4) "q"
5) "e"
6) "u"
7) "g"
8) "w"
9) "h"
10) "s"
127.0.0.1:6379> scan 1
1) "27" # 返回下次换代的新游标
2) 1) "z"
2) "c"
4) "l"
5) "y"
6) "d"
7) "a"
8) "i"
9) "k"
10) "o"
127.0.0.1:6379> scan 27
1) "0" # 返回0表示迭代结束
2) 1) "v"
3) "x"
4) "j"
5) "p"
6) "f"
7) "n"
8) "r"
返回:
SCAN cursor MATCH pattern:通过提供一个 glob 风格的模式参数, 让命令只返回和给定模式相匹配的元素, 这一点可以通过在执行增量式迭代命令时, 通过给定 MATCH
127.0.0.1:6379> mset a00 1 a001 1 a002 1 a003 1 a014 1 a015 1 a016 1
OK
127.0.0.1:6379> keys *
1) "a001"
2) "a01"
3) "a003"
4) "a014"
5) "a016"
6) "a015"
7) "a002"
8) "a00"
127.0.0.1:6379> scan 0 match *01 # 匹配01结尾的key
1) "0"
2) 1) "a001"
2) "a01"
127.0.0.1:6379> scan 0 match a01* # 匹配a01开头的key
1) "0"
2) 1) "a016"
2) "a015"
3) "a01"
4) "a014"
说明:
SCAN cursor COUNT count:增量式迭代命令不保证每次迭代所返回的元素数量, 但我们可以使用 COUNT 选项, 对命令的行为进行一定程度上的调整
127.0.0.1:6379> mset a0111 1 a0121 1 a0031 1 a0041 1 a0051 1 a0061 1 a0071 1 a0081 1 a0011 1 a0101 1 a0111 1 a0121 1 a0131 1
OK
127.0.0.1:6379> mset a001 1 a002 1 a003 1 a004 1 a005 1 a006 1 a007 1 a008 1 a001 1 a010 1 a011 1 a012 1 a013 1
OK
127.0.0.1:6379> scan 0 count 5
1) "4"
2) 1) "a005"
2) "a0041"
3) "a0121"
4) "a0031"
5) "a004"
127.0.0.1:6379> scan 0 count 5
1) "6"
2) 1) "a22" # count 5 返回了5个
2) "a016"
3) "a25"
4) "a26"
5) "a015"
127.0.0.1:6379> scan 0 count 8
1) "9"
2) 1) "a22" # count 8 返回了10个
2) "a016"
3) "a25"
4) "a26"
5) "a015"
6) "a21"
7) "a001"
8) "a01"
9) "a003"
10) "a014"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> mset a001 1 a002 1 a003 1 a004 1 a005 1 a006 1 a007 1 a008 1 a001 1 a010 1 a011 1 a012 1 a013 1
127.0.0.1:6379> mset a0111 1 a0121 1 a0031 1 a0041 1 a0051 1 a0061 1 a0071 1 a0081 1 a0011 1 a0101 1 a0111 1 a0121 1 a0131 1
127.0.0.1:6379> scan 0 count 8
1) "2"
2) 1) "a005" # 无似count 8限制,返回了10个
2) "a0041"
3) "a0121"
4) "a0031"
5) "a004"
6) "a013"
7) "a0011"
8) "a0081"
9) "a012"
10) "a0061"
SCAN cursor TYPE type:type选择保证每次迭代输出均为指定的数据类型
127.0.0.1:6379> get a005
"1"
127.0.0.1:6379> type a005
string
127.0.0.1:6379> scan 0 type string
1) "2"
2) 1) "a005"
2) "a0041"
3) "a0121"
4) "a0031"
5) "a004"
6) "a013"
7) "a012"
8) "a0081"
9) "a0011"
10) "a0061"
127.0.0.1:6379> scan 2 type string
1) "9"
2) 1) "a0101"
2) "a010"
3) "a008"
4) "a007"
5) "a0111"
6) "a006"
7) "a0071"
8) "a001"
9) "a003"
在同一时间, 可以有任意多个客户端对同一数据集进行迭代, 客户端每次执行迭代都需要传入一个游标, 并在迭代执行之后获得一个新的游标, 而这个游标就包含了迭代的所有状态, 因此, 服务器无须为迭代记录任何状态。
因为迭代的所有状态都保存在游标里面, 而服务器无须为迭代保存任何状态, 所以客户端可以在中途停止一个迭代, 而无须对服务器进行任何通知。
即使有任意数量的迭代在中途停止, 也不会产生任何问题。
使用间断的(broken)、负数、超出范围或者其他非正常的游标来执行增量式迭代并不会造成服务器崩溃, 但可能会让命令产生未定义的行为。
未定义行为指的是, 增量式命令对返回值所做的保证可能会不再为真。
只有两种游标是合法的:
增量式迭代命令所使用的算法只保证在数据集的大小有界(bounded)的情况下, 迭代才会停止, 换句话说, 如果被迭代数据集的大小不断地增长的话, 增量式迭代命令可能永远也无法完成一次完整迭代。
从直觉上可以看出, 当一个数据集不断地变大时, 想要访问这个数据集中的所有元素就需要做越来越多的工作, 能否结束一个迭代取决于用户执行迭代的速度是否比数据集增长的速度更快。
时间复杂度:增量式迭代命令每次执行的复杂度为 O(1) , 对数据集进行一次完整迭代的复杂度为 O(N) , 其中 N 为数据集中的元素数量。
返回值: