记一次线上DB被打挂

2023-03-08,,

这周刚新上了需求,在慢慢写代码的时候,突然报警群的消息多了,组长让我看看咋回事。

一开始没当回事,因为faas任务的错误日志一直很多,但是发现新的日志和以前大不相同,显示的是上游faas实例的连接被mesh拒绝。

我也没啥好办法,只能先去看看实例数量,再看看DB的QPS。

监控DB单实例QPS才3K多,平时刷数据一直这个量,所以我就觉得没问题 。

又看了看DB的CPU和io吞吐,也没到高水位,那想必不是DB问题,我就截了个日志图丢小群里继续写代码,毕竟faas任务也不是我管的(笑)。

后来faas任务的错误日志越来越多,终于吃饭时候主机房DB挂了,这会大家都急了,直接拉DBA,一看DB实例代理的CPU已经完全打满,连接数触目惊心,我才发现原来我司每台DB的端口都是有代理的。

然后DBA重启代理+扩容,终于恢复了主机房可用性。因为我们的faas任务横跨两个库,另一个大团队的通用库也打挂了,导致一小段时间整个业务写请求全部受到影响,但是幸好日常写请求不多,而且异地机房的从库很正常,所以大家也没发现。

最后小群里归因复盘,主要原因有几个:1.当天其他部门上游产出的领域事件比日常多很多,导致下午都没有消费完,平时只限于早上的高峰,问题暴露不明显;2.鸡架的领域事件设了无限重试,导致消费失败后的毫秒级重试,最后引起雪崩。这个最后是关闭重试,因为相关数据状态第二天数仓也会做同步,所以影响业务不大;3.那天调整了数据库连接池,将线程使用连接后放回连接池的时间延长了六倍,导致不得不重复创建连接,最后把代理打满;4.鸡架的限流设置并没有什么用,上游限流值设置完全失效;5.当天其他部门产出了重复的领域事件,为此当天还产生了数据库死锁的问题


所以如何解决问题,说实在作为一个组内地位最低的搬砖仔我也没啥好办法,感觉这就是管理和架构设计问题。

我们用的faas动态扩缩容,通过触发器实现消费,可以说是较多实例和较小QPS的方式,最后来批处理大量的数据,这种和传统批处理比有优有劣。

显而易见的坏处就是多实例可能会同时创建大量的连接,而不是选择复用连接,资源占用的高峰和低谷都很明显。

靠触发器而不是定时任务,以后会随着需求越来越多,占用资源的峰谷更加不稳定,带来更大的问题。

然后就是不好管理,如果鸡架稳定性不行,新创建的实例可能在每次初始化的时候都会有问题,这点不如单独部署若干台机器长期待机。


关于数据库死锁也提一嘴,批处理的时候尽量避免事务和同时更新同一行数据,如果要用事务也要尽量把同时更新的数据切小,不要同时锁住大量的行。

大厂的隔离级别一般都是读已提交,这种情况下MVCC依然有效,只是没有了间隙锁,读也是当前读,只要不是同时更新相同的大批量行问题还是不大的。

记一次线上DB被打挂的相关教程结束。

《记一次线上DB被打挂.doc》

下载本文的Word格式文档,以方便收藏与打印。