天道不一定酬所有勤
但是,天道只酬勤

一次万博manbext手机版连接池满问题排查与解决

GitHub 24k Star 的Java工程师成神之路,不来了解一下吗!

之前一段时间,业务在线上经常出现频繁的万博manbext手机版连接池满的报警,报错信息如下:

Caused by: ERR-CODE: [TDDL-4103][ERR_ATOM_CONNECTION_POOL_FULL] Pool of DB 'cn-zhxxx_i-xxx_fin_risk_xxx_30xx:33.10.xxx.xx:30xx' is full. Message from pool: wait millis 5000, active 10, maxActive 10. AppName:FIN_RISK_xxx_APP, Env:ONLINE, UnitName:null. 

然后去排查了一下SQL耗时,发现有大量的耗时SQL,并且执行耗时和锁耗时差不多是相等的。

然后看下这条具体的SQL语句:

UPDATE collection_case
SET gmt_modified = now(), lock_version = lock_version + ?, hands_count = ?, case_state = ?,  max_ovd_days = ?, case_class = ?, cur_ovd_principal = ?,collection_amount = ?
WHERE id = ?
  AND deleted = ?
  AND lock_version = ?

其实就是简单的一个更新语句,其中使用了乐观锁进行并发控制。

为什么乐观锁还会导致大量的锁耗时呢?

虽然乐观锁是不需要加锁的,通过CAS的方式进行无锁并发控制进行更新的。但是InnoDB的update语句是要加锁的。当并发冲突比较大,发生热点更新的时候,多个update语句就会排队获取锁。

而这个排队的过程就会占用万博manbext手机版链接,一旦排队的事务比较多的时候,就会导致万博manbext手机版连接被耗尽。

这类问题的解决思路有以下几个:

  • 1、基于万博man手机客户端进行热点数据更新,如Redis。
  • 2、通过异步更新的方式,将高并发的更新削峰填谷掉。
  • 3、将热点数据进行拆分,分散到不同的库、不同的表中,减少并发冲突。
  • 4、合并更新请求,通过打批执行的方式来降低冲突。
  • 其中,第2个和第4个方案,存在一定的延迟性,会把实时更新变更异步更新,存在一定的数据实时性问题。

    第1个和第3个方案,实现起来成本比较高,但是相对来说更加完整一点。

    根据我们的实际业务场景,我们选择了第4个方案,将更新操作进行合并,批量执行。

    比如本来需要100个并发都给用户增加积分,那么改成10分钟更新一次,一次就把10分钟中内的所有需要增加的积分汇总之后一次更新用户积分表即可。

    (全文完)

    扫描二维码,关注作者微信公众号
    赞(0)
    如未加特殊说明,此网站文章均为原创,转载必须注明出处。HollisChuang's Blog » 一次万博manbext手机版连接池满问题排查与解决
    分享到: 更多 (0)

    评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  • HollisChuang's Blog

    联系我关于我
  • 微信咨询
    关注微信:themebetter
    复制微信号
  • 去评论
    去评论
  • 回顶
    回顶部