在 Redis 2.8 之前,我们只能使用 keys 命令来查询我们想要的数据,但这个命令存在两个缺点:
然而,比较幸运的是在 Redis 2.8 时推出了 Scan,解决了我们这些问题,下面来看 Scan 的具体使用。
官方对 Scan 命令的描述信息如下。
The SCAN command, and the other commands in the SCAN family, are able to provide to the user a set of guarantees associated to full iterations.
- A full iteration always retrieves all the elements that were present in the collection from the start to the end of a full iteration. This means that if a given element is inside the collection when an iteration is started, and is still there when an iteration terminates, then at some point SCANreturned it to the user.
- A full iteration never returns any element that was NOT present in the collection from the start to the end of a full iteration. So if an element was removed before the start of an iteration, and is never added back to the collection for all the time an iteration lasts, SCAN ensures that this element will never be returned.
However because SCAN has very little state associated (just the cursor) it has the following drawbacks:
- A given element may be returned multiple times. It is up to the application to handle the case of duplicated elements, for example only using the returned elements in order to perform operations that are safe when re-applied multiple times.
- Elements that were not constantly present in the collection during a full iteration, may be returned or not: it is undefined.
官方文档地址:
https://redis.io/commands/scan
翻译为中文的含义是:Scan 及它的相关命令可以保证以下查询规则。
然后,Scan 命令包含以下缺点:
我们先来看看scan的基本语法:
scan cursor [MATCH pattern] [COUNT count]
接下来我们使用scan命令进行查询;
EVAL "for i=1,100000 do redis.call(‘set‘,string.format(KEYS[1],i),string.format(ARGV[1],i)) end" 1 user_token_%d id_%d
127.0.0.1:6379> scan 0 match user_token_1111* count 10000
1) "64408"
2) 1) "user_token_11117"
127.0.0.1:6379> scan 64408 match user_token_1111* count 10000
1) "70348"
2) 1) "user_token_11116"
2) "user_token_11119"
127.0.0.1:6379> scan 70348 match user_token_1111* count 10000
1) "15154"
2) 1) "user_token_11111"
127.0.0.1:6379> scan 15154 match user_token_1111* count 10000
1) "109670"
2) 1) "user_token_1111"
127.0.0.1:6379> scan 109670 match user_token_1111* count 10000
1) "34814"
2) 1) "user_token_11112"
127.0.0.1:6379> scan 34814 match user_token_1111* count 10000
1) "63129"
2) 1) "user_token_11113"
127.0.0.1:6379> scan 63129 match user_token_1111* count 10000
1) "31949"
2) 1) "user_token_11118"
127.0.0.1:6379> scan 31949 match user_token_1111* count 10000
1) "50995"
2) (empty array)
127.0.0.1:6379> scan 50995 match user_token_1111* count 10000
1) "106087"
2) 1) "user_token_11114"
127.0.0.1:6379> scan 106087 match user_token_1111* count 10000
1) "0"
2) 1) "user_token_11110"
2) "user_token_11115"
从以上的执行结果,我们看出两个问题:
Scan 是一个系列指令,除了 Scan 之外,还有以下 3 个命令:
来看这些命令的具体使用。
基本语法:
hscan key cursor [MATCH pattern] [COUNT count]
127.0.0.1:6379> hscan myhash 0 match k2* count 10
1) "0"
2) 1) "k2"
2) "v2"
基本语法:
sscan key cursor [MATCH pattern] [COUNT count]
127.0.0.1:6379> sscan myset 0 match v2* count 20
1) "0"
2) 1) "v2"
基本语法:
zscan key cursor [MATCH pattern] [COUNT count]
127.0.0.1:6379> zscan zset 0 match red* count 20
1) "0"
2) 1) "redis"
2) "10"
通过本文我们可以知道 Scan 包含以下四个指令:
Scan 具备以下几个特点:
原文:https://www.cnblogs.com/JerryQTQcjl/p/14205835.html