0
点赞
收藏
分享

微信扫一扫

自己动手写一个分库分表中间件(十)线上优化之数据库连接超时优化


注:本文核心思想来自于同组内同学共同对线上问题的分析和探讨。

分库分表改造上线后,我们发现了一个问题:系统对慢 SQL 的容忍度降低了(这里要补充一点的是,由于历史原因,当前系统的确存在一些对数据库操作不合理的地方)。

最初是系统突然卡顿,然后线上有机器重启,数据库“Threads Connected ”、“运行线程数”等飙升,系统也出现了大量获取数据库连接超时的异常。最终定位(具体的分析过程这里不做赘述)到是大量的慢 SQL 拖垮了系统。

原因主要有两点:

  1. 由于存在分布式事务的场景,所以会存在同时多个 ​​Connection​​​ 被 TM 同时管理的情况,此时会占用大量 ​​Connection​​;
  2. 由于我们的某个库数据中分了 5 个表,会存在一个全库查询的请求会占用 5 个 ​​Connection​​,而一般来说,慢 SQL 一旦慢,查询哪个库都会很慢,所以这个库会面临很大的压力;

那么接下来要做的事就是避免系统再次被慢 SQL 拖垮。肯定有同学第一反应是去优化慢 SQL,但其实慢 SQL 的优化并不像网上很多博客说的“优化慢 SQL 的那几项”那么简单,其实去年我们组内就做过一次慢 SQL 的优化并且取得了一定的效果,那种“能够简单遵循一些基本原则”解决的慢 SQL 早就解决了,剩下的都是一些“暗坑”或者你知道是坑但是一时半会难以解决的。

大家都知道 MyBatis 有个动态 SQL,动态 SQL 如果条件复杂是可能生成各种各样 SQL 的,而这个 ​​Mapper​​ 可能也被很多上层的方法所依赖,容易牵一发而动全身,最终这些“坑”肯定是要解决的,但是需要时间成本,我们现在最需要的是在慢 SQL 能够完全彻底治理之前的解决方案。

这里就又需要逆向思维了,正如在​​一次彻底解决因数据库全表扫描引发系统卡顿问题的实践​​中提到的:

我们常常会陷入这种“「知道系统可能出现这样的问题,但是无法预防和监控,只能被动地等发生问题了再排查再解决」”的尴尬境地。

所以我们现在需要做的是“不要让系统被一些慢 SQL 拖垮”,你慢归你慢,系统不能被你拖垮,毕竟慢 SQL 占比也不会很多,我们只需要系统能够快速挺过那一波慢 SQL 即可。

这里就有一个 Fail-Fast 的思想。我们希望系统出现了异常能够 Fail-Fast,不要出现了慢 SQL,请求和连接全部都 hang 在那里,该失败就失败,尽可能的缩短系统的异常持续时间。

结合上述分析,本次优化了两个部分的参数:

  • 超时时间:
  1. 缩减与数据库建立连接的超时时间;
  • 与数据库建立连接都慢,那就是大问题了
  1. 缩减从连接池中获取 ​​Connection​​ 的超时时间;
  • 说明此时连接这块已经不正常了
  • 缩减并行多库查询线程池队列大小
  • 数据库的操作应该就是急快的,适当情况下可以允许“缓存”少量的任务,但是一旦出现任务堆积,就肯定是系统出现了问题,此时应该 Fail-Fast;

同时还基于 DBA 提供的数据库熔断机制,限制 SQL 执行的时间(这里要注意的是,限制时间的设置可以先统计一下目前 SQL 执行的最大耗时及占比,确定一个合理的超时时间)和最大并行线程,这三块调整下,可以尽可能的避免系统被慢 SQL 拖垮。

总结

思路比解决方案更重要。

References

  • ​​https://mp.weixin.qq.com/s?__biz=MzU1OTgyMDc3Mg==&mid=2247485037&idx=1&sn=7d71b552adda07e6bb38d9aca72aece9&chksm=fc103ce6cb67b5f01817f2850415eec829442d077b3fdddb4a316ec23ace6efa6af768548918&token=806063056&lang=zh_CN#rd​​


举报

相关推荐

0 条评论