Redis(PHP-Redis)SCAN和KEYS以相同的模式显示不同的结果

时间:2018-04-05 10:47:27

标签: redis glob phpredis

我正在使用Redis版本3.1.6的PHP-Redis

$result = $redis->keys('source_1234_[a-zA-Z]*_[0-9]*');

产生

{array} [6]
 0 = "source_1234_test_1"
 1 = "source_1234_test_2"
 2 = "source_1234_test_3"
 3 = "source_1234_test_4"
 4 = "source_1234_test_5"
 5 = "source_1234_test_6"

然而

$iterator = 0;
$result = $redis->scan($iterator, 'source_1234_[a-zA-Z]*_[0-9]*');

返回

FALSE

我正在阅读KEYSSCAN的文档,但所有它都支持全球模式。

所以检查http://www.globtester.com/我可以确认该模式是有效的,并且应该返回正确的结果。为什么会出现差异?为什么SCAN在这种情况下会返回FALSE?

3 个答案:

答案 0 :(得分:2)

您的代码有两个问题:

(a)您需要将迭代器设置为NULL,而不是0

来自0的呼叫返回

SCAN,表示已扫描所有密钥。因此,它将停止并返回false

(b)SCAN迭代所有键的集合,返回每个调用的每个集合的匹配。您只需拨打一次扫描。它将扫描第一个COUNT密钥,如果没有匹配,则返回false。

请参阅https://redis.io/commands/scan#number-of-elements-returned-at-every-scan-call

  

SCAN系列函数不保证每次调用返回的元素数量在给定范围内。这些命令也允许返回零元素,只要返回的游标不为零,客户端就不应该认为迭代完成。[...]

要获得与KEYS相同的结果,您需要迭代所有键集:

$iterator = NULL
while($iterator != 0) {
    $arr_keys = $redis->scan($iterator, 'source_1234_[a-zA-Z]*_[0-9]*')
    foreach($arr_keys as $str_key) {
        echo $str_key;
    }
}

答案 1 :(得分:1)

因为我一直在寻找这个,所以我发布了对我有用的

$iterator = null;
while(false !== ($keys = $redis->scan($iterator, $pattern))) {
    foreach($keys as $key) {
        echo $key . PHP_EOL;
      }
 }

我是从scan的{​​{1}}的文档中摘录的。 这应该打印出与php-redis相匹配的每个键。

答案 2 :(得分:0)

尝试类似的事情:

$redisClient = new Redis();
$redisClient->connect($config['devices']['redis_ip']);
$redisClient->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
$start_time = microtime(TRUE);
$it = NULL;
while ($keys = $redisClient->scan($it, "useragent:*")) {
    foreach ($keys as $key){
        // Do something with the key
        usleep(1000);
    }
}
$end_time = microtime(TRUE);
$time = $end_time - $start_time;
echo "\t[done]: Total time: {$time} seconds\n";
$redisClient->close();