Redis扫描跳过键

时间:2015-08-03 19:04:03

标签: php laravel redis predis

我正在使用predis(如果它有任何区别的laravel)php客户端与Redis一起使用。

我需要从Redis中获取匹配特定前缀的所有密钥,我这样做:

$keys = [];
    foreach (new Iterator\Keyspace($this->redis(), Cache::KEY_PREFIX.'*') as $key) {
        $keys[] = $rate_key;
    }

完成这些键的工作后,操作重复 - 我再次在循环中再次获取这些键。 我注意到经过几次迭代后,$ keys数组中没有包含一些键。

最奇怪的是,消失的键永远不会出现在下一次迭代中。重启php进程(它是一个守护进程)修复了这个问题。

我正在使用带有Predis 1.0和PHP 5.4的Redis 3.0.2

P.S。在循环键中,我更改了其中一些键的值。但是,我没有删除任何键。

1 个答案:

答案 0 :(得分:4)

事实上!那是因为SCAN以这种方式工作,引用Redis文档:

  

然而,虽然像SMEMBERS这样的阻止命令能够在给定时刻提供属于Set的所有元素,但 SCAN系列命令仅对返回的元素提供有限保证,因为该集合我们递增迭代可以在迭代过程中改变。

     

然而,因为SCAN几乎没有关联状态(只是光标),它有以下缺点:   可以多次返回给定元素。由应用程序来处理重复元素的情况,例如,仅使用返回的元素,以便在多次重新应用时执行安全的操作。

因此,您可能希望在<p></p>之后使用 array_unique($keys)

要理解为什么迭代以这种方式工作,最好的方法是阅读this part of the Redis documentation