高性能用法之 Redis SCAN命令
Redis SCAN 命令
redis的扫描方法,使用scan,而不是使用 keys*
因为keys* 会全部key扫描一次,key数量很多时,容易造成阻塞太久甚至down机。
Redis Scan 命令用于迭代数据库中的数据库键。
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。
SCAN 返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标, 而第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。如果新游标返回 0 表示迭代已结束。
/**
* 查找redis key
* @param string|null $pattern // 要匹配的规则 'test_*'
* @param int $count // 每次遍历数量.count越大总耗时越短,但单次阻塞越长。 建议5000-10000。并发不高则可以调至接近1w。
* @return array
*/
function redisScan(string $pattern = '', int $count = 6000): array
{
$keyArr = array();
while (true){
// $iterator 下条数据的坐标
$key = env('redis.prefix', '') . $pattern;
Log::debug($key);
$data = Cache::store('redis')->handler()->scan($iterator, env('redis.prefix', '') . $pattern, $count);
$keyArr = array_merge($keyArr,$data ?: array());
if ($iterator === 0){ //迭代结束,未找到匹配
break;
}
if ($iterator === null) {//"游标为null了,重置为0,继续扫描"
$iterator = "0";
}
}
// 反转去重
return array_flip(array_flip($keyArr));
}