海鼎,助您成就梦想!

协同系统的数据一致性

2013年12月24日

评论数(0)

 /蔡笠

摘要: 在分布式协同应用中,多个系统的分工协作共同完成一个业务目标。协同工作的各个系统公布各自的服务,有各自的数据存储。这种情况下,保障协同系统的数据一致性是一个重要要求。本文给出了分布式远程调用的协同事务的概念,并指出当组成协同事务的相关事务满足可撤销性和幂等性的条件下,能够得到协同事务的一致性。 

关键字: 协同系统 协同一致性 分布式系统 远程调用 

网络技术的发展,应用系统结构产生了很大的变化,尤其明显的是,分布式协同成为常用的选项,多个系统的分工协作共同完成一个业务目标,取代了传统的集中式系统独立完成业务目标。协同工作的各个系统公布各自的服务,有各自的数据存储,通过可靠的本地通讯和不那么可靠的远程通讯协同完成一个业务目标。这种情况下,保障协同系统的数据一致性是一个重要要求。 

协同系统的设计,有两种方式。一种是分布计算、集中存储,也就是将计算功能分布到各个系统中,数据持久化功能还是集中在一个系统中。这对计算量巨大而存储量不那么大的应用来说,是一个很好的选择。分布式计算利用的主要是各个系统的计算能力。对于数据量巨大,或者数据的所有者是独立的机构时,就要求采用分布计算,分布存储的结构。例如一个应用由物品交易、资金结算、服务审计等部分组成,各部分功能由独立的机构提供, 所使用和产生数据由各个服务提供者各自拥有。在这种情况下,集中的数据存储就比较难以达成,除非各服务提供方都同意将自己的数据存储在一个公共的数据云中,而这在大多数情况下都是有很大的现实难度的。

一、分布式事务

传统的数据库数据一致性是由数据库事务来保证的。事务具有ACID特性。AAtomic)指的是事务的原子性。构成事务的操作对多种数据的修改要么全部完成,要么一个都不完成。 CConsistency)指的是事务的一致性,即按照一定的规约执行的操作,事务开始之前和事务结束以后,都保证了数据的完整性。IIsolation)指的是事务的隔离性。若干事务的并发执行互不干扰,就像各自顺序执行一样。DDuration)是持久性,一个事务完成后,其对数据的修改将持久地完全地保存下来。

事务的隔离性通常是由锁机制来完成的。每当事务中的操作要存取一个资源(数据)时, 对其上锁。有两种不同的事务锁: 悲观锁和乐观锁。悲观锁是在事务中的某个操作第一次存取一个资源时,锁住该资源,并且到事物结束后才释放。这使得在该事务进行过程中,其它的事务不能存取这个资源,大大降低了事务的并发性。为提高并发性,又有了共享锁和排他锁等机制来提高并发性。采用乐观锁方法,事务中的某个操作第一次存取一个资源时,并不锁住该资源,而是对其当时的状态做一个快照,其它的事务可以照常存取这个资源。当事务提交时,比较提交时该资源的状态和快照的状态,如果一致,则可以提交,否则,产生乐观锁异常,并撤销该事务对资源所做的改动。

在一个分布式的事务中,通常有这么几个角色: 事务管理者、事务上下文、事务对象和可恢复资源。事务管理者管理和协调各个事务;事务上下文标明一个特定的事务;受到事务操作的影响的对象称为事务性对象;如果一个事务对象的状态在事务提交时被持久化,在事务回滚时被恢复到事务开始前的状态,那么这个事务对象称为可恢复资源。事务的原子性由事务管理者保证。当事务提交或回滚时,如果事务只涉及一个可恢复资源,事务管理者的工作很简单,只要告诉这个可恢复资源提交或回滚。当事务涉及多个可恢复资源时,通常采用两阶段提交的方式来协调事务的原子性。事务管理者在告知各个可恢复资源提交其修改前, 向每个可恢复资源发出准备提交的指令。当得到所有的可恢复资源的肯定答复后,事务管理者向它们发出提交命令;如果有任何一个可恢复资源给出否定答复,事务管理者向其它的可恢复资源发出回滚命令。可恢复资源在对准备提交命令给出肯定答复后,能够提交修改。

在分布式环境中,可能发生的最坏的一种情况是,由于通讯故障,事务管理者和可恢复资源之间失去联络。如果在一段时间两者内无法通讯,可恢复资源将自行决定是提交还是回滚已执行的事务操作。这将导致参与一个事务的部分资源被提交,部分资源被回滚,从而破坏了事务的原子性,导致数据完整性的破坏。由于这种风险的存在,当可恢复资源做出自行决定的时候,必须保存和此决定相关的所有信息到可靠的持久化存储中,直到恢复和事务管理者的联系,执行事务管理者的指令;或者由系统管理员查看这些信息,修改资源状态,纠正可能的数据一致性错误。

 

