3

I'm replacing KEYS with SCAN using phpredis.

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
$it = NULL;
while($arr_keys = $redis->scan($it, "mykey:*", 10000)) {
    foreach($arr_keys as $str_key) {
        echo "Here is a key: $str_key\n";
    }
}

According to redis documentation, I use SCAN to paginate searches to avoid disadvantage of using KEYS.
But in practice, using above code costs me 3 times lower than using just a single $redis->keys()
So I'm wondering if I've done something wrong, or I have to pay speed to avoid KEYS's threat?

Note that I totally have 400K+ keys in my db, and 4 mykey:* keys

4

2 回答 2

5

由于keys在生产环境中使用是被禁止的,因为它在迭代全局空间键时会阻塞整个服务器,因此,这里没有讨论使用或不使用keys.

另一方面,如果你想加快速度,你应该使用 Redis 更进一步:你应该索引你的数据。

我怀疑这些 400K 密钥不能归类为集合或排序集合,甚至是散列,因此当您需要 400K-keys-database 的特定子集时,您可以scan对一组 1K 项运行任何 -equivalent 命令,而不是400K。

Redis 是关于索引数据的。如果没有,您就像使用一个简单的键值存储一样使用它。

于 2016-08-11T10:36:38.773 回答
5

使用示例的注意事项:

$it = NULL;
while($arr_keys = $redis->scan($it, "mykey:*", 10000)) {
    foreach($arr_keys as $str_key) {
        echo "Here is a key: $str_key\n";
    }
}

如果扫描的 10000 个键中没有一个匹配,那么它会返回空数组,然后它会放弃,并且你没有得到你想要的所有键!我建议做更多这样的事情:

$it = null;
do
{
    $arr_keys = $redis->scan($it, $key, 10000);
    if (is_array($arr_keys) && !empty($arr_keys))
    {
        foreach ($arr_keys as $str_key)
        {
            echo "Here is a key: $str_key\n";
        }
    }
} while ($arr_keys !== false);

以及为什么要花这么长时间,400k+ 个键,10000 个,这就是对 redis 的 40 个扫描请求,如果它不在本地机器上,每 40 个 redis 查询的延迟就会增加你的速度。

于 2018-11-15T09:47:30.917 回答