金融级分布式数据库架构设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
金融级分布式数据库架构设计
目录
1.行业背景 (3)
2.数据库分布式改造的途径 (3)
3.分布式数据库总体架构 (4)
4.两阶段提交的问题 (5)
5.CAP与BASE的抉择 (7)
6.raft的优势 (8)
6.1. Leader选举 (9)
6.2. 日志复制 (10)
6.3. 安全性 (11)
7.分布式数据库如何实现PITR (16)
1.行业背景
银行业从最初的手工记账到会计电算化,到金融电子化,再到现在的金融科技,可以看到金融与科技的结合越来越紧密,人工智能、大数据、物联网、区块链等新兴技术改变了金融的交易方式,为金融行业的创新前行提供了源源不断的动力。同时互联网金融的兴起是一把双刃剑,带来了机遇的同时也带来了挑战。普惠金融使得金融的门槛降低,更多的普通大众参与到金融活动中,这让金融信息系统承受了越来越大的压力。于是我们可以看到大型商业银行、保险公司、证券公司、交易所等核心交易系统都在纷纷进行分布式改造,其中数据库作为有状态的应用,成为了信息系统中唯一的单点,承担了所有来自上层应用的压力。随着数据库瓶颈的凸显,进行分布式改造迫在眉睫。
2.数据库分布式改造的途径
数据库进行分布式改造主要有三种途径:分布式访问客户端、分布式访问中间件、分布式数据库。由于其分布式能力实现在不同的层次(应用层、中间层、数据库层),对应用程序有不同的侵入程度,其中分布式访问客户端对应用侵入性最大,改造难度最大,而分布式数据库方案对应用侵入性最小,但是架构设计及研发难度最大。
3.分布式数据库总体架构
其实当前市面上的分布式数据库总体架构都是类似的,由必不可缺的三个组件组成:接入节点、数据节点、全局事务管理器。总体架构如下,协调节点负责sql解析,生成分布式执行计划,sql转发,数据汇总等;数据节点负责数据存储与运算;全局事务管理器负责全局事务号的生成,保证事务的全局一致性。这个架构或多或少都受到了google spanner F1论文的影响,这篇文章主要分析了这几个组件在实现上有什么难点,该如何进行架构设计。
4.两阶段提交的问题
我们知道两阶段提交是阻塞性协议,这也是它最大的问题。下图pgxc架构下的两阶段提交为例,主要分为下面几个阶段:
①:CN prepare ->②:所有DN prepare ->③:CN commit->④:所有DN commit
试想一下如果在cn commit阶段发生cn/dn宕机会发生什么?
如果在cn下发完cn commit命令后宕机,这时dn收到commit命令后会进行提交,但是返回commit ok时发生cn宕机,事务进入阻塞状态。如果cn下发commit之后某个dn发生宕机,则会造成某些dn commit成功,某些dn commit失败,造成不一致,但是如果dn重新启动后会继续去cn上拿事务提交信息,发现是commit状态,则会继续执行commit操作,提交之前的事务。在这个地方我们可以探讨一个更极端的情况,如果此时cn也宕机了,那么失败的dn重启后去cn拿状态发现拿不到,这是这个失败dn上的事务就处于一个未决态,不知道是应该提交还是回滚,这时候应该有一个进程能够从其他dn上发现该状态并报告给故障dn,通知它进行提交。这个角色就是pgxc_clean进程,其实之前几种情况下的事务的回滚也是该进程的工作。那我们再深入一下,如果该dn是事务的唯一参与者,那么此时pgxc_clean 就无法从其他dn以及cn获取状态,这时该dn就是真正的未决态了。
为了解决两阶段提交的阻塞问题,出现了三阶段提交,三阶段提交在commit之前引入了cancommit的过程,同时加入超时机制。因为如果协调者发生宕机,参与者无法得知协调者到底发出的是commit还是abort,三阶段提交cancommit过程就是告知参与者我发送的是commit或者abort命令,这时如果协调者发生失败,参与者等待超时时间后可以选出新的协调者,而该协调者是知道应该发出什么命令。
虽然三阶段提交解决了阻塞问题,但是无法解决性能问题,分布式系统中为了保证事务一致性需要跟每个参与者通信,一个事务的提交和参与需要分布式系统中每个节点的参与,必然带来延时,不过在万兆、infiniband、roce高速网络的支持下已经不再是问题了。
5.CAP与BASE的抉择
我们知道分布式系统无法战胜CAP。那么在设计分布式系统的时候该如何进行取舍?首先P (分区容错性)是必须保证的,因为分布式系统必然是多个节点(分区)通过网络进行互联,而网络是不可靠的,分布式系统是为了避免单点故障,如果因为网络问题或者某些节点失败造成整体系统不可用,那么也不符合分布式系统的设计初衷。如果保证A(可用性),那么当网络失败时,网络隔离的不同区域就要继续提供服务,那么就会造成不同分区的数据不一致(脑裂);如果保证C(一致性),那么网络失败时,就需要等待不同网络分区的节点同步完数据,如果网络一直失败,那么系统就会因为无法同步而一直不可用。
2PC就是典型的牺牲可用性保证一致性的例子,而BASE(basically available,soft state,eventual consistency)就是牺牲一致性保证可用性的例子,因为做到实时的强一致要牺牲的代价太大了,它允许数据在某些时间窗口内的不一致,通过记录窗口内的每一个临时状态日志做到在系统故障时,通过日志继续完成未完成的工作或者取消已经完成的工作回退到初始状态,这种方式保证了最终一致性。BASE与传统ACID理论其实是背离的,满足BASE理论的事务也叫柔性事务,在遭遇失败时需要有相应的补偿机制,与业务耦合性较高,其实我并不是很赞同BASE的做法,因为它已经背离了数据库最基本的设计理念。
6.raft的优势
不管是上面的XA还是BASE都无法彻底解决一致性问题,真正意义上的强一致一定是基于强一致协议的。paxos和raft是目前主流的两种共识算法。Paxos诞生于学院派,是分布式环境下基于消息传递的共识算法,它设计之初是考虑一个通用的模型,并没有过多的考虑实际的应用,而且paxos考虑了多个节点同时写入的情况,这就使得paxos的状态机异常复杂,所以难以理解,不同的人可能理解出不同的意思,这一点一直遭人诟病,比如MGR引入write set 的概念来处理多点写入冲突的问题,这在高并发热点数据的场景下是不可接受的。因为paxos 的难以理解,斯坦福的两名大学生设计了raft算法,相比来说,raft是工业派,同一时刻leader 只有一个,follower通过日志复制实现一致性,相比paxos来说raft的状态机更加简单易懂,实现起来也更加简单,因此在分布式环境上有着广泛的应用,例如TiDB、RadonDB、etcd、kubernetes等。