雪花新闻

光大银行分布式实战:缴费平台的数据库架构转型

本文由 dbaplus 社群授权转载。

我今天分享的主题是《高并发场景下,光大银行分布式数据库的架构转型实战》。

光大银行也是很有魄力的,拿出了一个重要的业务系统进行一次试点,做了一次这种分布式架构转型的项目。我有过十余年 DBA 相关的经验,不过之前接触比较多的主要还是传统的商用型数据库,所以能作为这次项目的推进人,也是我个人在这种新的架构下的一次学习的过程。

一、光大云缴费平台的基本情况

先给大家介绍一下今天分享的这个平台情况,对于一些业务的数据概况,可以见下图:

这个系统上线当初,是和其它的业务系统放在一起的。在 2015 年和 2018 年,考虑到业务和成本等多方面的因素,经历过两次业务剥离,最终在 18 年成了一个单独的平台。

里面涉及的缴费种类包含 20 大类,其中有 8000 余个缴费的项目,接近 500 个缴费渠道,目前覆盖国内 300+ 城市。平时大家生活中使用比较多的像水费、电费、生活费的缴纳,可能都是通过这个平台来完成的。目前,它已经被打造成为行内 TPS 最高的业务系统:

上图的这些数据,可以看出从 18 年 5 月开始,交费平台的各项数据有大幅度的增长,有的甚至是翻倍的增长。这些指标可以作为衡量一个业务系统是否有健康良好发展趋势的依据,但是转到后台,最终都代表着给数据库的压力是一个什么样的变化。

二、传统 IOE 架构的基本优化及面临的挑战

目前数据库传统的 IOE 架构是这样的:

包括云缴费系统,它用的也是这种传统的 IOE 架构,在部署模式上是采用的双中心 RAC 2+2 的冷备部署:

在这种传统的 IOE 架构下,我们通常会做到一些优化,大致如下:

其实做了这么多的优化,包括还有很多其它的优化,主要目的都是为了减少 IO 请求,通过物理设备的性能提升来保障业务能有一个稳定、快速的交易响应时间。

但是,这些可能都是只对读 IO 有作用的,也就是通过尽量减少它的物理读及 buffer 读,来提升业务 TPS,并降低 ART。但是对于写来说,主要是由业务需求决定的,所以从数据库层面,至少从这种传统的架构层面是优化不掉的,因为这个是它业务传导过来的一个最基本的写的指标。

所以我们总结了一下,在传统的架构下,会面临这样的一些挑战:

三、光大的分布式数据库技术调研及思考

所以光大银行对分布式数据库的技术做了一些相关调研。

1、分布式数据库核心要点

对于数据库来讲,其实它的核心其实就是 SQL 解析、事务控制和数据存储与访问。像数据复制、备份恢复、可用性切换、数据迁移、操作调度、开发接口、权限管理、对象管理、监控报警等等,这些都是它整个的一个生态。这些工具有没有、高不高效,就决定了运维的工作能不能更好的开展。

所以,分布式数据库其实就是将传统数据库的各技术组件通过松耦合的方式部署,通过网络之间,会有一个相互的协同工作,达到分散压力,提升总体处理能力的目的。也就是把我原来的瓶颈打散了。

但是被打散之后,各个组件之间可能网络通讯成本就增加了,所以在提升总体交易吞吐量的同时,平均的响应时间也就是 ART 可能就会增加。拿云缴费这个系统来说,我们测试的时候发现原来二十几毫秒的交易,到分布式上可能就会多个十几毫秒,或者再长一点的时间,主要整体是受到一个链路的影响。所以分布式并不能减少交易响应时间,但可以通过它的扩展性,带来交易响应时间的稳定。

那为什么我们的测试发现在分布式上交易响应时间变长了呢?主要是因为原来的数据库还没达到瓶颈。等到原来这种传统架构的数据库达到一个性能瓶颈,出现性能拐点,那时候一定会出现一个大幅度的性能抖动或者滑坡。但是在分布式架构下,我们就可以通过它横向的扩展能力,让平均响应时间基本维持在恒定的一条线上。

目前,分布式部署技术很多企业都在用,但切入点是不一样的,而且也形成了多种技术路线,并且这几种路线,从我们的调研来看,也都在不断地演进。

2、常见分布式数据库的技术路线

