分布式系统原理(8)-- 基于MVCC的分布式事务

   实现分布式事务除了使用类似“两阶段提交”协议等方式外,另一种简单有效的方式使用MVCC(Multi-version Cocurrent Control,多版本并发控制)技术,最初也是在数据库系统中被提出。

(1)MVCC简介

   是一种多个不同版本的数据实现并发控制的技术,其思想是为每次事务生成一个新版本的数据,在读数据时选择不同版本的数据可以实现对事务结果的完整性读取。在使用MVCC时,每个事务都是基于一个已生效的基础版本进行更新,事务可以并行进行,从而可以产生一种图状结构

   如图,数据基础版本是1,同时产生两个事务A和B,分别对数据进行本地修改(仅事务自己可见,不影响真正数据),A首先提交,生成数据版本2,在基于2,发起事务C,C提交后生成数据版本3,最后B提交,B的结果与C合并,若无数据冲突,则可提交,否则B提交失败。

   MVCC的流程与SVN等版本控制系统相似,事务基于基础数据版本做本地修改时,为不影响真正数据,有两种做法:

1. 将基础版本中的数据完全拷贝出来再修改,SVN check out就是拷贝过程

2. 每个事务只记录更新操作,不记录完整数据,读取数据时再将更新操作应用到基础版本数据,类似SVN的增量提交

(2)分布式MVCC

分布式MVCC的重点不是并发控制,而是实现分布式事务。

扫描二维码关注公众号,回复: 1717720 查看本文章

   问题模型:在分布式系统中,更新操作以事务进行,每个事务包括若干个对不同节点的不同更新操作。更新事务必须具有原子性,即事务中所有更新操作要么同时在各个节点生效,要么都不生效,假设不存在并发的事务,即上一个事务成功提交后才进行下一个事务。

   实现方法:为每个事务分配一个递增的编号,这个编号也代表了数据的版本号,当事务在各个节点上执行时,各个节点只需记录更新操作及事务编号,当事务在各个节点都完成后,在全局元信息中记录本次事务的编号。在读取数据时,先读取元信息中已成功的最大事务编号,再在各个节点上读取数据,只读取更新操作编号小于等于最大已成功提交事务编号的操作,并应用到基础数据形成读取结果。

   举例:系统中节点A/B状态如下表

1. 若此时全局元信息中的最大的生效事务序号为1,则在节点A上:var1 = 1,var2 = 2,在节点B上,var3 = 2;

2. 若此时全局元信息中的最大的生效事务序号为2,则在节点A上:var1 = 1 + 2 = 3,var2 = 2,在节点B上:var3 = 2,var4 = 1,

   优点:在新事务执行过程中,虽然更新操作已逐步记录到各个节点,但只要全局元信息不修改,始终不会读到没有生效的事务数据,从而实现全局一致性。并且,由于数据具有多个版本,可以自然实现对历史版本数据的读取

   缺点:随着执行的事务越来越多,各个站点保存的更新操作会越来越多,读取数据时需要应用的更新操作也越来越多。

   改进:工程中可以周期性的启动合并操作,将历史上不再需要的版本合并为一个更新操作

(3)工程投影

a)Megastore中的MVCC

Megastore利用了Big Table中的数据的多版本特性实现分布式的更新事务。每个事务更新的都是不同版本(timestamp)的Big Table数据,在读取数据时利用timestamp过滤,从而不会读到正在进行的尚未生效的事务数据。

b)Doris*中的MVCC

在Doris*系统中,数据按批进行更新,每个批量的数据都可以认为是一个事务,必须同时原子性的生效。为此,Doris*将每条数据附带了一个导入的版本号,在读取数据时根据元数据中已生效的版本号与 的导入版本号做过滤,从而不读取正在更新的尚未生效的数据,实现了分布式事务更新


猜你喜欢

转载自blog.csdn.net/summer00072/article/details/80774088