theme: orange
一、背景
有一天,dba在数据库告警群找到我,说我们数据库CPU有规律性的尖刺,qps每次突然增加500+,尖刺时cpu飙升到60%,没尖刺时只有5%左右
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/aa5d03639bbb4ead860554a2dc5a9c1a~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=240&h=240&s=50531&e=png&a=1&b=f6f4f4)
这种情况对系统造成的稳定性风险极高
,要我们尽快排查,尽早排除隐患。下面是当时的数据库qps监控
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba1d90fae027489282ff6c2c03a0d60d~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=742&h=170&s=48426&e=png&b=ffffff)
二、排查与沟通过程
由于是规律性的尖刺,我们想到我们的定时job
, 我们业务有一个业务配置
缓存数据,通过Java程序的定时job从数据库加载到本地内存的,而且时间也吻合。
通过查看代码,我们是一个单机的job每,5分钟加载一次,每台机器都是分页从数据库读取配置数据
,每次读取100条
,然后写到本地的内存里。
这里有两个问题,单机的job和分页查询,我们生产环境有50台机器,这样查询db的qps会放大
,造成数据库压力扩大。
和dba进行了沟通,dba给了我们两条建议:
1、要我们不要分页查询,直接一次性查询所有的配置数据。
2、不要用本地缓存,直接使用redis,这样就一份数据,操作数据库的qps也降低了。
三、第一次优化
由于是c端系统,而且业务配置缓存是系统的热点数据
,考虑到系统稳定性
第一,我们第一次没有大的改动,试图调高了
分页的limit
大小,观测数据库的监控,cpu使用率有下降,但是还是有尖刺,这样还有慢sql
情况。
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ab990a68ee454ac4ac03329d3155ccec~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=656&h=386&s=121539&e=png&b=191b1f)
四、第二次优化
由于尖刺仍然存在,对数据库还是有一定的压力
,且现在的方案存在优化空间
,为了彻底消除数据库隐患,因此我们开始了第二轮优化。
我们需要解决的问题:
1、降低数据库qps
,消除cpu尖刺
2、不影响查询热点配置数据的性能
因为每台机器都请求数据库,分页查询
请求,我们想着降低请求qps,因此我们去除原来这种单机定时加载缓存
方式,换成加载缓存到redis,这样就只要一台机器启动一个定时任务了,这样可以降低数据库的qps。由一个定时任务每5分钟执行一次,加载到redis。
不影响原来的查询性能,肯定不能直接查询redis,因此我们引入了本地缓存框架Caffine
,本地缓存从redis查询数据。这样就形成了二级缓存架构
。
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dbd5122a25d4449c9a7d1fa2200cd1d1~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=398&h=964&s=153677&e=png&b=fdfdfd)
整个缓存改造涉及三个阶段:
第一阶段:使用xxljob
定时job加载缓存到redis
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c006303651c34aaf90aac8952f2ffce9~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1176&h=1082&s=357590&e=png&b=fdfdfd)
第二阶段:程序启动初次加载缓存
,加载数据到本地缓存
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d888bd169f924a4eb41ffbf560ba139c~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=926&h=1190&s=328146&e=png&b=fefefe)
第三阶段:Caffine缓存未命中场景,单线程从缓存或者数据库加载
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/00a5b410ba2543438a8d48fca4af8ced~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1728&h=1284&s=563627&e=png&b=fdfdfd)
五、测试与上线流程
这次属于技术升级
,需要测试回归相关业务才能上线,整体测试与上线流程如下:
-
1、测试回归业务功能,开关验证
-
2、灰度验证
-
3、分机器发布
-
4、全量发布
先发布一台机器节点,观测了几天业务情况,观测没问题之后再分批次发布,直到所有机器节点发布完成。
六、最终效果
经过优化上线,数据库的qps和cpu使用率下来了,也没有了尖刺,彻底消除了数据库隐患。
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dd78e748609448478a48e051d3cb393f~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=472&h=208&s=73261&e=png&b=1a1c20)
七、总结
数据库是业务系统强依赖
的中间件,保障其稳定性至关重要,本文是根据实际性能优化经验,从架构设计
和代码层面
优化数据库的使用,降低数据库qps和cpu使用率,提高数据库的稳定性
。
通过这次优化实践
,给以后业务功能的设计开发也有一定的启发,一个好的方案设计
可以避免系统风险,提高资源利用率,作为程序员可以利用每次新功能的设计开发经验,不断的积累比较好的方案
,提升我们自身的能力。
坚持相信有输入一定要有输出,关注我们一起学习沉淀技术,希望我们的技术能力越来越强。
![image.png](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8f79832730064799bafa247f77588734~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=340&h=340&s=100533&e=png&b=fffbfb)
本文由 mdnice 多平台发布