记一次redis迁移遇到CPU占用过高问题

背景:

项目需要做redis(旧)到redis的数据迁移,考虑到三种方案:

1 redis和旧redis同时写,读的时候根据配置选择从redis还是旧redis读取数据。

2 通过旧redis到redis的数据同步,代码中直接修改redis的地址。

3 通过scan的方式扫描redis中的数据,再通过Pipeline的方式写入。

对比了一下方案的优缺点:

1 缺点是时间成本高,业务中有些数据过期时间长,切换周期长;优点是可以平滑切换;

2 缺点是需要dba的同学配合;优点是时间成本低。

3 缺点是对于一些有过期时间的key,写入的时候过期时间会有误差,同时写入的时候会有一些增量的数据无法写入,导致数据不一致的情况。

综上决定通过第二种方式来做redis和旧redis的数据同步。

实现:

客户端选择:项目是一个springboot项目,已有的客户端是在jedis上做的一层封装。如果使用springboot集成的redistemplate的话,需要新增redistemplate的工具类,以及改动所有涉及到redis的代码,或者在原有的工具类中修改jedis为redistemplate;如果使用jedis的话则不需要改动其他代码。所以选择了jedis作为客户端。

问题1:

在这个环节就出了问题,在配置redis连接池的时候,使用的redis的最大连接数是20,业务测试通过后,dba也做好了数据的同步,然后就进行了正式环境的升级。

结果:

刚上线后,cpu飙升,系统开始报警。当时也没有意识到是哪里的问题,就开始排查之路

问题排查:

1 查看cpu的进程:top 命令查看系统中占用cpu高的进程;

2 查看cpu高的线程:确认是自己代码导致的cpu过高后,通过top -Hp 进程号  按cpu占用率查看线程;

3 线程号转换十六进制:拿到占用cpu高的线程号之后,通过printf %x 线程号 打印出十六进制的线程号;

4 查看线程的栈信息:jstack 进程 | grep 0xd5352 -A 20其中0x后面的即为线程号的十六进制 

5 栈中的信息大多是大多是gc的信息和catalina的信息。

6 排查gc问题,通过jstat -gcutil 进程号 1000 30 每1秒查看一下该进程的gc信息,发现一直在进行full gc,FGCT时间也特别高

7 jmap查看堆的信息,(jmap -histo 可以查看堆中所有的对象的引用数量,jmap -histo:live 1314| head -20 查看存活对象大小排名前20的),jmap -dump:live,format=b,file=/home/work/1310.dump 1310想存一份线上的堆快照(可以进行压缩,以便下载 tar -zcf 1331.dump.tar.gz 1331.dump)分析一下,使用MAT进行分析,由于问题比较紧急,下载dump比较慢,先准备从监控系统分析。

8 由于仅仅是升级了redis,所以考虑是不是配置有问题,所以照搬了一份艾泽拉斯系统的配置,重新升级。(后续才发现,kibana上面一直在报错,Could not get a resource from the pool at redis.clients.util.Pool.getResource ,如果可以刚出问题就看一下kibana上面的错误信息,就可以很快的定位到是redis配置的问题)。

9 升级完成之后本以为可以解决cpu过高的问题,刚升级后没多久,cpu又开始爆满,重新开始上面的1-5的步骤,发现占用cpu高的线程里面指向了一些具体的业务代码,该代码是从memcache拿数据,拿不到就从数据库拿,发现业务代码栈顶信息指向了mybatis,说明缓存没有起作用。在比较紧急的情况下,将memcache改为了redis,并重新上线。(改了redis配置之后从cdb的监控中可以看到数据库的qps是比往常高的,也可以说明缓存并没有起作用)。

10 升级完成之后redis开始报警,提示出口流量过高, 看redis的监控信息,请求都从数据库转移到了redis上。

11 看了一下业务代码,主要是多层循环,循环次数可能会到几十万次,而循环体内会很多次调用redis。该接口是个查询接口(数据会变),所以将查询结果做了个缓存,定期更新查询结果,放入redis中,外部请求直接从redis中拿数据,升级后问题解决。

总结:

出现问题的根本原因就在于1 redis连接数配置有问题,2 该接口数据量比较大,调用量增多导致的。

心得:

1 遇到线上问题需要先结合kibana、以及内部的监控系统结合起来排查信息。

2 配置类参数需要慎重修改。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每年进步一点点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值