我们的分布式数据库技术调研发现,基本上可以分为三类:

1)应用层分布式架构

主要是通过应用架构的设计,将业务数据分散到多个数据库存储。

这个其实也算是一种单元化吧,所以这层主要的核心是在于对进来的交易做一次解析,然后在交易通过应用层之后,解析完成了,它知道自己该去哪个数据库,去访问哪些数据。

2)NewSQL 分布式数据库

数据以物理分片的方式,把数据打散,分散到若干个存储节点。它是在存储层实现分布式的数据扫描和过滤。

3)数据库访问代理中间件

最早像 tomcat,也算是一个分布式中间件。这种通常都是选择恰当的分片键,通过分片键来将数据打散,然后在应用访问代理的时候,将 SQL 按照它的分片规则做一次解析,解析完成后,来实现对各个分片进行单独访问。也就是说,相当于是做了个 SQL 的拆分,由它路由到我指定的数据库上,访问指定的数据。

这是目前常见的几种分布式数据库的技术路线。

3、总结

接下来我们总结和整合一下:

第一个是分布式应用架构层面。目前在分布式数据库应用架构的路线上,就是做的分库分表,一般都是产品 / 厂商自建的。因为这种一般都比其它的与应用的业务特点,结合的是更加紧密的。对于单系统来说,它单独地进行了一些分析,对业务进行了一些拆分,效果是比较突出的,但这种模式不容易推广,因为一旦做一个系统,就需要对系统所有的交易、数据库的设计、表之类的重新梳理一次,比较费时间。不过效果确实很明显,目前这么做的系统也不少。

第二个是分布式代理中间件。主要是通过分布式代理中间件,在一定程度上实现了自动化的分库分表。实际上就是按照分片键的规则将数据拆分了,由它来进行分库分表的操作。所以这个性能还是跟应用设计有很大关系的,如果大表找不到合适的分片键的话,用这种数据库可能就达不到预期的效果。所以这类我们觉得是可以作为分布式应用架构的一种比较好的补充。

第三类就是 NewSQL 分布式。这类的性能扩展对应用相对透明,但是这些产品出来的时间相对来说都不是很长,还在演进中,开发接口等方面可能就存在一些限制,并没有前两种分布式的架构那么灵活。

四、光大自研的分布式数据库 EverDB

光大结合调研结果,采取了两个技术路线:一个是 NewSQL 的引入,一个是想要自研一个分布式数据库,也就是 EverDB。

1、EverDB 分布式数据库分层设计

EverDB 有三个主要的组件:

然后数据库实际上用的就是 MySQL 集群。数据节点采用的就是 MySQL 数据库,对部署模式没有什么限制,支持多种部署模式。

2、EverDB 分布式数据库主要功能特性

1)数据分片

2)数据存储

3)横向扩展

4)迁移备份

5)开发应用

所以在开发上面,可能确实和原生的 MySQL 是有一定的区别的,但是已经可以满足我们目前大部分的应用逻辑设计的需求了。

3、EverDB 分布式数据库测试重点

在整个改造的过程当中,数据库测试算是我们的一个重点工作,主要集中在两方面:

1)测试场景设计

这次数据的迁移改造,我们一共设计了 30 余个测试场景,其中主要包括:

2)测试关注的指标

4、云缴费系统实施重点

在云缴费系统实施的过程当中,也有一些重点,简单给大家介绍一下:

1)逻辑设计

2)开发设计

3)批量设计

4)试运行方案设计

刚才提到的 bridge 的工具,就是我们现在在试运行,以后会正式运行的一个主要的逃生方案。这种新技术产品带来的架构风险,一定要有逃生方案才能比较有信心在上面跑,在极端情况下,可以将新架构隔离开,让它回到相对来讲比较传统的架构上去。

目前云缴费架构已经算是改造完成上线了,但是它并没有完全接轨 Oracle 的真实交易,是在应用层做了一个转发,把发给 Oracle 的交易同步发给 EverDB 一份,然后通过这个试运行阶段,来验证产品的兼容性、稳定性。这个也算是个过渡阶段吧,因为只有经过真实生产的全量交易的压力后,我们才敢把其它的交易完整切过去。

