前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次redis cpu 100%的紧急bug

记一次redis cpu 100%的紧急bug

作者头像
林老师带你学编程
发布2020-02-13 09:54:40
3K0
发布2020-02-13 09:54:40
举报
文章被收录于专栏:强仔仔强仔仔

前段时间遇到一个棘手问题,mq消费速度突然从30/s变成1/s,而且还持续了很长的一段时间,吓得我赶紧动手排查问题。但是mq消费速度慢的原因,可能有很多种(例如mysql、jvm、redis、mq、代码问题等)。为了可以快速定位问题点,博主直接通过Arthas工具进行问题的排查和追踪。

Arthas用法可以参照:https://mp.weixin.qq.com/s/FT1gKYDzczWa05xYm-z0Vw

image
image

通过Arthas的trace命令,可以分析方法中每一行代码的执行时间,分析得到方法中最耗时的竟然是redis,看到这个结果差点没卧槽出来,redis怎么可能会那么慢呢。因为公司使用的是腾讯云的redis,所以可以直接在控制台上面看到redis各个监控指标,博主火速打开控制台,然后就看到如下所示cpu持续不断的飙到100%。

image
image

那会是什么操作引起的呢?我们首先要清楚一般什么情况下会导致redis的cpu飙升到100%。导致cpu飙升的原因,一般可能会有如下几种:

  1. redis从库大批量同步到redis主库
  2. redis请求的qps过高
  3. redis存在大量慢查询

因为系统redis目前是单例,所以不存在第一种的情况。至于第二种,从腾讯云控制台中看到redis总请求的量,发现cpu高的那个时间段,总请求数并没有飙升,所以也不是第二种可能。至于第三种可能性,如下所示,发现了很多keys *report:requestId:*的命令出现。

image
image

到了这一步基本可以确定是因为keys *report:requestId:*引起的,但是为了出于严谨考虑,我们在测试环境多次请求keys *report:requestId:*命令,发现果然cpu直接飙升上去了。原来罪魁祸首是keys模糊搜索引起的啊,那我们要如何解决这个问题呢?

我们可以用scan来替代keys命令,java代码如下所示:

代码语言:javascript
复制
Set<String> keys = (Set<String>) redisTemplateForRequestId.execute((RedisCallback<Set<String>>) connection -> {
            Set<String> keysTmp = new HashSet<>();
            Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(multiRedisKey + "*").count(100).build());
            while (cursor.hasNext()) {
                keysTmp.add(new String(cursor.next()));
            }
            return keysTmp;
        });

优化之后可以明显看到,redis的超过2s的命令都不存在了,cpu也恢复到之前平缓的状态了。所以以后在写redis的api时候要慎用甚至不用keys命令,如果数据量特别大的情况下,严重可能会导致redis持续性宕机。

大家是不是以为到这边就结束了呢?不!不管使用keys还是scan都比一般的命令耗时。如果我们想要查询的命令可以通过枚举一一列出来(数量不大,允许一一枚举),那我们一定要用枚举来查询,这样效率会比用scan高很多(有点类似数据库的like和=操作)。所以最后代码博主优化为:

代码语言:javascript
复制
redisTemplate.opsForValue().multiGet("list集合,里面存储着redis的key值")

之所以能这么快定位到redis对应的问题,很大一部分是因为腾讯云给我们提供了很多便捷式的查询。如果你的redis没有这些指标监控呢,你又该如何监控这些指标呢?哈哈,后面有机会给大家介绍。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档