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

  • 时间:
  • 浏览:87
  • 来源:可可资源网_提供ACE资源网技术_爱Q活动网资讯

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

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

  众所周知,中兴通讯的主航道产业是5G通信,然后 各行各业全版都是使用数据库,中兴通讯提交给客户的通讯设备上面也都使用了小量的数据库,为了给客户提供更好的交付体验,大要素全版都是自研的产品。

  从1002年开始英语 ,中兴通讯推出EBASE文件数据库,1007年推出EBASE-MEM内存数据库,做到2011年的DHSS分布式数据库,开始英语 有了有一一四个 雏形。2014年的有一一四个,中兴通讯开始英语 研发了GoldenDB许多金融级的数据库,2015年的有一一四个愿因有第有一一四个 商业版本GoldenDB 1.0,并在中信银行的北京营业厅的冠字号业务上开始英语 使用。到2016年的有一一四个,愿因在多个银行不同业务等级的生产系统上做了商用投产。2017年,中兴通讯做了另外一件事情,和联 信银行一起去在总行的账务系统上做了有一一四个 核心下移的测试验证,然后 验证通过了,性能超过10000TPS。当时客户就决定要在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)。

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

  2、分布式事务的难点

  那么,要实现分布式事务的实时一致性(保证ACID ),难点在哪?觉得包括有一一四个 要素:一是要素DB提交失败,何何如证全局事务的原子性(A);另一要素是,并发访问时,每个事务都问你许多事务的情况汇报,何何如证事务之间的隔离性(I)。以转账交易为例: 交易前有一一四个 账户资金余额各100,事务T1从账户1转账100到账 户2。需处置大大问题:在事务T1提交期间,愿因DB1和DB2提交时间有空隙,若此时事务T2读取有一一四个 账户的余额,会发现余额之和是 100+100=100;位于事务T1对账户1上扣钱成功,给账户2加钱失败的情况汇报。

  3、何何如障原子性?

  在业内,通常都用2PC协议保障原子性,在MySQL中就能看到所以场景,有一一四个 是MySQL里跨存储引擎的事务,二有存储引擎里bin log一致性的保障,都通过2PC实现。2PC有自己的优势,参与者在投赞成票有一一四个可不可以单方面注销 事务,然后 全版都是许多局限性。第有一一四个 大大问题,它五种是有一一四个 阻塞式的算法,进入Prepare有一一四个一定要成功;第一四个大大问题是,协同者的情况汇报觉得是有一一四个 单点,协调者挂了有一一四个,参与者那么最好的办法继续进行下去,参与者和协调者在许多情况汇报会等待消息,时要启动定时监控;第三大大问题是,正常的提交流程,日志写入数量比较大,为 2N+3 ,消息数也多,为 4N ,其中 N 为参与节点的数量。

  另外,还有所以通过增加消息上面件,愿因使用TCC分布式事务框架,来实现事务原子性的方案。通过业务改造保障原子性,会有额外的大大问题:首先,是对业务的侵入性较大,所有业务全版都是增加反向操作逻辑/增加额外上面件;其次,处置过程中数据位于短暂不一致或愿因更新延后,原子性非要100%保障;其三,无论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是单守护线程池池跑,所以隔离性也那么大大问题,然后 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,理论上限100万 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先申请了100个GTID,我时要他在很短的时间内把这100个GTID给用掉,愿因不必,时要有有一一四个 废弃的机制,大概保证GTID申请的那些事务在误差内保证单调。有一一四个可也减少交互次数,降低交互数据量。

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

  Proxy北向是有一一四个 数据库连接池,跟应用的连接池做交互,有的执行守护线程池池是在做建链,全版都是在做SQL解析,然后 全版都愿因大伙儿儿全版都是做GTID的查询,愿因所有的守护线程池池都能直接和GTID去做交互,交互数据量会很大。所以,代理守护线程池池可汇总执行守护线程池池的请求,然后 跟GTM做单独的交互,然后 许多交互是单守护线程池池单工的,使用一份活跃事务列表应答。当在途请求那么返回时,代理守护线程池池不必发送新的查询请求。

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

  GTM和Proxy是一对多的,多个计算节点去访问同有一一四个 GTM,GTM在汇总多个Proxy请求有一一四个,他也可不可以产生有一一四个 子守护线程池池出来。专门处置GTM返回请求的拼装,用同一份活跃事务列表应答不同Proxy发来的请求。 当子守护线程池池那么拼装完返回列表时,不必处置新的请求,这和Proxy处置机制之类。

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

  有有一一四个 大大问题是,刚在Proxy上和GTM上都做了组提交,但对有一一四个的预锁机制,对性能到底有那么影响。在优化有一一四个的场景下,Proxy上所有向GTM发的查询请求,都时要过0.5ms(32k包大小万兆下的双向下行带宽 )可不可以收到响应,Proxy获取到的事务列表都落后GTM0.25ms;优化有一一四个,Proxy上所有的请求,在0~0.5ms 内会收到响应,Proxy获取到的事务列表的时间那么变化,仍然是落后GTM0.25ms,经过组提交优化后,并未增加单消息处置下行带宽 。愿因其他同学会问,愿因有一一四个性能要求更高的情况汇报下,何如处置下行带宽 占用的大大问题?大伙儿儿可不可以通过自适应算法精简请求,最好的办法请求数、统计时间和当前负载情况汇报,实时修改发送周期。另外,可不可以通过数据压缩技术,通过记录GTID起始值(8Byte)和偏移量位图(255Byte),将数据包大小由32k降到1K以内,压缩后万兆的下行带宽 允许提供1100个Proxy。所以,Proxy和GTM的下行带宽 不必是性能瓶颈。

  5、申请释放GTID优化:GTM守护线程池池优化

  这是有一一四个踩的有一一四个 坑,有一一四个是按照做DB的思路去做GTM上的持久化,专门弄了有一一四个 Flush守护线程池池去写日志,然后 那么考虑到有一一四个 大大问题所以GTM上的数据价值形式非常简单,消耗的全版都是I/O,消耗的是IOPS,专门弄有一一四个 守护线程池池去做异步处置,处置得调快,每次收到的请求很少,愿因IOPS非常高,然后 守护线程池池切换非常严重。然后 ,把它变成串行化处置了有一一四个,请求积攒了,IO量变大了,然后 IOPS会降下来,不必做CPU的守护线程池池的切换了,CPU也减低了。

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

本文由

Danny

发布在

ITPUB

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

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