现实中有许多分布式的应用,在可能出现通讯故障的环境下,可以采用最终一致性的要求来取代事务的强一致性要求,或者说将一个事务分解为多个相关事务,通过相关事务管理者的协调,来达到应用所要求的协同一致性。同时,这种方法也避免了现实应用中常常出现的可能长达几天甚至几周的大时间跨度的事务造成的并发存取资源的问题。

二、协同事务

从客户端或事务发起者的角度来观察数据的更新时,会考虑到的内容有存储系统、事务发起者、强一致性、弱一致性和最终一致性。这里的存储系统,指的是一个协同事务所存取的数据存储系统,通常由不同的业务所有者各自拥有一部分数据存储。例如从银行甲转账到银行乙的这样一个协同事务,其存储系统是由银行甲拥有的存储系统和银行乙拥有的存储系统组成。事务发起者是相互独立的并发的进程,都会对存储系统执行各自的协同事务。强一致性说的是在任何一个事务发起者完成数据更新后,其它发起者的后续访问都将得到更新后的值。弱一致性则不保证。从更新完成开始到保证任一观察者得到更新值为止这段时间称为不一致窗口。最终一致性是弱一致性的一种特殊形式,保证最终所有的访问都能得到最后的更新值。在满足最终一致性的条件下,在不一致窗口中,如果所执行的事务不违背业务规则的话,则该协同事务满足协同一致性。例如,一个三方转账业务中,事务一致性定义为甲方转账到乙方并且乙方转账到丙方,而协同一致性可能定义为必须在甲方转账到乙方完成后,才能并且必须进行乙方到丙方的转账;或者必须在乙方转账到丙方完成后,才能并且必须进行甲方到乙方的转账。

一个协同事务通常可被分解为若干串行执行的相关事务,其执行的先后次序体现了业务规则的公平性。在上述例子中,在传统的事务一致性定义下,是先从甲方转账到乙方,还是先从乙方转账到丙方,次序无关紧要, 因为事务的原子性保证了这两个操作要么都完成,要么都不完成。而在协同一致性的定义下,次序体现了业务规则的公平性: 如果完成一个双方的转账需要较长的时间,那么业务规则决定了资金会在哪一方的账户中停留或预支一段时间:先从甲转到乙,那么资金可能会在乙方账户上停留一段时间;先从乙转到丙,那么乙方会先预支一段时间。

组成协同事务的相关事务,除了具有传统事务的ACID特性外,还具有可逆性和幂等性。 这里的可逆性不同于可恢复资源的可恢复性。可恢复性指的是资源可恢复到事务前的状态,而可逆性指的是可消除增量性的操作。典型的增量性操作有在原有数值的基础上增加或减少若干数值。幂等性要求同一个相关事务可被执行多次,但其结果和只被执行一次是相同的。 幂等性的要求隐含了事务状态的持久性要求,即可以得知历史事务的执行情况,是提交还是回滚。

协同事务环境中,通常包含协同事务管理者和相关事务管理者两个角色。相关事务管理者负责管理相关事务。协同事务管理者负责管理和协调各个相关事务管理者,保证协同事务的协同一致性。如果协同事务中只包含一个相关事务管理者,那么它的工作很简单,只要告诉这个相关事务管理者提交或回滚。当协同事务包含多个相关事务管理者时,它按照业务规则顺次向相关事务管理者发出指令(在相关事务可并行的时候,也可发出并行指令)。当所有的相关事务管理者都给出了肯定的回答后,协同事务宣告完成。如果有某个相关事务管理者给出了否定的回答,那么协同事务管理者按照业务规则规定的相反次序,依次向已提交的相关事务管理者发出撤销命令,利用相关事务的可逆性撤销已完成的操作。如果由于通讯的原因,无法从某个相关事务管理者得到明确的答复时(肯定或否定的答复),协同事务管理者将不断地向其发出指令直到得到明确的答复。得不到明确的答复的一种常见的原因是相关事务管理者给出答复时失去了和协同事务管理者的联络。相关事务的幂等性保证了重复执行的正确性。

三、应用举例

考虑一个代收付的应用,AB转账100元,由B将其中的40元转账给C60元转账给D。我们约定,转账只能在同一银行的账户中进行。AB在银行x都有一个账户AxBxBC在银行y都有一个账户ByCyBD在银行z都有一个账户BzDz。业务规则约定,B只有在收到A的转账后,才向CD进行转账。于是可以设计出3个相关事务,T1AxBx转账事务,满足可撤销性;T2ByCy的转账,T3BzCz的转账,满足可撤销性和幂等性。协同事务管理者的执行图为T1T2||T3 

文章为作者独立观点,不代表联商专栏立场。

联商专栏原创文章由作者授权发表,转载须经作者同意,并同时注明来源:联商专栏+海鼎。