redis深入学习-05—redis中scan的用法

平时线上Redis维护工作中,有时候需要从Redis实例的成千上万个key中找出特定前缀的key列表来手动处理数据。这里就有个问题如何从海量的key中找出满足特定前缀的key列表?Redis提供了一个简单的指令keys用来查询出所有满足特定正则规则字符串的所有key。这个指令虽然简单,但是有明显的缺陷。

1. 没有offset、limit参数,一次性会查询出所有满足条件的key。如果数据量大,绝对会造成操作堵塞,导致其它查询redis的线程等待,是比较危险的操作。

2. redis的keys操作的复杂度是O(n),需要一个一个去遍历匹配。所以性能比较低。

面对以上的问题,redis在2.8版本以后提供了一个指令-----scan。这个命令具备以下特点。

1. 复杂度O(n),但他是通过游标分布进行的,不会阻塞线程。

2. 提供limit参数,可以控制每次返回结果的最大条数,limit只是一个 hint,返回的结果可多可少。

3. 同keys一样, 他也提供模式匹配功能。

4. 服务器不需要为游标保存状态,游标的唯一状态就是scan返回给客户端的游标整数。

5. 返回的结果可能会有重复,需要客户端去重。

6. 遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的。

7. 单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零。

下面我们看一个命令:

san 0 match keyuser* count 100

参数解释:

0:cursor整数值。

keyuser*:key的正则模式。

100:遍历的limit值。

第一次遍历时,cursor值为0,然后将返回结果中第一个整数值作为下一次遍历的cursor,一直遍历到返回的cursor值为0时结束。

如果执行上述命令,虽然与keyuser*相关的结果可能超过100,但是上述命令执行后返回的结果不一定是100个,因为这个100只是代表扫描了100个key,这100个key中有可能没有一个与制定的正则key匹配,可能返回结果为空,我们要看是否扫描完,主要是看返回来的第一个整数值是否为0。为0,则扫描完毕。

以下为示例:

查询 s* 相关的key,一共有7个key。

每次查询的时候,都查询指定查询数为3。从下图可以看出实际每次查询结果都是2个,但是扫描了3个key。如果要翻页查,下次执行命令的时候,cursor就得指定上一次返回的第一个整数参数,如下图红框所示。指导图片中的最后一行命令执行的返回结果中第一个正式值为0时,扫描完毕。

 

郑重声明:以上内容参考了《Redis深历险》一文,非常感谢作者的贡献。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荆茗Scaler

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值