今天爱分享给大家带来假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?【解决办法】,希望能够帮助到大家。
KEYS 指令
KEYS pattern #用法
KEYS t?? #查询如two,ttt这类的key
KEYS * #查询所有key
Redis的单线程的。KEYS命令一次性返回所有匹配的key,keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。
所以应该在生产环境禁止用使用keys和类似的命令smembers,这种时间复杂度为O(N),且会阻塞主线程的命令,是非常危险的。
SCAN 指令
使用SCAN命令获取所有key
SCAN 0
遍历返回结果,使用MATCH参数匹配前缀
SCAN 0MATCH "prefix:*"
其中prefix为前缀,*表示匹配任意字符
需要注意的是,如果Redis实例中有很多key,这个操作可能会比较慢,需要耗费一定的时间。另外,如果有多个Redis实例,需要分别对每个实例执行这个操作。
每次执行都只会返回少量元素,所以可以用于生产环境,而不会出现像 KEYS 或者 SMEMBERS 命令带来的可能会阻塞服务器的问题。
SCAN命令是一个基于游标的迭代器。这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程
当SCAN命令的游标参数(即cursor)被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。
这种方法使用 SCAN
命令进行逐步迭代,避免了 KEYS
命令可能带来的性能问题。你可以根据需要调整 COUNT
参数来控制每次迭代返回的 key 数量。
注意:在执行此类操作之前,请确保你了解 Redis 中的 key 数量和数据分布,以便合理调整参数和预期结果。同时,建议在非生产环境下进行测试,以验证方案的可行性和性能。
scan缺陷
在对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素提供有限的保证 。
scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。