我正在使用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:*
密钥
答案 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查询增加延迟以提高速度。