专栏首页我是攻城师redis命令keys和scan的区别

redis命令keys和scan的区别

redis的keys命令,通来在用来删除相关的key时使用,但这个命令有一个弊端,在redis拥有数百万及以上的keys的时候,会执行的比较慢,更为致命的是,这个命令会阻塞redis多路复用的io主线程,如果这个线程阻塞,在此执行之间其他的发送向redis服务端的命令,都会阻塞,从而引发一系列级联反应,导致瞬间响应卡顿,从而引发超时等问题,所以应该在生产环境禁止用使用keys和类似的命令smembers,这种时间复杂度为O(N),且会阻塞主线程的命令,是非常危险的。

keys命令的原理就是扫描整个redis里面所有的db的key数据,然后根据我们的通配的字符串进行模糊查找出来。官网详细的介绍如下。

https://redis.io/commands/KEYS

取而代之的,如果需要查找然后删除key的需求,那么在生产环境我们应该使用scan命令,代替keys命令,同样是O(N)复杂度的scan命令,支持通配查找,scan命令或者其他的scan如SSCAN ,HSCAN,ZSCAN命令,可以不用阻塞主线程,并支持游标按批次迭代返回数据,所以是比较理想的选择。keys相比scan命令优点是,keys是一次返回,而scan是需要迭代多次返回。

https://redis.io/commands/scan

但scan命令的也有缺点,返回的数据有可能重复,需要我们在业务层按需要去重,scan命令的游标从0开始,也从0结束,每次返回的数据,都会返回下一次游标应该传的值,我们根据这个值,再去进行下一次的访问,如果返回的数据为空,并不代表没有数据了,只有游标返回的值是0的情况下代表结束。

redis命令例子如下:

scan 0 match my*key count 10000

在Java项目里面,使用jedis执行scan命令的模板例子如下:

               Jedis jedis = getJedis();               //存储返回的结果                Set<String> result=new HashSet<String>();                //设置查询的参数                ScanParams scanParams=new ScanParams().count(scanLimitSize).match(pattern);                //游标的开始                String cur=ScanParams.SCAN_POINTER_START;                do{                   //遍历每一批数据                    ScanResult<String> scan=jedis.scan(cur, scanParams);                    //得到结果返回                    List<String> scanResult =scan.getResult();                    result.addAll(scanResult);                    //获取新的游标                    cur=scan.getStringCursor();                //判断游标迭代是否结束                    }while (!cur.equals(ScanParams.SCAN_POINTER_START));                //返回结果                return result;

本文分享自微信公众号 - 我是攻城师(woshigcs),作者:攻城师在路上

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 开源大数据索引项目hive-solr

    我是攻城师
  • hive自定义udf实现md5功能

    我是攻城师
  • 理解Java里面的jvm,jre,jdk的区别和联系

    我是攻城师
  • Redis 监控器

    Redis有一个monitor命令,某个client执行monitor命令后,就成为了一个监控器,服务器端执行的所有命令都会发送给监控器 monitor 是一个...

    dys
  • R语言获取ArrayExpress数据库数据

    大家可能有一部分人对ArrayExpress数据库是比较熟悉的,当然也有人可能没怎么听说过。今天我么主要介绍一个可以获取ArrayExpress数据库数据的R包...

    一粒沙
  • 机器翻译不可不知的Seq2Seq模型

    Seq2Seq,全称Sequence to Sequence。它是一种通用的编码器——解码器框架,可用于机器翻译、文本摘要、会话建模、图...

    机器学习算法工程师
  • 使用python创建跨平台的fork()炸弹

    进程炸弹运行截图 这是一个用python实现的最简单的fork炸弹 import os while True: os.fuck() 但是对于win...

    zhaoolee
  • SFFAI分享 | 田正坤 :Seq2Seq模型在语音识别中的应用

    随着神经机器翻译的兴起,基于Attention的Seq2Seq模型由于其强大的建模变长序列直接转换问题的能力,也在其他领域获得了极大的关注。语音识别问题本质上也...

    马上科普尚尚
  • 搞清“连接”和“会话”

    对Oracle中连接和会话的含义,总是有些模糊,参考TOM大叔的《Oracle编程艺术》,重新整理了下知识点。

    bisal
  • 谷歌为机器学习研制专用芯片

    2016年5月18日,谷歌官方博客发布消息称:谷歌为机器学习任务研制了专用芯片。文章内容如下: 机器学习为谷歌的许多最受欢迎的应用程序增加了潜在吸引力。事实上,...

    人工智能快报

扫码关注云+社区

领取腾讯云代金券