使用phpredis扫描命令性能

时间:2016-08-11 09:27:57

标签: redis phpredis

我正在使用phpredis用SCAN替换KEYS。

$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";
    }
}

根据redis documentation,我使用SCAN对搜索进行分页以避免使用KEYS的缺点。
但在实践中,使用上面的代码比仅使用一个$redis->keys()成本低3倍 所以我想知道我做错了什么,或者我必须付出速度来避免KEYS的威胁?

请注意,我的数据库中有400K +密钥,还有4个mykey:*密钥

2 个答案:

答案 0 :(得分:5)

由于在生产环境中使用(select-keys* m [:a :b [:c :d]]) 是禁止的,因为它在迭代全局空间键时会阻塞整个服务器,因此,此处不讨论是否使用keys

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

我怀疑这些400K密钥无法按集或有序集,甚至哈希进行分类,因此当您需要400K密钥数据库的特定子集时,您可以运行任何keys - 对一组1K项目的等效命令,而不是400K。

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

答案 1 :(得分:1)

使用示例时要小心:

$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查询增加延迟以提高速度。

相关问题