工商银行核心应用 MySQL 治理实践

极客挖掘机

共 5738字,需浏览 12分钟

 ·

2021-01-15 03:06

摘要:本文根据2020年DTCC数据库大会分享内容整理而成。工商银行在2014年就开始推广使用MySQL。时至今日,生产环境的MySQL节点数量已经发展到近万个;应用场景也从外围低等级应用,推广到核心高等级应用。此次与大家分享,为承接核心业务数据存储的重担,工商银行在MySQL应用治理方面的思路和方案。



演讲者介绍:林镇熙,工商银行小兵一枚,2014年开始接触MySQL,将MySQL 5.5、5.7版本引入工行。负责MySQL架构设计,开发规范,以及相关技术培训工作。

工商银行在核心应用MySQL的治理,主要分为三个方面:目前面临的情况和挑战,为了解决这些问题的思路和具体的方案,最后是后续提升的思路。

现状与挑战

1.1、现状 

这是行内MySQL的部署节点数发展情况,从2019年6月开始到现在,在短短的两年期间,MySQL节点规模上涨得非常厉害,翻了几番。绿色部分是目前这些节点当中的核心应用节点数的情况。核心应用占的比例其实是比较大的,有两个方面的因素:一方面是行内在数据库使用的策略上,对于新增的数据库节点,如果没有特别要求的话都会使用MySQL数据库;另一方面是与行业内业务发展情况相关,行内对于高容量、高并发、弹性扩展的业务需求非常旺盛,这种情况下对于分布式架构的数据库要求越来越多,所以对于分布式内容的应用规模也会比较庞大。

行内将应用分为ABCD四个等级,最高等级为A类应用,核心应用就是指最高等级的A类应用。


1.2、面对的挑战:

行内对高容量、高并发、弹性扩展的业务需求比较多。目前基本完成了分布式体系的建设,满足业务的需求,MySQL也是分布式数据库体系的一部分,除了数据库之外也实现了分布式服务、软负载、分布式事务、分布式消息、批量、缓存、对象存储、文件存储,加上数据库等,共有九大运行支撑平台。通过这些平台的组合,形成了完整的分布式解决方案,满足业务的要求。

关于运维方面的压力,现在MySQL节点数量非常庞大,对于生产运维来说,为了能够支撑这么大的体量,运维的压力非常大,包括监控告警、故障恢复等。如果没有借助自动化、智能化的手段是很难满足运维的要求。这里我们是与第三方公司一起合作研发MySQL的管理平台,具体的是爱可生公司。我们也经历了很长的一段合作时间,能够把这套东西打磨出来,基本覆盖了完整的运维流程,特别是对故障的诊断和自动化的切换,效果也是非常好的。在这么多节点的大基数情况下,发生故障的总体概率会相对较高,但都可以很好地应对,在故障时迅速切换,基本不会对业务造成影响。


现在这么大的体量,如果按照传统物理机的部署模式,资源浪费会比较大,特别是在CPU方面。因为MySQL正常使用的话,CPU资源一般都会比较低。这个问题行内看得比较远,资源规划方面已经实现了90%的容器化部署,目前大部分MySQL已经运行在容器上面,效果也非常明显,使用率能够提升4-5倍的程度。

本次我想重点介绍的内容是,现在核心应用接入到MySQL,怎样才能保证生产运行的过程中,降低问题的数量和影响的程度?可以分为几个方面来讲:事前,我们希望能够在研发阶段尽快发现一些问题;事中,降低问题的影响;事后,希望快速定位到问题,迅速地予以解决。

治理思路与方案

这些就是对治理思路的总结。首先是基础规范的管理工作。对于我们所需要做的工作,所有要求都是应该落在规范上面,希望做到有理有据,对于后面问题的定位和责任的划分都会非常有帮助。在此基础上,我们进行三个方面的治理工作,包括事前、事中和事后。


  2.1规范起到的三个作用:

首先规范能够制定操作的标准,例如建表的时候该怎样,每张表必须要有主键,建库建表甚至设计字段的时候不允许在SQL当中添加字符集和排序规则的属性,默认实例的属性就可以。

其次规范可做量化的控制,有时要求一条SQL扫描的数量与返回的数量都不能太多,执行时间不能太长等等,从定性角度看问题都不大,但要落到实处,这样的要求是不够的,因此需要提供量化的指标。比如对慢SQL,要求联机交易扫描的行数和结果集行数比不能超过100:1。对于一个事务,更新的数量不能超过10万条。指标在开始设计时可能并不完美,但在使用的过程中不断研究、完善,就能够定出来更细化的指标。对于开发或是运维,都要对这些程序的设计和运行有一个底线的意识,一定不能越过这条线。