所以这块儿的设计也挺重要的,如果直接就新上的话,可能会出现各种各样预期外的问题,解决起来可能也会无从下手。我们利用交易转发的机制,还在验证这种新架构的运行模式。对这种并行试运行的方案还有逃生方案,都要进行充分的测试,最终目的就是保障数据安全,同时这种逃生环境要能承载一定量的业务运行,毕竟它节点数不会有分布式那么多,所以如果业务全部切过来的话,它可能运行起来会遇到一些资源征用之类的问题。

5、云缴费系统部署架构

这张图是云缴费系统部署架构的一个真实的 1:1 的物理图:

它前面是 APP 的数量,一共是 24 台,后边用两个 grid 节点,然后有两台备份的服务器,和两台逃生的服务器。中间的区域全是 MySQL 的集群,全都是主从,采用的是一主三从的模式,目前是双机房运行。每个机房里有一主一从,另一个机房里有两从,然后通过配置,我保证同机房和跨机房有两个节点是数据强一致的,另外一个节点就不管了。这样如果发生故障的话,由 grid 这层会告诉它哪个节点的数据是最新的,是一致的,这样就会切到那个节点。

6、云缴费系统试运行总结

目前云缴费系统试运行也有半年了,这里是对它简单的一个总结:

1)分布式改造收益

2)运维方案积累

因为这个对于我们来说也是第一次做这种比较大的改造转型,所以在监控指标及监控方案、故障场景的应急预案、分布式数据库的技术标准 & 规范等,都是通过这次的探索和迁移总结出了一些经验。

3)产品自身完善

4)技术难点

目前我们碰到的一个技术难点就是交易全链路监控分析。因为这个交易链路从外部到前端的 F5,再到 AP,再到 F5,再到 grid,再到 MySQL,包括可能 grid 之间(也就是中间件节点之间)可能会有些数据同步,MySQL 之间也会有些数据同步,所以这个交易链路实际上比以前变得是太长太长了,所以现在如果某一笔交易慢了的话,可能在一些有日志的节点上,或者说日志做的比较完善的话,可能还是有迹可循的。可是如果网络抖动了一下,或者是出现一些延时的问题,目前看这种全链路虽然不是不能监控,但至少还没能实现一笔交易完整的一个追溯的过程。

五、EverDB 后续发展规划及里程回顾

1、后续发展规划

1)近期

增强运行稳定性,提升分布式事务性能。目前来讲,我们对于 XA 事务的处理可能性能上还有一定的优化空间,同时我们也希望这种数据库能够支持国产 ARM 平台和国产操作系统,能够接近于全系的安全可控标准;

2)中期

3)远期

如果说的再远一些,就是希望支持更多种底层数据存储引擎,不仅仅是 MySQL 了,可能还会有金融其它的数据库产品,并通过这种方式来扩展我们的应用场景。

以上就是我们后续想对分布式架构做的一些主要的工作。

2、里程回顾

这里展示了我们整个的一个里程碑,从开始改造到现在经历的一些比较重要的时间节点:

其实架构转型,收获还是很大的,对于分布式的一些优势、劣势,包括它能做什么,不能做什么,如果没有完整地做一次的话,了解的就没有这么深入和具体。以上就是我今天给大家分享的全部内容。

Q & A

Q1:分片集群一致性备份策略是怎么样的?跨机房切换后性能下降后怎么和应用联动的呢?

A: 是这样,关于备份,是可以在 grid 层面获取到每个数据节点的一致性点的,可以通过这个一致性点,对后端的 MySQL 做一个相应的备份。关于跨机房切换后性能下降的问题,从 1:1 的架构图里,可以看出,我们做了服务器数量上的冗余保障,即便只在单边机房运行,每个服务器上也只有一个主节点,不会出现切换后一台服务器存在多个主节点导致的资源争用问题。

Q2:MySQL 使用的是什么版本呢?

A: 目前使用的还是 MySQL 5.7.26,暂时还没考虑 MySQL 8。MySQL 8 我们也在学习当中,因为它目前出现的时间也不算太长,相对来说现在比较稳定的还是 MySQL 5.7.26 或者 MySQL 5.7.28 这种版本。

Q3:跨机房的延时怎么解决呢?

A: 其实跨机房的延时很难解决,因为你要保证数据一致性的话,跨机房的延时是一定要等的,就像 CAP,可能保了一致性,就要牺牲一些别的东西。这个可能不同的领域有不同的权衡吧,也许对有些能够牺牲一致性的业务来说,对这块儿就可以把延时问题规避掉。但是涉及到转账,这种账务问题,可能还是没办法解决掉延时。其实在发生故障切换的时候,我们必须要保证另一个机房是有一份完整的数据的。

