缓存密集加载导致数据库崩溃问题
[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/Bug-Log-Optimization/cache-load-database-crash.html
背景
SISP自己基本不存储业务数据,但是每个节点都需要本地缓存了一些网点、员工信息、月结用户信息等基础数据,生产监控发现数据库定期压力飙升,数据库CPU压力到达80+%
如图:
用脚趾头分析
- 从图中可以看出,每天小时飙升一次,明显就是定时任务大批量查询数据库导致的,在SISP系统,也就只有加载缓存可能会导致
- 找到运维获取慢日志,发现大量的查询语句,如下:
1 | SELECT DISTINCT nd.division_code AS city_code, nnd.dist_cn_name , nnd.dist_en_name |
因为是单库,数据量也大,单条sql查询耗时近40s,因此,大量查询导致数据库压力飙升
解决
解决手段1:缓存刷新时间分散开,错峰加载缓存
因为是通用方法,这里8分钟内刷新一次的小任务就忽略了。我们对大于8分钟的任务,增加了随机时间间隔,如下代码所示(其中delayPercent = 0.2,表示随机减少时间定时任务0~20%的间隔时间):
1 | /** |
解决手段2: 优化慢查询sql
重新梳理业务逻辑,其实我们只是需要城市代码对应的多城市名而已,其在tm_new_district中就有了,只是我们没有从上游上同步到我们数据库罢了。
同步完对应表字段后,完全不需要连接表,用一条简单sql就可以了,新的SQL:
1 | SELECT DIST_CODE, DIVISION_CODE, CITY_CODE, dist_cn_name,dist_en_name FROM tm_new_district t WHERE t.division_code IS NOT NULL |
新的sql查询耗时只有不到1s,因此,大量查询导致数据库压力飙升的问题得到了解决
上线后优化效果
优化前CPU压力图(单节点):
手段1优化后:
结合手段1、手段2,优化后:
结论
经过优化后,数据库压力得到了很大的缓解,突发峰值也基本消失;应用CPU压力也从原来的15%降低到3%左右,整体系统性能得到了很大的提升。
结语
这次分享了:缓存短时间密集加载
与sql慢查询(姑且算是吧)
的处理。算是很经典的问题了,到处都会遇到,希望能帮助到大家。