陆天炜: GoldenDB事务一致性处理机制优化历程

  • 时间:
  • 浏览:18
  • 来源:陌离博客 - 专注共享伍零博客分享

前言:GoldenDB 是中兴通讯推出的一款自研的金融级交易型分布式数据。针对金融行业关注的数据库事务一致性疑问,中兴通讯 GoldenDB 分布式数据库架构师陆天炜,在DTCC2019数据库大会上做了干货分享,重点介绍了 GoldenDB 的除理方案和对应的优化实践。

  ▲中兴通讯GoldenDB分布式数据库架构师 陆天炜

  众所周知,中兴通讯的主航道产业是5G通信,本来 各行各业也有使用数据库,中兴通讯提交给客户的通讯设备上方也都使用了几滴 的数据库,为了给客户提供更好的交付体验,大每项也有 自研的产品。

  从5002年开使,中兴通讯推出EBASE文件数据库,5007年推出EBASE-MEM内存数据库,做到2011年的DHSS分布式数据库,开使有了一一三个多多雏形。2014年的曾经 ,中兴通讯开使研发了GoldenDB你这一金融级的数据库,2015年的曾经 本来 有第一一三个多多商业版本GoldenDB 1.0,并在中信银行的北京营业厅的冠字号业务上开使使用。到2016年的曾经 ,本来 在多个银行不同业务等级的生产系统上做了商用投产。2017年,中兴通讯做了另外一件事情,与生信银行一并在总行的账务系统上做了一一三个多多核心下移的测试验证,本来 验证通过了,性能超过50000TPS。当时客户就决定要在2019年的曾经 ,把核心业务的数据库,从基于小机的DB2上迁移到基于X86平台的GoldenDB上。

  GoldenDB分布式数据库总体架构是哪些?

  GoldenDB分布式数据库总体架构分成一三个重要每项:

  第一每项,是计算节点集群,是多点读写模式,本来 计算节点那末清况 ,全都可不时要做到横向扩容。

  第二每项,是数据节点集群。在一套GoldenDB上方,可不时要有多个数据节点集群去承载多个不同的业务,每个数据节点集群是可不时要做到物理隔离的。每个集群组织组织结构根据对应的业务流量,还有存储压力,去做分片,做负载均衡。每个数据分片也有 一主多备的形态,每个备机可不时要做容灾和读负载能力的扩展。

  第三每项,全局事务管理节点,用来管理全局分布式事物的一一三个多多生命周期。它跟计算节点做交互,提供全局事务ID的分配、回收,以及全局活跃事物列表的查询功能。

  第四每项,是管理节点,主要含晒 有几个重要功能:第一,提供了一一三个多多Web控制台页面,在控制台上可不时要做自动的安装、更新,集群的组建,主备切换,备份恢复等各种与运维相关的操作;第二,管理节点上方还含晒 了元数据管理器,源数据管理器存了两每项信息,第一每项信息是GoldenDB拓扑的组网信息,包括各个集群的设备信息,主备信息、IP信息等,第二每项全都 业务数据库的源数据,包括DDL、库表形态、分布清况 、分布规则;第三,管理节点还提供了监控,可视化告警等与管理相关的功能。

  这全都 GoldenDB数据库的整体架构,对外连接业务,提供的是MySQL的标准协议。

  GoldenDB现在正在做的一一三个多多事情是,在2019年底的曾经 要把中信银行的DB2给替换掉。下面总结了GoldenDB数据库满足金融核心功能的有些关键需求。

  第一,实时一致的分布式事务控制;在做分布式事务控制的曾经 ,也能做到实时一致,本来 事务除理不影响业务曾经 的业务逻辑,业务曾经 的代码迁到GoldenDB上的曾经 是不时要做逻辑变更。我们 我们 曾经 的代码是RPG的代码,直接通过工具改成Java代码,业务开发的工作量非常少。

  第二,支持同城异地容灾和一致的备份恢复,符合异地监管的一致性。GoldenDB契合金融的一一三个多多三中心架构,也能做到同城RPO为0。无论是一致的备份恢复,还是异地接管的恢复,在做备份的曾经 各个节点单独备份,但恢复的曾经 也也能恢复到全局一致的清况 。全都,异地做接管的曾经 ,其实会有数据丢失,本来 接管后的数据也是一一三个多多一致的清况 ,更加方便业务进行数据回补。

  第三,线性横向扩展与生机数据重分布,这含晒 两每项内容:一一三个多多是性能的横向扩展;一一三个多多是容量的横向扩展。关于性能的横向扩展,DBProxy能做到百分之百的横向扩展,底层数据节点是瓶颈的曾经 ,数据节点能做到95%的横向扩展。支持在线数据重分布,本来 通过追增量和冻结日志的方法,也能把真正对联机交易的影响降低到秒级,一般默认的阈值配置也有 5秒以下。

  第四,充足的监控体系和完善的运维能力。传统核心基于DB2本来 Oracle,可不可不可以 也能 一两台设备,运维人员和DBA人员本来 监控一两台设备就行,换到你这一X86的分布式架构下面,本来 是十几台本来 几十台,这对运维体系的易用性,对监控体系的完备性要求就更高。全都,中兴通讯的GoldenDB在2018年一整年也有 做那末个事情,那全都 充足监控运维体系,跟全都第三方的平台和第三方工具做对接。

  怎么看待GoldenDB 事务除理机制的各种疑问?

  1、事务理论的分布式延伸

  关于GoldenDB的分布式事务除理机制,我们 我们 先看下事务除理在分布式架构哪些延伸。我们 我们 理解的事务的一致性,其实是在事务内的原子性(原子性-A)和事物间的隔离性(隔离性-I),以及故障时的持久性(持久性-D),可不可不可以 也能 三者组合到一并也能保证数据的一致性(C)。

  在分布式架构下,原子性的要求,是在多个数据分片上的多次操作,要么一并成功,要么一并失败;而在单机架构下,仅是一台机器上多条记录的多次操作;隔离性方面,要求多个计算节点上的不同连接,不必相互访问到在多个数据分片内未提交事务的数据;而单机数据库的隔离性,是指不同连接(除理多tcp连接 或多多tcp连接 )不必相互访问到当前机器上未提交事务的数据;另外,从持久性淬硬层 看,分布式数据库的事务提交前时要将日志在分片主、 从节点都得到群克隆,主节点故障时,能在从节点上找回数据,继续完成事务;单机数据库的事务要求是,提交前时要先将日志落盘,机器宕机恢复后不丢失数据。

  2、分布式事务的难点

  那末,要实现分布式事务的实时一致性(保证ACID ),难点在哪?其实包括一一三个多多每项:一是每项DB提交失败,怎么保证全局事务的原子性(A);另一每项是,并发访问时,每个事务都谁能谁能告诉我有些事务的清况 ,怎么保证事务之间的隔离性(I)。以转账交易为例: 交易前一一三个多多账户资金余额各5000,事务T1从账户1转账500到账 户2。需除理疑问:在事务T1提交期间,本来 DB1和DB2提交时间有空隙,若此时事务T2读取一一三个多多账户的余额,会发现余额之和是 500+5000=5000;占据 事务T1对账户1上扣钱成功,给账户2加钱失败的清况 。

  3、怎么保障原子性?

  在业内,通常都用2PC协议保障原子性,在MySQL中就能看后全都场景,一一三个多多是MySQL里跨存储引擎的事务,二有存储引擎里bin log一致性的保障,都通过2PC实现。2PC有此人 的优势,参与者在投赞成票曾经 可不时要单方面撤除事务,本来 也有 有些局限性。第一一三个多多疑问,它并也有是一一三个多多阻塞式的算法,进入Prepare曾经 一定要成功;第一三个疑问是,协同者的清况 其实是一一三个多多单点,协调者挂了曾经 ,参与者那末方法继续进行下去,参与者和协调者在有些清况 会停留消息,时要启动定时监控;第三疑问是,正常的提交流程,日志写入数量比较大,为 2N+3 ,消息数也多,为 4N ,其中 N 为参与节点的数量。

  另外,还有全都通过增加消息上方件,本来 使用TCC分布式事务框架,来实现事务原子性的方案。通过业务改造保障原子性,会有额外的疑问:首先,是对业务的侵入性较大,所有业务也有 增加反向操作逻辑/增加额外上方件;其次,除理过程中数据占据 短暂不一致或原因分析更新延后,原子性可不可不可以 5000%保障;其三,无论2PC、MQ还是TCC,都占据 的一一三个多多疑问,全都 在2阶段提交Commit阶段,在MQ不断重试的阶段,在TCC的Confirm阶段本来 突然冒出了异常,那末方法除理,那末除理方法,时要人工干预。

  至于,GoldenDB事务原子性机制怎么实现?总结起来就两句话:第一句是一阶段提交。GoldenDB有一一三个多多全局事务,整体的提交是一阶段。把一一三个多多全局事务拆成由若干个子系统单独提交的一一三个多多个子事务,把哪些子事务由计算节点交给对应DB去执行。执行曾经 ,我们 我们 先在GTM那边把事务标记成活跃的清况 ;本来 所有的DB都执行成功了,在GTM那边把事务标记为不活跃,全局事务就开使了;第二句是自动回滚补偿。遇到像转账失败的流程后,子事务在单机上会自动回滚,反馈给计算节点后,也有 删改成功的,计算节点时要向数据节点架构设计 回滚的消息。回滚补偿全都 把架构设计 回滚的操作做到数据库层面,业务层不时要做补偿交易。你这一模式的优点,一是应用层不必增加额外补偿逻辑;二是,失败回滚是少数清况 ,整体性能高于两阶段提交,只时要一次交互就可不时要了,大大节省了单机资源。

  4、已提交事务回滚实现和优化方法

  在你这一过程中,会涉及已提交事务回滚的实现和优化方法。整个过程要经历定位-遍历-生成-执行曾经 一一三个多多流程。通过全局事务ID所对应的Binlog提升回滚性能,数据行里会存有全局事务的ID, 当你Commit的曾经 ,全局事务ID会随着Binlog一并进入文件里。通过Binlog上方的GTID找到你这一GTID所对应的所有Binlog的语录块,本来 解析Binlog,生成SQL,立刻组成新的事务,重新执行一遍。对整个操作过程,GoldenDB做了全都优化,包括表定义缓存、预分析并行查找、共享内存、key值利用、SQL格式,未来时要把正向Binlog直接生成反向 Binlog,不走SQL解析,直接走MySQL并行回放机制,直接应用到数据库。

  5、事务隔离性的各种异常

  我们 我们 怎么除理事务隔离性的各种异常?首先,事务隔离性的各种疑问也有 并行调度除理不好原因分析,本来 写写冲突,除理不当,会原因分析 ‘脏写’。比如: T1w、T2w、T1a,基于被回滚的数据做了update,造成了丢失回滚。再比如,写读冲突除理不当,原因分析‘脏读’,本来 第一读,读到了未提交的数据,那全都 脏读,本来 多次读并读了不同版本的数据,那是不可重复读,本来 事务并发原因分析前后读出的多个数据间不满足原有约束,那是读偏序,本来 事务并发原因分析满足条件的结果集,变多本来 变少,那是幻读。此外,还有读写冲突,除理不当原因分析 ‘脏写’ ,比如:T1r、T2w、T1w,T2w被覆盖,会原因分析丢失更新。最后是写偏序,这是并也有违反语义的异常,在数据库层面看正常,本来 达可不可不可以 让我 求的效果,就像黑白球,我有一黑一白一一三个多多球,事务一要把黑球改成白球,事务二要把白球改成黑球,当在快照级别隔离下,一一三个多多事务一并并发操作时,会原因分析最终事务一改了一一三个多多球,事务二改了一一三个多多球,一黑一白变成了一白一黑,你这一清况 是错误的,不满足于任意并也有串行除理结果。以上哪些异常也有 并发调度那末除理好的结果。

  在《A Critique of ANSI SQL Isolation Levels》论文中,总结了隔离级别及对应的疑问。首先,R R级别的隔离除理不了幻读;其次,SI隔离除理不了写偏序。可不可不可以 也能 可串行化的隔离级别也能除理所有疑问。他们说MySQL级别的R R隔离能除理幻读,其实MySQL级别的R R隔离太多论文里指出的R R级别,它实际上是SI的隔离级别。

  那末,实现可串行化隔离级别的方法哪些呢?第并也有方法是严格按照串行顺序执行,你这一方法肯定能保证隔离性。像Voltdb,号称是最fast的内存数据库,通过串行保证隔离性,通过在存储过程里执行保证了原子性。Redis是单多tcp连接 跑,全都隔离性也那末疑问,本来 Redis只支持单语录事务,可不可不可以 也能 保证单语录的原子性。本来 你时要Redis去做多行的事务,就时要此人 去保证它的原子性。第二种,是运用SS2PL技术,加锁除理幻读 。比如:MySQL、SQL Server、Informix的隔离级别,实际上也有 通过SS2PL技术做到可串行化的隔离级别。第并也有,可串行化的快照隔离SSI,可除理写偏序疑问。像PostgreSQL、FoundationDB,也有 你这一模式的隔离。你这一一三个多多也有 正确的隔离,而有些的隔离也有 对性能的妥协,也有 不正确的。

  6、怎么通过2PL进行事务并发控制?

  这里主要看下怎么通过2PL进行事务并发控制。Eswaran等人本来 证明:遵守2PL算法的并发调度一定是可串行化的。哪些是2PL?是占据 数据库事务除理中的两阶段锁定,前一一三个多多阶段可不可不可以 也能 加锁,后一一三个多多阶段可不可不可以 也能 释放锁。本来 所有的事务都能遵循曾经 一一三个多多原则去除理,并发起来的最终结果就等同于某并也有串行化的并发调度结果了。不考虑事务Commit时的失败,那2PL这就够了,本来 能保证事务的一致性了。本来 你这一可串行化的本来 太多了,本来 LockPoint比较难找,全都大每项厂商的实现方法也有 SS2PL,也有 把读锁和写锁的释放插进Commit阶段一并去执行。

  疑问是,从2PL到SS2PL到底哪些限制?第一一三个多多是到S2PL,它做了第一一三个多多限制,先把写锁插进Commit,当一一三个多多事务对某个数据做了修改,本来 没提交曾经 ,所修改的数据的后像是可不可不可以 被有些的事务读本来 写的。SS2PL则在S2PL基础上,把读写也插进了最后。本来 一一三个多多事务做了修改,那末所做修改的数据的前像是那末被有些事务给读过的,SS2PL最终达到的效果是,在所有的可串行化的并发调度里最终取舍了某并也有本来 某几种,来保障事务的形态。

  GoldenDB是为什么会么会做事务的并发控制的?GoldenDB引入了全局事务管理器(GTM:Global Transaction Manager)实现全局事务的隔离性,并协助实现全局事务的原子性。

  与SS2PL的比较,GTM封锁是在事务提交曾经 ,所有的GTID相关的数据也有 能被读取和修改。活跃事务列表里的GTID,大概写锁。保障了写写和写读冲突下的数据一致性。另外,通过对读操作显式加锁,达到严格的SS2PL效果,保障了读写冲突下的数据一致性。而SS2PL只在事务提交的的曾经 才释放读锁和写锁。

  GoldenDB还有一一三个多多预锁机制,用来除理如下疑问:DBProxy查询到的活跃事务列表是旧的;DBProxy基于活跃事务列表做的判断是不准确的。GoldenDB的除理方法是,将所有的本来 性冲突都认为是冲突。在返回活跃事务列表中,增加Max_GITD,Proxy判断本来 GTID大于Max_GITD,也认为该事物是占据 冲突的。

  总结下来,对于事务除理中的写一致除理,涉及一一三个多多方面:一一三个多多是满足条件的记录上无锁, GTID不活跃,就可不时要直接修改数据,本来 GTID活跃,你这一曾经 时要通过预锁机制重新停留GTID被释放;另外是满足条件的记录上有锁,可不可不可以 也能 先走单机锁冲突的事务除理机制,等到锁释放了,再去判断GTID是否是活跃。

  对于事务除理中读一致性的除理:在脏读的场景下,不做任何判断,直接读,本来 不推荐你这一隔离级别;读已提交,本来 有排它锁,证明这条数据有事务正在修改,直接读它的前像。本来 无排它锁,GTID不活跃,那末单机事务,全局事务,直接读当前数据行。本来 无排它锁,GTID活跃,说明那末单机事务,本来 有全局事务,仍然可不可不可以 读单机上的数据,时要去读 数据,你这一前像数据的purge操作时要全局进行;在读已提交的场景下,有排他锁和无排他锁、GTID活跃场景的除理方法是一样的;在可重复读,有排它锁的清况 下,会按照GTID版本号去找,找到快照开使曾经 的版本号。在可重复读的场景下,无排它锁,GTID不活跃,看上去那末疑问,本来 当前数据行有本来 本来 被提交过了,可不可不可以 直接读,时要筛选版本判断是否是时要找前像数据。无排它锁,GTID活跃,也是一样的,时要去找满足条件的GTID版本号的事务版本;可序列化级别也那末,加共享锁无冲突,GTID不活跃,可不时要直接读数据,本来 GTID活跃,还可不时要读数据,本来 要把活跃的冲突的GTID号给带上去,DBProxy根据预锁的机制,判断哪些曾经 GTID能正常释放,本来 正常释放,数据就可不时要读到。可不可不可以 语录,时要把事务重启。在可序列化、加共享锁有冲突的场景下,仍然按照单机锁冲突的并发控制去除理。

  事务除理模块优化哪些实践经验?

  在GoldenDB上有个GTM,是一一三个多多主要的优化点。为什么会么会除理性能的瓶颈?首先,GTM被设计得很简单,可不可不可以 也能 一一三个多多流程,负责GTID的分配、回收,负责向计算节点提供活跃事务ID的查询的一一三个多多接口。GTID的分配和回收时要实时落盘,GTID大概一一三个多多大号的Binlog ,一次写盘大概1μs,理论上限5000万 TPS,可不时要突破?另外一一三个多多优化点是,Proxy和GTM之间的消息交互,对网络资源消耗过大,理论瓶颈1.25GB 速率单位怎么利用?

  1、申请/释放GTID优化:Proxy批量请求

  在释放GTID的曾经 ,做了批量释放,也能做到减少交互次数,降低交互的数据量。在申请GTID的曾经 也做了批量申请,本来 这里有个疑问,在RC和串行隔离下面,可不时要任意使用批量申请,本来 在RR隔离下面,是可不可不可以 肆无忌惮的去使用批量申请的,在RR隔离级别下,是基于GTID的数据快照,要求GTID是严格单调的,全都在GTID申请的曾经 ,还是要保障GTID单调,先来的事务先获得GTID。但实际上,本来 系统的调度也有 有误差的,比如Proxy1向GTM申请了GTID1,要去修改数据A, Proxy2向GTM申请了GTID2,也要修改数据A,其实是Proxy1先申请,本来 他不一定能最快地给数据I加进去去锁,全都靠分配GTID去严格保障时间顺序,有误差。也全都 数据库调度会有疑问,可不可不可以 保证先来的请求也有先被执行。全都,在一定误差范围内,分配的GTID可不时要不保证严格单调的,时要做额外除理。Proxy1先申请了50000个GTID,我时要他在很短的时间内把这50000个GTID给用掉,本来 不必,时要有一一三个多多废弃的机制,大概保证GTID申请的哪些事务在误差内保证单调。曾经 可也减少交互次数,降低交互数据量。

  2、查询GTID列表优化:Proxy进行组提交

  Proxy北向是一一三个多多数据库连接池,跟应用的连接池做交互,有的执行多tcp连接 是在做建链,也有 在做SQL解析,本来 也有 本来 我们 我们 我们 是 做GTID的查询,本来 所有的多tcp连接 都能直接和GTID去做交互,交互数据量会很大。全都,代理多tcp连接 可汇总执行多tcp连接 的请求,本来 跟GTM做单独的交互,本来 你这一交互是单多tcp连接 单工的,使用一份活跃事务列表应答。当在途请求那末返回时,代理多tcp连接 不必发送新的查询请求。

  3、查询GTID列表优化:GTM进行组提交

  GTM和Proxy是一对多的,多个计算节点去访问同一一三个多多GTM,GTM在汇总多个Proxy请求曾经 ,他也可不时要产生一一三个多多子多tcp连接 出来。专门除理GTM返回请求的拼装,用同一份活跃事务列表应答不同Proxy发来的请求。 当子多tcp连接 那末拼装完返回列表时,不必除理新的请求,这和Proxy除理机制例如。

  4、组提交优化后对预锁机制的影响

  有一一三个多多疑问是,刚在Proxy上和GTM上都做了组提交,但对曾经 的预锁机制,对性能到底有那末影响。在优化曾经 的场景下,Proxy上所有向GTM发的查询请求,都时要过0.5ms(32k包大小万兆下的双向速率单位)也能收到响应,Proxy获取到的事务列表都落后GTM0.25ms;优化曾经 ,Proxy上所有的请求,在0~0.5ms 内会收到响应,Proxy获取到的事务列表的时间那末变化,仍然是落后GTM0.25ms,经过组提交优化后,并未增加单消息除理速率单位。本来 他们会问,本来 曾经 性能要求更高的清况 下,怎么除理速率单位占用的疑问?我们 我们 可不时要通过自适应算法精简请求,方法请求数、统计时间和当前负载清况 ,实时修改发送周期。另外,可不时要通过数据压缩技术,通过记录GTID起始值(8Byte)和偏移量位图(255Byte),将数据包大小由32k降到1K以内,压缩后万兆的速率单位允许提供1500个Proxy。全都,Proxy和GTM的速率单位不必是性能瓶颈。

  5、申请释放GTID优化:GTM多tcp连接 优化

  这是曾经 踩的一一三个多多坑,曾经 是按照做DB的思路去做GTM上的持久化,专门弄了一一三个多多Flush多tcp连接 去写日志,本来 那末考虑到一一三个多多疑问全都 GTM上的数据形态非常简单,消耗的也有 I/O,消耗的是IOPS,专门弄一一三个多多多tcp连接 去做异步除理,除理得放慢,每次收到的请求很少,原因分析IOPS非常高,本来 多tcp连接 切换非常严重。本来 ,把它变成串行化除理了曾经 ,请求积攒了,IO量变大了,本来 IOPS会降下来,不必做CPU的多tcp连接 的切换了,CPU也减低了。

  经过各种优化后,GoldenDB在你这一数据模型下,经过了严苛的技术验证,实现了3亿客户15亿账户转账交易、明细查询50000 TPS的支撑能力。在你这一过程中,还模拟了软硬件故障的各种测试,能满足核心业务强一致性要求,正确率达到5000%。一并,在你这一场景下,做了当Proxy是瓶颈的曾经 ,去扩展Proxy;在DB是瓶颈的曾经 ,去扩展DB的一一三个多多测试。其中,计算节点扩展线性率达到5000%,数据节点扩展线性率95%。在故障隔离方面,计算节点故障、不影响整体系统交易;数据节点故障的曾经 ,不影响有些节点交易。

本文由

Danny

发布在

ITPUB

,转载此文请保持文章删改性,并请附上文章来源(ITPUB)及本页链接。

原文链接:http://www.itpub.net/2019/07/08/2363/