php - Redis 扫描跳过键

标签 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 进程(它是守护进程)可以解决问题。

我将 Redis 3.0.2 与 Predis 1.0 和 PHP 5.4 一起使用

附言在键的循环中,我更改了其中一些键的值。但是,我不会删除任何 key 。

最佳答案

确实如此!那是因为 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.

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.

所以你可能想用想用 array_unique($keys) foreach 之后。

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

关于php - Redis 扫描跳过键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31794866/

相关文章:

php - 从谷歌地图 url ftid(十六进制)获取纬度/经度

jquery - 如何在导航项上添加 bootstrap 4 事件类?

laravel - 在Laravel中启用Whoops错误控制台

php - Dropzone 在后端 Laravel 中没有有效的 MIME 类型?

c# - 在 Redis 中存储和使用配置文件的最佳方式?

php - Doctrine2 与 MS Server 分页和排序在 ZF2 下不工作

javascript - 使用 Javascript 循环将 PHP 数据发送到 Modal

javascript - 如何通过函数更新全局变量

php - 如何根据php中的键添加数组的总和值

django - 修复 Celery 问题 'can' t pickle <class 'module' > : attribute lookup module on builtins failed