导火索:线上频发报警,网关频繁转发超时,系统很多服务响应时间过长,服务cpu过载,数据库死锁等不正常现象

问题排查:目标范围缩小在近两日上线功能,并锁定在新上线的操作redis缓存功能上。

问题复现:将功能在开发环境测试,由于访问量不足并未发现异常。

将某需求下线后,线上环境得以好转。

分析代码:发现如下

    /*** Del.** @param keys the keys*/public static void del(String... keys) {try (Jedis jedis = getJedis()) {jedis.del(Arrays.stream(keys).map(v -> key(v)).collect(Collectors.toList()).toArray(new String[]{}));} catch (Exception e) {log.error("Redis error:{}", ExceptionTools.getExceptionStackTrace(e));throw new RuntimeException(e);}}/*** del by pattern** @param pattern prefix**/public static Long del(String pattern) {try (Jedis jedis = getJedis()) {Set<String> keys = jedis.keys(key(pattern));if (CollectionUtils.isNotEmpty(keys)) {return jedis.del(keys.toArray(new String[0]));} else {return 0L;}} catch (Exception e) {log.error("Redis error:{}", ExceptionTools.getExceptionStackTrace(e));throw new RuntimeException(e);}}

事故原因:工程师执行redis keys * 导致环境濒临宕机
由于及时发现,虽然未造成重大事故,但实属本年度PO级特大事故:

由于工程师直接操作上线redis,执行:

keys * wxdb(此处省略)cf8*

新增的单参数的del方法覆盖了多参数的del方法,所有调用del的地方都走单参del方法,然而此方法内含有keys命令。

redis是单线程服务,这样的命令,导致redis锁住,导致CPU飙升,引起所有支付链路卡住,等十几秒结束后,所有的请求流量全部挤压到了rds数据库中,使数据库产生了雪崩效应,发生了数据库宕机事件。

由于之前验收环境缓存量小,未发现此影响其他服务响应延迟的问题。

运维表示之后会逐步收回运维部各项权限!

二、一条铁律

在业内,redis开发规范中有一条铁律如下所示:

线上Redis禁止使用Keys正则匹配操作!

然而大家都知道,却一直忘记,所以事故会不断的发生。
下面讲一讲在线上执行正则匹配操作,引起缓存雪崩,最终数据库宕机的原因。

三、深度分析

1、redis是单线程的,其所有操作都是原子的,不会因并发产生数据异常;

2、使用高耗时的Redis命令是很危险的,会占用唯一的一个线程的大量处理时间,导致所有的请求都被拖慢。(例如时间复杂度为O(N)的KEYS命令,严格禁止在生产环境中使用);

有上面两句作铺垫,原因就显而易见了!

  • 运维人员进行keys *操作,该操作比较耗时,又因为redis是单线程的,所以redis被锁住;
  • 此时QPS比较高,又来了几万个对redis的读写请求,因为redis被锁住,所以全部Hang在那;
  • 因为太多线程Hang在那,CPU严重飙升,造成redis所在的服务器宕机;
  • 所有的线程在redis那取不到数据,一瞬间全去数据库取数据,数据库就宕机了;

需要注意的是,同样危险的命令不仅有keys *,还有以下几组:

因此,一个合格的redis运维或者开发,应该懂得如何禁用上面的命令。所以我一直觉得出现新闻中那种情况的原因,一般是人员的水平问题。

四、怎么禁用这些命令呢?

就是在redis.conf中,在SECURITY这一项中,我们新增以下命令:

另外,对于FLUSHALL命令,需要设置配置文件中appendonly no,否则服务器是无法启动。

注意了,上面的这些命令可能有遗漏,大家可以查官方文档。除了Flushdb这类和redis安全隐患有关的命令意外,但凡发现时间复杂度为O(N)的命令,都要慎重,不要在生产上随便使用。例如hgetall、lrange、smembers、zrange、sinter等命令,它们并非不能使用,但这些命令的时间复杂度都为O(N),使用这些命令需要明确N的值,否则也会出现缓存宕机。

五、改良建议

业内建议使用scan命令来改良keys和SMEMBERS命令:

Redis2.8版本以后有了一个新命令scan,可以用来分批次扫描redis记录,这样肯定会导致整个查询消耗的总时间变大,但不会影响redis服务卡顿,影响服务使用。

