编者按
本文由微众银行数据库负责人胡盼盼撰写,介绍了微众银行自年以来从传统RDBMS到NewSQL的架构演进,以及TiDB在微众银行核心批量场景的应用。转眼间,已在微众工作近七载。这期间,一直负责微众银行数据库平台的建设和运营。微众银行在成立之初,IT基础建设就没有选择传统的IOE集中式架构路线,转而选择采用了基于单元化的分布式架构。在这种大的背景下,微众银行的数据库的架构演进,也是走出了一条不同寻常的路线。
一、~,两地三中心时代
在微众银行IT建设的第一阶段,基于成本和效率的考虑,IDC的建设采用了两地三中心的架构(简称IDC1.0架构)。两个同城数据中心作为生产中心,一个异地容灾中心作为灾备。
IDC1.0架构
在IDC1.0架构的基础上,我行设计了基于DCN的单元化分布式架构(DCN,即DataCenterNode的简称)。一个DCN,可以理解为一个从应用层到中间件层,到数据库层的完整的自包含的逻辑单位。不同的业务产品被归类到不同类型的产品DCN;同一个业务产品,再通过一定的计算规则(比如客户号的hash),分配到每一个小的DCN产品单元中;每一个DCN单元会有一个核定的用户承载量;当一个DCN的用户承载量用满时,便可以发起新的DCN单元扩容,以此来实现水平扩展的特性。在实际两地三中心的部署架构中,每个DCN都会有同城主DCN、同城备DCN、异地备DCN三种角色,即每个DCN也都实现了两地三中心的架构。同时,不同的DCN主分片,在同城的两个IDC之间是交叉部署的,以此可以实现DCN单元粒度上的同城双活。DCN主备交叉部署架构
那么,基于这种IDC和DCN架构的前提下,数据库如何选型?架构如何设计呢?客观的讲,在的时候,满足金融级要求的国产分布式数据库产品并不多,可选范围也非常有限。经过充分的调研也评估,微众最终选择了腾讯的数据库产品TDSQL,作为DCN架构下的核心数据库。基于TDSQL,我们设计了如下的数据库部署架构:两地三中心的数据库部署架构
可以看到,TDSQL的部署架构也遵循了两地三中心的原则,分为同城主数据库SET,同城备数据库SET和异地备数据库SET。同城主数据库SET和同城备数据库SET由三个数据副本构成(一主二备),异地备数据库SET由两个数据副本构成(一主一备)。SET内部基于TDSQL的主备强一致数据同步功能,可以实现数据的高可靠和零丢失。二、~,同城多活架构改造
IDC1.0时代的架构基本满足了我行的业务发展需求,但还是存在以下几个问题:
同城双中心之间的数据库同步是准实时的,在极端场景下是有可能出现数据丢失的(同城RPO不为0)
只实现了DCN分片单元粒度的多活,还没有实现真正意义上的应用跨同城数据中心多活;
在单个DCN或者IDC出现故障时,需要做人工的同城容灾切换,耗时太久(RTO约二小时)
同城有6份数据库副本,资源成本较高。
既然有问题,那就得继续优化架构。所以我们提出了第二阶段的架构优化目标:实现应用系统的同城跨数据中心多活;
数据库同城RPO=0,同城RTO接近于0;
降低数据库副本数,减少成本。
首先,我们在同城新增了一个数据中心,由同城的两中心,变为了同城三中心(IDC2.0),这是实现同城应用多活架构的前提。IDC2.0架构图
基于IDC2.0,我们设计了同城三中心多活方案,应用层和数据库的架构都做了相应的调整。同城多活架构
数据库层面,由原来的双中心主备SET的架构模式,调整为单SET三副本跨三中心部署的模式,主节点可以进行读写,备节点只读,可以实现数据库层面的同城跨IDC的RPO=0,RTO达到秒级。以此为前提,应用层就可以实现真正的跨同城数据中心多活。也就是应用层可以在同城的三个数据中心内各部署一套对等的应用系统,接入业务流量,经过接入层转发,最终到数据库的主节点上(开启读写分离的情况下,读流量可以转发到备节点上)。同城应用多活的架构改造,进一步提升了整体的可用性,简化了容灾架构,同时也将数据库的六副本缩减为三副本,极大的降低了资源成本,可以说很好的完成了架构优化目标。三、~,引入NewSQL数据库
随着业务的快速发展,DCN的数量也在快速增加,DCN的水平扩展特性很好的支撑了业务的快速增长。但在某些非DCN架构的中后台业务场景中,单实例架构的数据库逐渐遇到了容量或者性能上的瓶颈。一个比较典型的场景就是安全存证类的数据存储。这个场景属于中后台业务,需要持续存储交易行为类的数据,以供随时审计或者举证,所以一般是不能删除的。随着业务规模增涨,存证数据也会持续的增涨。然而对于单实例的数据库来说,是要求不能超过3TB的存储容量的,一个原因是硬件层面的限制(SSD的单盘容量),另一个原因是单实例过大的容量,会带来数据库性能上的不确定性和运维的复杂性。按照比较传统的解决方案,可以选择基于中间件的分库分表方案来解决这个问题。然而分库分表事实上是对业务开发和DBA都不太友好的一种方案。对业务开发来说,因为分库分表一般在语法和SQL使用层面都会有一些限制和限定,所以一般需要重构代码和SQL,以适配分库分表环境下的数据库使用;对于DBA来说,分库分表的扩展性不是那么灵活,DDL等日常操作也比较得复杂,使得整体的运维工作量增加。我们不想走回分库分表的老路,所以也在探寻有没有更优雅、更先进的解决方案。年下半年开始,NewSQL的概念逐渐兴起,带来了一种全新的ShareNothing的分布式架构的数据库(基本上是以GoogleSpanner分布式架构为原型)。经过充分的调研和评估,我们最终选取国产开源的NewSQL数据库产品TiDB进行尝试。TiDB主要有以下几个特性吸引了我们:TiDB采用了标准的ShareNothing架构,计算与存储分离,并且都可以做到水平扩展,且对业务层透明。TiDB采用MySQL协议体系,与我们当前的协议体系兼容度高,降低业务的开发和迁移成本以及接入门槛。TiDB采用开源的模式进行运营,社区较为活跃,版本迭代较快,并且已有一部分的互联网用户开始使用。
TiDB整体架构
可以说,TiDB的特性可以很好的解决我们的需求和瓶颈,但当时TiDB还是属于一个非常新兴的数据库产品,稳定性和成熟性不够,所以我们也是非常谨慎的进行充分的测试和验证,在生产上首先选取的比较边缘的业务场景进行灰度,并且准实时同步一份数据到TDSQL进行兜底。TiDB在微众的部署架构也类似于TDSQL,利用同城三机房的硬件优势,采用同城三副本跨三中心部署,可以有效的支持应用同城多活架构。TiDB部署架构
经过近两年多的运营,我们已将TiDB应用在安全、智能监控、数据归档、反欺诈、反洗钱、历史交易明细查询等各类中后台业务中。随着TiDB的版本逐渐成熟,整体的稳定性和可运维性也提升了不少。回头来看,虽然我们冒着吃螃蟹的风险,采用了NewSQL的方案而放弃了分库分表的方案,但带来的收益也是巨大的。目前,TDSQL继续作为核心数据库,承载DCN架构下的核心系统;TiDB作为补充,承载非DCN架构下的、对容量和扩展性要求较高的中后台系统。TiDB作为微众整个单化元架构的补充,很好的补齐了数据库层面的短板。四、~,NewSQL在核心批量场景的应用
经过两年多对TiDB数据库的使用,踩了不少坑,也积累了不少经验。TiDB本身随着版本迭代也更加成熟稳定,逐渐形成企业级的数据库产品。年初,我们收到了贷款科技部门针对贷款核心的日终批量系统的优化需求。当时,贷款核心系统的日终批量系统是部署在业务DCN内部的,和联机系统复用DCN内的TDSQL数据库资源。随着交易数据的日积月累,贷款核心系统的批量面临着以下几个问题:批量的耗时持续增涨(优化前已近三小时),如果因为某种原因批量需要重跑,有比较大的超时风险。批量系统和联机系统都在DCN内部署,批量系统带来的数据库高负载,会对联机系统产生影响。受限于MySQL的主备复制的原理限制以及单实例的性能瓶颈,无法继续通过提高应用层并发来提升批量效率。批量效率逐渐成为单个DCN的用户容量瓶颈,而非实际的用户量。
贷款核心批量架构(优化前)
基于以上问题,业务部门也提出了优化目标:将整个批量系统重构(包括应用层和数据库层),核心业务微粒贷的整体批量耗时缩短到半小时内以(在限定的资源内)。将批量系统的资源和联机系统完全解耦(包括应用层和数据库层)批量系统的数据库需要具备可水平伸缩的特性。最初看到这个优化目标,感觉还有挑战的。特别是每天数亿条帐务的批量计算处理,需要优化到半小时以内完成,应该没有那么容量。经过评估,我们最终决定尝试用NewSQL数据库TiDB来承载贷款核心的批量系统(优化后的架构如下图)。批量数据每天通过DCN内的TDSQL近实时的同步到TiDB集群进行汇总,然后由批量应用程序在TiDB集群进行批量计算和加工。经过近一年的持续优化、调整和灰度验证,最终项目顺利上线,并且完全达到了既定的优化目标。贷款核心批量架构(优化后)
下表是微众5个主要贷款业务的核心批量优化前后的耗时对比,优化效果非常明显。在整个项目的实施的过程中,踩坑不少,也总结了不少的优化经验和教训,主要有以下几点:1.应用SQL模型的整体重构和优化针对批量应用的SQL,进行SQLbatch化的改造,提升单个SQL的效率;对于频繁访问的热点静态数据进行缓存,减少SQL的请求次数;对复杂SQL进行内存占用优化、执行计划优化等,降低SQL的耗时。2.基于TiDB的热点数据打散机制优化
在ShareNothing架构的数据库中,数据热点是经常会遇到的一个问题,如果分片规则或者应用的写入的规则不合理,很容易就形成针对某一个数据库分片的热点,导致数据库响应变慢,甚至假死。贷款核心的批量数据表,都是数亿级别的数据量导入,热点问题更加明显。针对这种超大表的数据导入,我们联合数据库厂商,开发了数据表预打散的功能,完全避免了热点问题。3.TDSQL到TiDB数据同步的一致性校验机制优化贷款核心批量的数据正确性至关重要。在优化后的架构,批量数据表需要从多个TDSQL源近实时的汇总同步到一个TiDB集群中,并进行合表处理。为了保证数据同步的可靠性和准确性,我们在三个层面做了优化:对数据同步工具做了高可用架构优化,确保没有单点问题,并且在某个同步节点故障后,可以自动进行替换和恢复;
对数据同步增加全方位的监控,包括同步状态、同步延迟、数据源存活状态、目标端存活状态等;
在应用层增加数据分片同步的实时校验。针对每一个数据分片,应用层都会计算一个CRC校验值,并由上游的TDSQL同步到下游的TiDB,待此分片数据同步完后,在下游再进行一次CRC计算,并和上游同步过来的CRC值进行比对;除了分片校验,还会有数据行数的最终一致性检验。
4.故障SOP预案和兜底机制的建立和演练针对日常的服务器故障,或者数据库bug,导致的批量中断,准备了批量断点续跑的预案,并在生产环境定期演练;
针对可能的数据错乱导致批量需要重跑的场景,通过批前的rename备份表的方式,可以实现快速的批量重跑。
针对极端的灾难场景下,需要重建数据库进行批量重跑的场景,通过批前的冷备数据,进行快速的数据库重建和导入,从而实现批量重跑。
TiDB数据库在贷款核心批量系统的应用,是对微众整个单元化架构的又一次补充和完善。我们经常说,数据库没有银弹,没有一种数据库能够适用所有的业务场景。针对每个场景,用最适合的数据库产品和数据库架构,才是价值的最大化。除了关系数据库产品,我们也大量使用了Redis来适合大部分需要高并发、低延迟响应的读场景。在尽量保证架构一致性的前提下,我们根据业务的实际需求,也少量引入了MonggoDB、PostgreSQL、Oracle等数据库产品。未来,我们也将在数据库的云原生、数据库的智能运维、数据库的硬件国产化、HTAP场景的应用实践等方向继续探索,不断提升和完善我们的架构,为国产数据库在金融场景的应用实践贡献自己的一份力量。本文内容来自微众银行基础科技产品部