Q4:分片表主要就是业务流水,全局表就是类似人员信息这种主数据?

A: 差不多,这个也主要是在开发层做的设计。对于表的分类大致是这种方向,因为其实就是流水表、日志表最大,这种表在原来的 Oralce 的部署里面就已经做了一层甚至两层的分区了,只不过它提供的存储还是在一个里边。在这块儿,如果将分片表按照分片键做了拆分,实际上就已经部署到不同的物理分区上了。

Q5:选择合适的 MySQL 字符集,选了什么,utf8mb4 吗?

A: 是的,用的就是 utf8mb4。

Q6:分布式,是否涉及到多个库完成一个事务?若有,如何保证事务完整执行?

A: 分布式肯定是要涉及多个库的,这个实际上是已经跨了物理的分区和我的 MySQL 实例的,这个目前在云缴费的批量交易里是存在的,其实大部分联机都规避了这个问题,所以在批量交易里有这么个事务,就是用的 XA 的事务协议,来保证事务的完整性。

Q7:数据库节点变多,是如何做到备份统一调度的?

A: 这个其实跟刚才 Q1 是一样的。实际上我们备份的时间还是选择在业务相对低峰的时间段进行的,可能凌晨几点这样,因为确实在获取一致性点的时候,对业务是有点影响的,所以当节点变多的时候,影响可能会有点放大,不过也不会太大,而且又是凌晨两三点的那种基本上交易比较少的时间。所以还是通过数据一致性点来做的统一的调度。

Q8:分布式数据库,多大尺寸时,得再拆库?或者,达到其它什么指标时,得考虑再拆库?

A: 这个主要还是看物理分区的容量。因为这个用的不是存储,而是 nvme 的闪盘,也是为了保证效率,所以这个盘的扩展数量肯定是有限的。还有就是 CPU 和内存,当这几方面,还有单点承受的一些 QPS、TPS 指标,当它承受到一定量,可能会有些风险的时候,可能就会提前做一些数据节点或分片水平扩展的操作。

Q9:备份是如何发起的,有统一的数据库备份平台吗?

A: 备份发起使用 control 的那个管理组件,它实际上是一个外部的管理台,用它来调度响应的备份策略的。

Q10:对 SQL 有限制么,中间件会有内存溢出的风险么,mycat 落地中间数据,有内存溢出风险

A: 目前还没出现,关于溢出这个问题,目前在测试环境应该是压到了差不多 10000 左右的 TPS,目前看着是没有什么问题。

关于对 SQL 的限制,是指语法吗?语法上是确实有些限制的,比如对于过程的调用、临时表表或是 left join 之类的操作,具体的限制要通过开发手册作为指引,但目前基本已经支持了绝大多数的开发语法。

Q11:可以实现在线扩缩容吗?具体原理是怎样的?

A: 有两种,一种是要扩物理的机器,一种是要加 MySQL 实例。扩机器的时候,就是挪动主从的位置,其实也就是一个切换,对局部影响有,但比较小,从测试结果来看,比加实例挪数据的影响小得多。

Q12:读写分离是基于中间件还是业务层处理?

A: 是通过中间件来做的,具备读写分离功能但目前未启用,主要是因为试点业务没有这个需求,所以不是目前主要的测试目标。

Q13:DDL 变更怎样保证所有节点一致,如果某个节点执行失败,怎么处理?

A: 其实现在对于 DDL 的原子性还是没有一个很好的保障的,但是对于 DDL 操作是有相应的检测命令的,所以在 DDL 场景下,可能还是需要通过操作的标准规范来避免这个问题。比如说,DDL 命令下去之后,要返回一下我所有 DDL 修改的结果,因为它毕竟涉及到多个实例,目前还没有很强的一个 DDL 保障。

作者介绍:

于树文,光大银行资深 DBA

原文链接:

https://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&mid=2650792712&idx=1&sn=e8b25231d00b76f9e651663ea1cc63d9&chksm=f3f9569dc48edf8bbadb3b805474a8712ec1ddd14c7ddd627b55c898e9b02b407ec04ed0e688&scene=27#wechat_redirect

相关文章