Redis线上做Keys命令引发的生产事故相关推荐

  1. 【Linux服务器开发系列】一场redis线上事故引发的思考丨redis持久化 rdb和aof丨redis主从复制

    一场redis线上事故引发的思考 1. 事故背景介绍 2. redis持久化 rdb和aof 3. redis主从复制 4. 解决方案详解 [Linux服务器开发系列]一场redis线上事故引发的思考 ...

  2. 【Jedis testOnBorrow配置 引发的生产事故】

    [Jedis testOnBorrow配置 引发的生产事故] 背景 问题排查 问题总结 原因分析 破案 总结 完 背景 公司系统在昨晚升级之后,一晚上基本没睡觉的我一大早7点被运维打电话叫醒,并告诉了 ...

  3. Redis 敢在线上做Keys正则匹配操作!你可以离职了!

    作者:孤独烟,资深后端工程师,业内知名原创作者 一个新闻 新闻内容如下 php工程师执行redis keys * 导致数据库宕机 某公司技术部发生2起本年度PO级特大事故,造成公司资金损失400万,原 ...

  4. 指令脚本redis线上环境监控脚本(python脚本)

    在改章节中,我们要主介绍指令脚本的内容,自我觉感有个不错的议建和大家分享下 近来一个月没啥新更,边身生发太多事,结业几年来霉运太多,虽然不信命,但我信有些性命的确好,有些性命的确差,其它不说也罢.(大 ...

  5. 报告!活捉Redis线上故障一枚!

    一.前言 最近项目的生产环境遇到一个奇怪的问题: 现象:每天早上客服人员在后台创建客服事件时,都会创建失败.当我们重启这个微服务后,后台就可以正常创建了客服事件了.到第二天早上又会创建失败,又得重启这 ...

  6. Java开发必须掌握的线上问题排查命令

    作为一个合格的开发人员,不仅要能写得一手还代码,还有一项很重要的技能就是排查问题.这里提到的排查问题不仅仅是在coding的过程中debug等,还包括的就是线上问题的排查.由于在生产环境中,一般没办法 ...

  7. 水果店线上做活动方案,水果店线上运营策划方案

    1.顾客群偶尔做低价活动 水果店刚开始建群,都会遇到没什么人下单,这个时候,就没有动力去去做了,其实没有必要,坚持就好.找几个爆品加好友进群半价卖,准备一个群花五百块钱试试,五百不行就八百,群里人总会 ...

  8. 一个情怀引发的生产事故

    在一个项目中,需要轻量级用到脚本语言,来提高应用服务的灵活性.因为知道Roslyn可以动态编辑C#,本着情怀,就自然用Roslyn来处理这块业务了.开在windows上执行,一次调用风平浪静,因为这个 ...

  9. Redis线上救命丸:01---误操作AOF、RDB恢复数据

    Redis的flushall/flushdb命令可以做数据清除,对于Redis的开发和运维人员有一定帮助,然而一旦误操作,它的破坏性也是很明显的.怎么才能快速恢复数据,让损失达到最小呢?本文我们将结合 ...

  10. 一台电脑上配置多个git账号(gitee),向不同git线上仓库提交(命令行/TortoiseGit同时) 代码

    目录 1.一台电脑上实现与多个git在线仓库提交代码的实际场景 2.安装git TortoiseGit 生成SSH key 和 git的.ssh目录 创建并配置config文件 2.1.首先必须先安装 ...

最新文章

  1. Howto: Deploy VC2008 apps without installing vcredist_x86.exe
  2. 用软件如何识别pdf文字
  3. hiho_1089_floyd最短路
  4. 英语影视台词---六、Saving Private Ryan Quotes
  5. python 网页樱花动态图_python,tensorflow线性回归Django网页显示Gif动态图
  6. 影子场vs.属性访问器接口第2轮
  7. CountDownLacth详解
  8. 服务器安装opencv报错--libSM.so.6: cannot open shared ...+tensorflow 报错libcusolver.so.8.0: can not...
  9. zblog拓源纯净主题
  10. 英特尔将开源进行到底!
  11. 某些数组和字符串类型转换(转)
  12. mybatisnet - 2 使用 DataMapper 访问数据库
  13. 基于GPU的大规模图计算系统与应用
  14. xbee模块和单片机_什么是xbee模块?和zigbee模块有什么区别?
  15. MySQL的金科玉律:“不要使用SELECT *”
  16. ibm邮件怎么撤回_请问LotusNotes具备发出邮件后撤回 – 手机爱问
  17. K8S环境快速部署Kafka(K8S外部可访问)
  18. 创立仅一年GMV突破3亿!这个新锐品牌如何在快手实现爆发?
  19. 西安交通大学计算机组成实验报告,西安交通大学实验报告
  20. 孕妇吃米饭好吗?盘点适合孕妇吃的美食

热门文章

  1. 支付宝小程序登录 -tp
  2. optionnally mysql_关于Tomcat与MySQL连接池问题的解析!
  3. [散文]茶想(作者:王莹莹)
  4. 微信内嵌浏览器打开手机浏览器下载APP(APK)的方法
  5. 10、返回当前审批流程图、后续审批按钮
  6. 中国水疗市场趋势报告、技术动态创新及市场预测
  7. 京交会将首设“一主多辅”场馆 展览面积较往届倍增
  8. MySQL数据备份与恢复及sql语句使用方法
  9. mysql索引填充因子_处理索引碎片,填充因子(FILLFACTOR)
  10. 西门子plc200 c语言转换,西门子S7-200 系列PLC量程转换及编程方法