zoukankan      html  css  js  c++  java
  • 缓存穿透导致数据库性能不稳定

    事件描述 && 解决过程

    1. DAY1 19:47 业务新增一个访问接口来增加网站的访问量 。业务访问量比较少,当天没有发现问题。

    2.DAY2 下午业务开发联系我们,发现了一些下面的错误:

    ### Error querying database.  Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
    

    通过 google 可以发现是MySQL 的dbcp 连接池上的连接数使用完了,新的 client 请求没法获取可使用的连接池,等待超时。

    3.当时首先想到的是增加连接池的最大连接数,咨询了下开发,连接数从原来的50增加到 100.

    4.随后数据库服务器开始出现突然的 load 飙到40+,然后瞬间降到0.1 左右,业务数据量很少,请求频率也不高,每次报警的时候上去看了下,发现连接都不多,只有10+个用户连接。

    5.第一步确认下是不是 Linux Server 本身问题呢?联系 SA ,SA 大大说可能是 xfs 文件系统的一个bug。可是数据库系统都是统一配置的,为什么就这个机器有问题呢?当时后面 SA 的建议是迁移走数据,机器升级。

    6.随后数据库稳定,就没有继续追究,先看看连接数增加到 100 是否有效果。如果不行,考虑准备迁移走业务、升级机器。 [虽然业务量不大,但是物理机器上好几个 MySQL 小业务,迁移都需要联系对应的开发,也是个辛苦活。]

    7.DAY3 8:30 数据库 load 继续忽高忽低,DBA 接收到断线报警,查看监控平台信息,只有 cpu 的使用率也随着 load 呈现相似变化。登录到数据库机器上看的时候,load 变得很低,top 查看进程的资源消耗也很低。找了一个资深的 SA 大大帮忙看了下,麻烦他确认下是不是Linux 系统问题。

    8.SA 大大开了多终端,看了下 Linux机器的信息,发现没有啥问题,但是他在top 监控机器的过程中突然发现 MySQL 的cpu 使用率瞬间达到2000%,然后几秒后又很低甚至消失在top 的前几个资源进程消耗上。

    9.DAY3 9:10 左右DBA[调侃他下]开始 top 和 show processlist 来实施捕捉 MySQL 的进程状况,发现每过4-5min 左右,就会大量的出现 select now() from dual 和 select user()的请求,那个时间的相关业务连接数的确也非常高,接近100.

    10.最后让业务开发检查下原因。

    10.1 诊断期间有修改 dbpc 的配置,比如 validationQuery 从 select now() 改为 select 1, timeBetweenEvictionRunsMillis 和 minEvictableIdleTimeMillis 从1000 改为 3min ,5min 。 [效果不大]

    10.2 最后是开发那边对缓存上了 lock,避免缓存穿透,效果明显。

    解释:如果多个client发现缓存数据失效,只允许一个线程从数据库读取数据,放置到缓存供后续的请求读取。这样可以有效的避免当缓存失效的时候[开发设置5min],所有的 client 请求都下发到 DB ,造成DB 瞬间的请求处理请求数量增加,从而 cpu 和load 自然暴涨起来了。

    事后总结

    虽然这个事情最后是解决了,但是我发现这次解决问题的思路还是有些问题的。我就马后炮的总结下诊断事故的正确姿势。

    1.业务开发给出错误以后,DBA 首先看看出错日志的原因。比如这次是连接池等待资源超时。

    2.DBA 要连接到数据库机器上,查看当前的数据库资源使用情况,对应实例的连接情况,是否有阻塞的SQL等,确保其他业务还能正常使用。[一个 MySQL 实例可能有多个业务在上面]

    3.咨询开发人员,这个业务什么时候开始出现这些错误的,错误频率如何 .[这个当时没有咨询,只是考虑到可能是我们数据库这边出现了问题]

    3.1 如果是最近出现问题 && 并且数据库没有做任何变更,就要咨询是否最近业务是否变更、请求量是否最近有增加。[太重要了!!!业务更新不是每次都会通知DBA的]

    3.2 如果业务让然没有变更,看看数据库服务器历史资源使用情况 [比如最近几天的load cpu io tcp 连接数变化等],一来是看看数据库最近的变化,二来看看是否是其他业务导致了这个业务受到影响。

    4.看看慢查询日志,查看最近是否有高频并且占用资源较高的SQL。

    5.如果的确没有什么请求量,数据库这边没有啥动静,并且业务出现错误了,可能需要其他专业人士 SA 也来帮忙看下,是否是 Linux 机器本身的问题,或者是网络问题。

    容易陷入的陷阱:

    1.没有数据库自我检查结束,就潜意识以为是DB 问题,其他方面出现问题的可能性没有考虑全[硬件、网络、业务本身问题]。

    2.处理问题的全局性不够,没有再次出现问题就以为事情解决了,也没有后续跟进修改业务参数以后的效果。

  • 相关阅读:
    python基础练习(七)列表、元组、字典遍历
    python基础练习(六)字典_练习
    python基础练习(五)元组_练习
    python基础练习(四)列表_练习
    滑动条设置为角度
    cell-元胞数组
    MATLAB 爬取天气预报数据
    正则表达式匹配
    函数检视
    相关分析(三)——如何在Excel中计算两个变量之间的相关系数?
  • 原文地址:https://www.cnblogs.com/liushuiwuqing/p/6647346.html
Copyright © 2011-2022 走看看