zoukankan      html  css  js  c++  java
  • Redis-Scan命令

                                                                                Scan命令

    Scan命令:从海量的 key 中找出满足特定前缀的 key 列表

    查询key为某一类型的数据可能有很多方法,例如可以通过keys*或者是keys codehole*,查询key前缀为codehole的redis缓冲数据,但是当缓冲数据量比较大时,该命令表耗费时间,效率比较慢,具体的缺点如下列所说那样。

    一、keys * 、keys codehole* 分别是查询全部的key以及查询前缀为codehole的key。特点太暴力,性能不好,搜索的是整个redis;

    缺点:

    1、没有 offset、limit 参数,一次性吐出所有满足条件的 key,万一实例中有几百 w 个 key 满足条件,当你看到满屏的字符串刷的没有尽头时,你就知道难受了。

    2、keys 算法是遍历算法,复杂度是 O(n),如果实例中有千万级以上的 key,这个指令就会导致 Redis 服务卡顿,所有读写 Redis 的其它的指令都会被延后甚至会超时报错,因为 Redis 是单线程程序,顺序执行所有指令,其它指令必须等到当前的 keys 指令执行完了才可以继续。

    二、由于keys命令存在以上的缺点,所以redis引入以下scan命令,scan命令的特点:

    1、复杂度虽然也是 O(n),但是它是通过游标分步进行的,不会阻塞线程;

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

    3、同 keys 一样,它也提供模式匹配功能;

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

    5、返回的结果可能会有重复,需要客户端去重复,这点非常重要;

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

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

    三、scan命令具体用法:

    1、scan提供3个参数:第一个是 cursor 整数值,第二个是 key 的正则模式,第三个是遍历的 limit hint,例如:scan 0 match key99* count 1000 解释:从0开始遍历,匹配key99*,总数是1000 ,1000不是结果数量,是redis单次遍历字典槽位数量(约等于),如下图所示:

    scan 参数提供了三个参数,第一个是 cursor 整数值,第二个是 key 的正则模式,第三
    个是遍历的 limit hint。第一次遍历时,cursor 值为 0,然后将返回结果中第一个整数值作为
    下一次遍历的 cursor。一直遍历到返回的 cursor 值为 0 时结束。


    127.0.0.1:6379> scan 0 match key99* count 1000
    1) "13976"
    2) 1) "key9911"
    2) "key9974"
    3) "key9994"
    4) "key9910"
    5) "key9907"
    6) "key9989"
    7) "key9971"
    8) "key99"
    9) "key9966"
    10) "key992"
    11) "key9903"
    12) "key9905"
    127.0.0.1:6379> scan 13976 match key99* count 1000
    1) "1996"
    2) 1) "key9982"
    2) "key9997"
    3) "key9963"
    4) "key996"
    5) "key9912"
    6) "key9999"
    7) "key9921"
    8) "key994"
    9) "key9956"
    10) "key9919"
    127.0.0.1:6379> scan 1996 match key99* count 1000
    1) "12594"
    2) 1) "key9939"
    2) "key9941"
    3) "key9967"
    4) "key9938"
    5) "key9906"
    6) "key999"
    7) "key9909"
    8) "key9933"
    9) "key9992"
    ......
    127.0.0.1:6379> scan 11687 match key99* count 1000
    1) "0"
    2) 1) "key9969"
    2) "key998"
    3) "key9986"
    4) "key9968"
    5) "key9965"
    6) "key9990"
    7) "key9915"
    8) "key9928"
    9) "key9908"
    10) "key9929"
    11) "key9944"

    2、scan遍历顺序采用高位进位加法来遍历,进位的方向是从高位到低位,原因是考虑到字典的扩容和缩容时避免槽位的遍历重复和遗漏。

    3、redis的扩容:旧的数据移动到新的新组下,redis采用渐进式 rehash,同时保留旧数组和新数组

    4、定位大key:redis提供给了一个命令:redis-cli -h 127.0.0.1 -p 7001 –-bigkeys,如果担心该指令会大幅提升redis的ops,可以增加一个休眠的参数:redis-cli -h 127.0.0.1 -p 7001 –-bigkeys -i 0.1

  • 相关阅读:
    Android
    mysql监视器MONyog的使用
    网络架构、云平台和微信公众平台开发接入
    Protocol buffer序列化及其在微信蓝牙协议中的应用
    基于微信硬件公众平台的智能控制开发流程
    物联网架构演进和微信智能设备平台开发
    Android设置虚线、圆角、渐变
    android shape的使用详解以及常用效果(渐变色、分割线、边框、半透明阴影效果等)
    android bitmap的 一些简单操作
    Android Bitmap开发之旅--基本操作
  • 原文地址:https://www.cnblogs.com/matengfei123/p/12424095.html
Copyright © 2011-2022 走看看