再是为了避开一些Bug。一个例子是,大表的Truncate会导致数据库hang住,昨天农行的同事也有讲到,大家遇到的问题基本都是一样的。另外一个例子是Replace into的Bug,会导致主备的元数据信息不一致,如果发生切换,新的主库插入数据的时候会出现主键冲突,这个问题相对比较大。为避免此类问题,规范上会要求不允许使用。

2.2具体规范内容有两个特点

供大家参考:
规范应该是容易被理解的,所以在规范中特意针对每一个条款增加了一个解读的内容。虽然规范提出了一些要求,但在具体落实时还会有很多人并不知道为什么会有这样的要求。所以在文档当中增加了很多解释,可以让读者很清晰地知道,除了不能这么做之外,还能知道为什么不能这么做。

对于规范当中的内容,会尽量安排落地,例如事前的治理方面,涉及到表结构和代码的审核系统,都是基于规范的内容安排具体的落地。所以规范才会真正变成非常有效的工具,不会是一纸空文。


2.3我们三个主要工作,事前预防,事中应急,事后诊断。

首先是事前预防工作:


表结构的审核,是规范要求的落地实现,包括每个表必须建立主键,禁止单独设立字符排序规则,或者使用TimeStamp的数据类型等。行内目前的表结构审核系统,除了进行审核之外还负责进行版本控制,主要有两种情况:对于新增表,建表的语句是由审核系统生成的,不需要人工来写代码,可以减少很多不必要的错误。这一点我也是深有体会。之前看到不少同事的表结构是从一个地方拷贝过来,有些属性不是很理解,特别是表的属性中存在存储引擎的属性、排序规则的属性,不知道的话就自己带进来了,里面的要求可能都不是我们想要的。现在我们都是统一使用InnoDB引擎,要是不小心的话就会把MyISAM的表带入进来,所以隐患还是比较大的。表结构变更,例如加一个字段或加一个索引,这也是由表结构审核系统生成,不需要人工实现。


代码审核方面,我们在MySQL审核基本上都是基于MyBatis的开发方式,包括配置文件的扫描和实现,下面举的例子就是代码审核的要点。现在也是在持续地补充和完善。


健康检查方面,可以举个例子,是关于慢SQL。这也是大部分公司在MySQL遇到最多的一类问题。我们利用MySQL中的一张视图进行分析,作为检查的一个依据。这张视图中记录了每一条SQL从MySQL开机到现在运行的计数器,比如截止到目前运行的次数,花费的时间,扫描记录的条数。我们利用这张表的计数器的特点,在两个时间点采集相同的表的数据,并且将两个时间点的数据进行比较,可得到这段时间内这些SQL运行的指标。对于相同的语句在八点钟采集一次,在九点钟采集一次,之后两个数据相减就知道SQL在八点钟到九点钟一共执行100次,执行时间是900秒,扫描记录数是9000万。从这个数字来看,有些比较敏感的同事,会发现单条记录的执行时间应该是偏长的,并且单条记录扫描的记录数也明显偏多。那么这条SQL就有一个明显的效率问题,需要进行整改。大部分问题都是可以通过增加索引来解决。


事中应急


事中主要考虑应急,并且是自动化应急。接触过生产的同事对应急应该是深有感触,要遇到一个问题之后开始分析、定位问题,最后采取措施,中间这段时间可能是相对不可控的,有时很快能够处理,但也有需要几十分钟甚至几个小时才能处理完毕,这时已经对业务造成了非常大的影响。因此我们更多的要考虑,怎样实现这种自动化的应急手段。

关于监控查杀,我们希望能够通过监控实时地捕捉到性能上的问题,进行自动查杀的操作,也就是把对应的线程杀掉,避免问题的进一步扩大。刚才多次提到的慢SQL,是我们面临的最大敌人,主要包括两个方面的危害:很多时候,有大量的数据扫描,导致吃CPU资源。在大并发情况下,一条SQL可以吃掉一个CPU,几十个SQL就能够把服务器的CPU吃光,问题的影响也是非常大。SQL执行慢,并且有多个线程堆积的情况下,可以把InnoDB的线程池耗尽。在这种情况下,原来一些没有问题的SQL,在执行的时候就会明显被拖慢,导致整个系统交易全部受到影响。所以就不仅仅是慢SQL的交易,整个系统的交易都会存在问题,影响很大。


我们对此已经实现联机交易的自动查杀功能,通过设置一个阈值,对于超过这个阈值的SQL自动杀掉。具体原理比较简单,通过类似ProcessList得到时间点和线程ID,然后去查杀。在这里有个特别要注意的地方,为了实现这些,我们做了联机和批量用户分离操作,针对不同用户进行差异性处理。主要是因为联机和批量的特性不一样,批量的SQL有时会要做大批量的处理,时间是会比较长,这是很正常的。联机基本上是短平快的操作,大部分都是毫秒级的,稍微慢一点的可能是几秒钟,但十几秒、几十秒的话就是不正常了。所以是在用户分离的前提下再进一步做慢SQL的查杀。


