简体   繁体   English

Redis扫描跳过键

[英]Redis scan skipping keys

I'm using predis (with laravel if it makes any difference) php client to work with Redis. 我正在使用predis(如果有任何区别,请与laravel一起使用)php客户端以与Redis一起使用。

I need to fetch all the keys from Redis that match certain prefix and I do it like this: 我需要从Redis获取与某些前缀匹配的所有键,我这样做是这样的:

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

After the work with those keys is done, operation repeats - I'm getting those keys again in again in a loop. 使用这些键完成工作后,操作将重复进行-我再次将这些键再次放入一个循环中。 I noticed that after a few iterations some keys are not included in $keys array. 我注意到经过几次迭代后,某些键未包含在$ keys数组中。

The strangest thing is that keys that disappear never appear in next iterations. 最奇怪的是消失的键永远不会出现在下一个迭代中。 Restart of the php process (it's a daemon) fixes the problem. 重新启动php进程(这是一个守护程序)可以解决此问题。

I'm using Redis 3.0.2 with Predis 1.0 and PHP 5.4 我正在将Redis 3.0.2与Predis 1.0和PHP 5.4一起使用

PS Within the loop over keys, I change values for some of them. PS在循环键中,我更改了其中一些的值。 I'm not deleting any keys, however. 但是,我没有删除任何键。

Indeed! 确实! That's because SCAN works that way, quoting from Redis documentation: 这是因为SCAN以这种方式工作,引用Redis文档:

However while blocking commands like SMEMBERS are able to provide all the elements that are part of a Set in a given moment, The SCAN family of commands only offer limited guarantees about the returned elements since the collection that we incrementally iterate can change during the iteration process. 但是,虽然像SMEMBERS这样的阻塞命令能够在给定的时间内提供Set中所有元素, 但是SCAN系列命令仅对返回的元素提供有限保证 ,因为我们递增迭代的集合可以在迭代过程中更改。

However because SCAN has very little state associated (just the cursor) it has the following drawbacks: A given element may be returned multiple times. 但是,由于SCAN具有很少的关联状态(仅是游标),因此具有以下缺点: 给定元素可能多次返回。 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. 由应用程序来处理重复元素的情况 ,例如仅使用返回的元素来执行在多次重新应用时安全的操作。

So you may want to use want to use array_unique($keys) after the foreach . 因此,您可能要在foreach之后使用想要使用array_unique($ keys)的方法。

To understand why the iteration works that way the best thing is to read this part of the Redis documentation . 要了解为什么迭代如此工作,最好的方法是阅读Redis文档的这一部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM