分类 高性能用法 下的文章

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));

}