Spanner分布式事务

Spanner要满足的external consistency 是指:后开始的事务一定可以看到先提交的事务的修改。所有事务的读写都加锁可以解决这个问题,缺点是性能较差。特别是对于一些workload中只读事务占比较大的系统来说不可接受。为了让只读事务不加任何锁,需要引入多版本。在单机系统中,维护一个递增的时间戳作为版本号很好办。分布式系统中,机器和机器之间的时钟有误差,并且误差范围不确定,带来的问题是如何给一个只读事务赋予一个时间戳作为版本号。Spanner通过原子钟和GPS解决了这个误差范围不确定的问题,由于原子钟和GPS比较昂贵,只在数据中心的某些机器上部署,对外提供TrueTime API,数据中心的其他server通过调用API来得到真实时间,API返回值为一个区间[start,end],保证当前的真实时间位于这个区间。

Spanner是一个支持分布式读写事务,只读事务的分布式存储系统,只读事务不加任何锁。和其他分布式存储系统一样,通过维护多副本来提高系统的可用性。一份数据的多个副本组成一个paxos group,通过paxos协议维护副本之间的一致性。对于涉及到跨机的分布式事务,涉及到的每个paxos group中都会选出一个leader,来参与分布式事务的协调。这些个leader又会选出一个大leader,称为coordinator leader,作为两阶段提交的coordinator,记作coordinator leader。其他leader作为participant。

数据库事务系统的核心挑战之一是并发控制协议。Spanner的读写事务使用两阶段锁来处理。分布式读写事务请求到达coordinator leader后,coordinator leader运行两阶段提交协议,将读写请求发给participant,pariticpant和coordinator leader开始加读,写锁。最后commit的时候,读写锁解除。

如第一段所述,给只读事务赋予一个时间戳版本号是这样一个分布式存储系统的核心,对应的,读写事务也需要被指定时间戳版本号。下面先说如何确定读写事务的版本号,再说只读事务。

前面已经说了两阶段提交过程中两阶段锁的过程,这里就省略这些,只讨论两阶段提交过程中如何确定最后的读写事务的时间戳版本号。

读写事务 

读写事务开始时,coordinator leader 首先调用TrueTime API,获得一个时间区间[CB1,CE1],然后给所有的participants发送prepare消息,participants收到prepare消息后,调TrueTime API返回区间[PB,PE],然后取PB和这个participants维护的已commit的事务版本号的最大值。记participant维护的已commit的最大事务时间戳为maxtimestamp,那么将max(maxtimestamp+1, PB)返回给coordinator leader。coordinator leader收集到所有prepare的时间戳后,从中选出一个最大的,记作maxpreparetimestamp,同时再次调用一次TrueTime API,获得时间区间[CB2,CE2],为了保证这个分布式事务的时间戳确实位于这个分布式事务执行过程中的某个点,coordinator leader必须为这个分布式事务选择一个介于[CE1,CB2]的时间戳。另外,这个分布式事务的时间戳还必须满足一个条件,就是大于maxpreparetimestamp。从B的角度来看,如果本地已提交事务版本号比要读的版本号大,就可以读。这就要保证后面提交的单机事务和分布式事务版本号都要比现在已提交事务的版本号更大。否则,读的时候可能会有事务插进来,导致都到的数据可能不是一个快照。

另外,一台机器在收到快照读时,有可能需要阻塞。举个例子,在分布式系统中,即有分布式事务也有单机事务,以A,B,C为例,A为coordinator leader,B和C为participant,以B为例,假设B当前维护的本机最大的commit时间戳为100,现在从A来了一个分布式事务T1的prepare请求,B返回了101给A,在这个分布式事务commit之前,B机器来了一个单机事务T2,并且先于T1提交,时间戳为105,而A可能为这个分布式事务指定的版本号为104. 显然,如果在T1提交前来了一个大于101比如110的快照读事务,这个快照读事务必须被阻塞住直到T1提交才能向客户端返回结果,因为B不知道T1这个还未commit的事务最后的时间戳是多少。

只读事务

一种方法是询问一边所有的participants,从所有的commit timestamp中拿出最大的作为时间戳去读即可。或者调用TrueTime API,将右区间作为只读事务的版本号即可。

下面说一下两阶段提交的错误处理。

同样以A,B,C三份数据为例,他们分别有三个副本,记作(A1,A2,A3),(B1,B2,B3),(C1,C2,C3),每组作为一个paxos group,内部通过paxos协议保证一致性。假设,A1,B1,C1分别为各自paxos group的leader,A1为coordinator leader。

Prepare阶段:A1给B1和C1发送prepare消息后,假设B1挂了,A1等待超时,A1给C1发送rollback。B1后续回滚分为两种情况:1. B1在持久化prepare消息之前挂了,B1恢复后可自行回滚 2. 如果B1持久化prepare消息之后挂了,B1自身可以回放日志得知事务未决,主动联系(A1,A2,A3)。A1给B1,C1发送prepare消息之后,自己挂了,同样,A1通过回放日志可以得知。实际上,A1本身挂了之后,A2和A3通过选主协议选出一个新的leader,这个新的leader内存中很有可能已经有了状态。