关于大事务,我们的定义是在一个事务当中增删改的记录数超过一定的阈值。目前定义的阈值是10万条记录,超过10万条就定义为一个大事务。具体危害性可以从这张图进行介绍。每笔交易都会经历一个记录binlog再从备库返回的过程,这是MySQL半同步最基本的操作。如果记录的内容比较大,那么具体的量也随之非常大,不管是写入、传输还是落地方面时间都会有明显差异。目前我们觉得最大的问题在于,MySQL主库写入binlog的处理都是单线程的,如果有一个交易写入,其它交易都是排队的状态。如果出现大事务的话,其它交易就会被卡住。


在主库出现堵塞的情况下,高可用的机制可以探测到主库长时间不可用,我们就会去做主备的切换。但是在大事务的情况下,切还是不切是比较大的问题。大事务的写入、传输和回放需要经历一个比较漫长的阶段,如果马上用备库的话,数据就已经不是最新的,也就是会丢掉一些数据;如果我们等待回放,做完以后再切,可能时间就不可接受了。所以这是一个两难的问题,我们要尽量避免大事务。

为了做到严格的控制,我们也对大事务实现了自动查杀,对于超过一定的阈值自动执行和操作。

自动查杀也不是立即能够实施,需要经历不断的小范围的试点,先做监控报警,再做自动查杀,这样一步一步走下来。


有候我们开玩笑,谈到删库跑路,例如遇到程序Bug有些数据会被误删,或者更新成其它我们不需要的数据,这时候就需要进行数据恢复。常规的办法是存量备份和增量BinLog进行追补。可追补的过程中是单线程的,基本上很难实施,因为存量备份都是每周一次,要是恢复的数据是五六天之前,追补的数据范围会非常大。我们采用两种方案:伪装成Slave进行回放,网上已经有现成的案例;为了更快地进行恢复,我们借鉴了一些业界恢复工具,主要包括两类,一类是DML,比如Delete转化为Insert,另一类是基于文件系统工具进行恢复。


最后是事后诊断


最重要还是数据的采集能够完整到位,对事后诊断才是有帮助的。除了常规的数据采集,针对MySQL,还有些高密度和低密度的采集。高密度是针对后台线程情况的采集,是为了解决一些瞬间的性能波动,有时只是一两分钟或者更短的十几秒、几十秒的波动,通过高密度的采集能够作为事后分析的依据。低密度是刚才提到的慢SQL的性能数据,目前是十五分钟采集一次。SQL的历史执行情况对问题分析也十分有帮助,也是十五分钟采集一次。

后续提升思路


 3.1、首先是问题的定位,

有两方面:
在问题发生之前,怎样在研发测试环境,甚至生长环境能够提前捕捉到;问题发生的时候怎样能够迅速地定位到问题,迅速采取一些措施解决。前面有提到检查和自动化的处理,但还是远远不够,还是有很多的提升空间。

 3.2、其次是问题的预判,

据一些性能数据,包括性能指标和SQL的执行情况、发展曲线提前进行预判。比如有些表刚开始的数据量不是很大,即使有些SQL效率不高,执行的情况还是可以接受的。但随着数据量的增长,执行时间和扫描数据量都在不断攀升,在达到一个临界值影响到具体业务之前,我们希望能够找到它,并且尽快修正过来。

 3.3、最后是关于问题的自愈,

现在希望借助于智能自动化的手段,能够在出现问题的时候自动地做修复,避免这些问题进一步扩大。例如,有些程序写得不够好,就会出现全表扫描的情况,如果是在出现问题后再去定位添加索引,时效性会比较慢。希望我们的程序能够自动发现这个问题,然后加上一个索引,可以让这个业务基本上不受到影响。
以上就是我的分享主题,可能讲得也不是很深,都是比较浅的东西,希望大家能够多多指正。

嘉宾:工行的核心系统是开源自己搭建的还是商用的产品?

林镇熙:我们是用MySQL社区的开源版本,5.7,我们是一主多从、两地三中心的架构。


嘉宾:你们是容器化部署还是物理机部署?

林镇熙:我们90%以上都是容器化部署,就是使用K8S架构解决方案,存储是使用本地SSD。


嘉宾:工行使用MHA架构吗?

林镇熙:我们刚开始也有考虑,分析下来MHA有一定的缺陷,所以我们是跟第三方公司一起合作研发一整套的运维平台,去实现故障的判断、定位和切换。


嘉宾:相当于工行自己研发了另外一套高可用系统是吗?

林镇熙:是的。


嘉宾:工行还有10%的MySQL跑在物理机上面是吗?

林镇熙:是的。


嘉宾:工行容器化单机可以跑到多少实例数?

林镇熙:1个主机是4个以上的容器,现在上线的是4-8个左右。


嘉宾:本地SSD还是共享存储?

林镇熙:本地SSD。



源:ITPub社区

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!





感谢阅读



浏览 10
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报