redis中keys和scan的区别
相同点:
都是用来返回key的,但是使用场景和方法不同。
一、 keys
KEYS pattern
示例:
keys *
keys user:*
缺点:
在redis拥有数百万及以上的keys的时候,如果数据量很大将会等待很久,会执行的比较慢,更为致命的是,这个命令会阻塞redis多路复用的io主线程,如果这个线程阻塞,在此执行之间其他的发送向redis服务端的命令,都会阻塞,从而引发一系列级联反应,导致瞬间响应卡顿,从而引发超时等问题,所以应该在生产环境禁止用使用keys和类似的命令smembers,这种时间复杂度为O(N),且会阻塞主线程的命令,是非常危险的。
因此,只适合用在可控的量小的键查询,比如几百,几千。
优点
一次返回,不会重复
二、scan
SCAN cursor [MATCH pattern] [COUNT count]
cursor:查询游标,第一次0,后面就是使用返回数组中第一个值,当返回的值为0时则表示遍历完毕。
MATCH pattern:匹配一个表达式,同上,选填。
[COUNT count]:指定每次迭代返回元素的最大值的一种提示(默认值为 10),但是在大多数情况下,
这种提示都是有效的,因此,返回的个数在count左右。
示例:
scan 0 MATCH user:* COUNT 5
1、随机性较高,没有规律。
2、唯一能判断遍历结束的标志就是返回结果集的第一个元素等于0就结束。
3、返回的列表存在重复的情况,需要应用程序自己处理。
4、返回的数量没有确定的数量
在数量未知或者数量较大的情况下使用scan遍历来获取所有的key
$cursor = 0;
$arr = [];
while(true){
$re = $redis->scan($cursor, 'user:*', 5);// 仅表示示例
if($re && is_array($re)){
if($re[2] && is_array($re[2])){
// 加入$arr
}
if($re[1] == 0){
break;
}else{
$cursor = $re[1];
}
} else{
break;
}
}
$arr = array_unique($arr);