Commit阶段:A1给B1,C1发送commit消息,B1 commit成功,C1挂了,C1起来后,如果C1之前没有持久化commit消息,则A1主动要求C1继续commit。如果C1之前已经持久化了commit消息,则自己commit。如果C1由于某些原因,始终commit不成功,则由上层业务进行回补操作。

Spanner分布式事务

时间: 2024-08-24 14:33:16

Spanner分布式事务的相关文章

分布式事务实现-Spanner

Spanner要满足的external consistency 是指:后开始的事务一定可以看到先提交的事务的修改.所有事务的读写都加锁可以解决这个问题,缺点是性能较差.特别是对于一些workload中只读事务占比较大的系统来说不可接受.为了让只读事务不加任何锁,需要引入多版本.在单机系统中,维护一个递增的时间戳作为版本号很好办.分布式系统中,机器和机器之间的时钟有误差,并且误差范围不确定,带来的问题就是很难判断事件(在本文,事件指分布式事务版本号)发生的前后关系.反应在Spanner中,就是很难

蚂蚁技术专家:一篇文章带你学习分布式事务

小蚂蚁说: 分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在这几年越来越火的微服务架构中,几乎可以说是无法避免,本文就围绕分布式事务各方面与大家进行介绍. 一. 事务 1.1 什么是事务 数据库事务(简称:事务,Transaction)是指数据库执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成. 事务拥有以下四个特性,习惯上被称为ACID特性: 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要

XA分布式事务

XA分布式事务 XA XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准.目前,Oracle.Informix.DB2和Sybase等各大数据库厂家都提供对XA的支持.XA协议采用两阶段提交方式来管理分布式事务.XA接口提供资源管理器与事务管理器之间进行通信的标准接口.XA协议包括两套函数,以xa_开头的及以ax_开头的 简介编辑 取决于上下文, XA 有多种意思. 我们常见的数据库连接交易中的 XA 是指由 X/Open 组织提出的分布式交

浅谈分布式事务

前言应用场景 事务必须满足传统事务的特性,即原子性,一致性,分离性和持久性.但是分布式事务处理过程中, 某些场地比如在电商系统中,当有用户下单后,除了在订单表插入一条记录外,对应商品表的这个商品数量必须减1吧,怎么保证? 在搜索广告系统中,当用户点击某广告后,除了在点击事件表中增加一条记录外,还得去商家账户表中找到这个商家并扣除广告费吧,怎么保证? 一 本地事务以用户A转账用户B为例,假设有 用户A账户表:A(id,userId,amount) 用户B账户表:B(id,userId,amount

聊聊分布式事务

聊聊分布式事务 2017-04-15 数据库开发 (点击上方公众号,可快速关注) 作者:员海滨 nickid.cn/2017/04/分布式事务/ 如有好文章投稿,请点击 → 这里了解详情 分布式事务场景如何设计系统架构及解决数据一致性问题,个人理解最终方案把握以下原则就可以了,那就是:大事务=小事务(原子事务)+异步(消息通知),解决分布式事务的最好办法其实就是不考虑分布式事务,将一个大的业务进行拆分,整个大的业务流程,转化成若干个小的业务流程,然后通过设计补偿流程从而考虑最终一致性. 什么是事

使用事件和消息队列实现分布式事务(转+补充)

虽然本文并非笔者原创,但是我们在非强依赖的事务中原理上也是采用这种方式处理的,不过因为没有仔细去总结,最近在整理和总结时看到了,故转载并做部分根据我们实际情况的完善和补充. 不同于单一架构应用(Monolith), 分布式环境下, 进行事务操作将变得困难, 因为分布式环境通常会有多个数据源, 只用本地数据库事务难以保证多个数据源数据的一致性. 这种情况下, 可以使用两阶段或者三阶段提交协议来完成分布式事务.但是使用这种方式一般来说性能较差, 因为事务管理器需要在多个数据源之间进行多次等待. 有一

java分布式事务

原文地址:http://blog.csdn.net/moonpure/article/details/52779794 在本系列先前的文章中,我们主要讲解了JDBC对本地事务的处理,本篇文章将讲到一个分布式事务的例子. 请通过以下方式下载github源代码: git clone https://github.com/davenkin/jta-atomikos-hibernate-activemq.git 本地事务和分布式事务的区别在于:本地事务只用于处理单一数据源事务(比如单个数据库),分布式事

分布式事务 解决方案

事务的概念来源于业务过程.在许多情况下我们都希望能够确保在一个过程中执行的所有操作是完全成功的.在集中式系统中,事务被广泛用于服务器端和数据库系统,控制数据的操作.随着分布式计算的发展,事务在分布式计算领域中也得到了广泛的应用,但是分布式系统架构中,分布式事务问题是一个绕不过去的挑战.而微服务架构的流行,让分布式事问题日益突出! 下面我们以电商购物支付流程中,在各大参与者系统中可能会遇到分布式事务问题的场景进行详细的分析! 如上图所示,假设三大参与平台(电商平台.支付平台.银行)的系统都做了分布

关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究[转]

1.XA XA是由X/Open组织提出的分布式事务的规范.XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口.XA接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁.XA之所以需要引入事务管理器是因为,在分布式系统中,从理论上讲(参考Fischer等的论文),两台机器理论上无法达到一致的状态,需要引入一