专栏首页大龄码农老大说:谁再用redis 的 keys命令,立刻给我走人

老大说:谁再用redis 的 keys命令,立刻给我走人

先看现象

redis-cli keys * | args redis-cli del
(error) ERR network error
(30.00s)

#执行了一条 keys xxxxx* 命令,令数据库宕机了,怪不得技术总监发狠话:谁要是敢用 keys 命令,直接收拾包袱走人。接下来我们看看是什么回事:

最近有好多个项目要迁移了,一般迁移前都会做评估,对现有的业务,资源,关系等等做整理,其中有个项目,在做旧云 与 新云之间的数据源(redis)同步时,同步工具卡死了,新云的数据源竟然报警,内存不足!纳尼!!!!用的可是 8G容量的redis实例阿!why!!!! 赶紧查下redis内存信息

info memory

used_memory:16638616792
used_memory_human:16.88G
dbsize
(integer) 98923051

旧云的redis实例的key竟然高达 16G+,接近1亿个key,我的天,操着为公司节省资源的心,我发誓一定要把一切的垃圾通通清掉,于是就走向了深渊

开始我使用 big key命令

[0.43%] Sampled 1000000 keys so far
[0.87%] Sampled 2000000 keys so far

但是一个下午过去了,才0.87%,果断放弃了,选择直接看业务代码,后来发现是因为某个key没有设过期时间造成的,于是就想看看它的量有多大,于是就有了下面的操作

redis-cli keys * | args redis-cli del
(error) ERR network error
(30.00s)

直接30秒超时,并且直接锁住了整个redis,执行 keys 模糊的匹配命令是为了清理没用的键,但是没有考虑到keys *进行模糊匹配引发 Redis 锁,造成 Redis 锁住,CPU 飙升,引起了所有调用链路的超时并且卡住,等 Redis 锁的那几秒结束,所有的请求流量全部请求到 RDS 数据库中,使数据库产生了雪崩,使数据库宕机

那应该怎么办呢,其实有改进方案的

  1. 所有线上操作,全部要经过运维通过后方可执行,运维部门逐步快速收回各项权限
  2. 新增 Redis 实例,进行分离
  3. 如果有使用类似 keys 正则命令需求,使用 scan 命令代替

SCAN 命令

Redis从2.8版本开始支持scan命令,SCAN命令的基本用法如下:

  1. 复杂度虽然也是 O(n),通过游标分步进行不会阻塞线程;
  2. 有限制参数 COUNT ;
  3. 同 keys命令 一样提供模式匹配功能;
  4. 服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的游标整数;

批量删除scan命令

因为KEYS命令的时间复杂度为O(n),而SCAN命令会将遍历操作分解成m次,然后每次去执行,从而时间复杂度为O(1)。也解决使用keys命令遍历大量数据而导致Redis服务器阻塞的情况。所以建议使用下边的指令进行批量的删除操作:

redis-cli --scan --pattern "key的前缀*" | xargs -L 1000 redis-cli del

最后,经过删除命令,redis实例的内存占用,之下下降到 不到100M,直接换要给1g的实例,刚刚,经过1天的折腾,为公司剩下了资源,也算是很有意义产出了,日报周报赶紧安排!!!

总结 因为Redis的KEYS在某种情况下会阻塞。在生产环境中一定要慎用慎用,有个真实真案件小哥哥生产用KEYS,最终导致服务宕机。后果很严重,产生的经济损失就不说了。

切记严重会导致程序的雪崩,删除的时候用SCAN命令,看完这篇文章应该都记住了。

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Redis的过期策略以及内存淘汰机制

    为什么不用定时删除策略? 定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应...

    traffic
  • ajax跨域问题

    跨域问题来自于浏览器同源策略的限制,包括DOM同源限制和ajax同源限制,本文探讨的是ajax跨域。ajax跨域指的是一个页面的ajax只能请求...

    traffic
  • linux安装redis

    安装编译器:yum install gcc-c++(需要先安装C++编译器,redis 使用c++写的)

    traffic
  • Redis模式匹配删除key

    Redis keys命令支持模式匹配,但是del命令不支持模式匹配,有时候需要根据一定的模式来模糊删除key,这时只能结合shell命令来完成了。 具体命令是:...

    joshua317
  • 5分钟就能做一个Excel动态图表,你确定不学学?(纯gif教学)

    下图是一个比较酷炫的Excel动态图表,最难的部分就是用到了一个复选框控件。其实这个控件我很早就见过,但是不会用呀!望洋兴叹。这次呢,我也是借着这个文章为大家讲...

    Python进阶者
  • redis中key过期事件

    刚到新公司一个月左右,有个新需求,想做定时任务,比如在用户注册时间的3天后推送用户一条消息。

    用户1558882
  • shell脚本实现基因重测序和变异位点检测(附源代码)源代码在文末

    基因组重测序和变异的这一节,之前有花时间学习过,所以整个过程,心中也大致有一些脉络,下面就当是做一个回顾。 下面引用一下,谈老师ppt里面的一张图:

    HUBU生信
  • 《google工作法》前言

    yeedomliu
  • 跟我一起学Laravel-EloquentORM进阶部分

    假设User模型关联了Phone模型,要定义这样一个关联,需要在User模型中定义一个phone方法,该方法返回一个hasOne方法定义的关联

    用户2131907
  • DevOps: 项目多环境配置和健康检查

    前面提到了你自己开发、给测试小妹妹测试以及给运维人员发布,一共三个环境,而实际上一个软件系统的环境往往不止这些。

    DevOps时代

扫码关注云+社区

领取腾讯云代金券