Google关于Spanner的论文中分布式事务的实现
Google关于Spanner的论文中分布式事务的实现
Google在Spanner相关的论文中详细的解释了Percolator分布式事务的实现方式, 而且用简洁的伪代码示例怎么实现分布式事务;
Percolator算法在分布式数据库中运用广泛, 国内著名的开源分布式数据库TiDB的事务实现来源于Percolator, 腾讯TBase的分布式事务实现也来自于Percolator;
在讲Percolator之前, 我们先看几个问题:
1, 假设一个事务开始的时间戳是 T2 , 这个事务读取数据的原则是什么, 是读取最新的数据还是只能读取截止到 T2 的数据?
2, 假设一个事务里面需要访问很多表的记录, 而且都是截止到 T2 时间戳的快照, 怎么能获取到这些快照?
3, 假设一个事务操作很多记录, 这些记录落在多台服务器上, 怎么能保证多台服务器上的记录操作都是在原子锁的情况下进行?
4, 假如有多个 Worker 操作多个服务器上的多条记录上的锁, 这些记录和锁属于一个事务, 怎么能保证这些记录全部提交, 或者这些记录全部回滚?
我们直接摘抄Google的论文, 看看 Percolator 的实现:
假设有一个表, 有2个用户, Bob和Joe, Bob的账户余额是$10, Joe的账户余额是$2
下面开始一个事务, Bob转 7美金给Joe:
假设这个事务开始的时候, 时间戳是 7, 这个时间戳是事务开始时间戳;
第 1 步, 加主锁, 主锁只有一个;
在Bob这条记录(row)的bal列(余额列)的data列, lock列, 都写入带有时间戳7的记录, row上的操作是行级别的事务;
第 2 步, 加从锁, 从锁关联主锁, 从锁可以有多个;
在Joe这条记录(row)的bal列(余额列)的data列, lock列, 都写入带有时间戳7的记录, row上的操作是行级别的事务;
上述流程是第1阶段, 预写入(Prewrite);
Prewrite之后, 进入第 2 个阶段, 提交阶段(Commit阶段);
提交阶段会获取第2个时间戳---提交时间戳, 这里假设是8;
一旦清除主锁, 并写入write列, 则事务一定要完成; 从锁可以保证即使发生异常, 事务也能进行前向滚动从而完成整个事务; 而主锁可以确保事务加锁的原子性;
注意1: 需要说明一点, 因为对每一个记录的操作都会涉及到多个列, 所以会使用 row 事务, 保证对同一row的多个列的操作是原子性的;
上面就是Commit流程, 先处理主锁, 然后依次处理从锁, 主锁是关键, 是原子级的锁, 一旦主锁提交(这是一个row事务, 更新lock列和write列), 这个事务必须要提交;
如果主锁没有提交, 则这个事务是可以回滚的, 回滚时也必须先操作主锁, 确保对多个锁的原子性操作, 然后依次处理从锁, 事务提交者在Commit阶段发现主锁已经失效, 说明事务被其他worker回滚掉了, 不能进行提交;
可以看到, Percolator包括:
1. 两阶段提交, Prewrite阶段, Commit阶段;
2. 主从锁, 主锁作为多个锁当中的负责原子级操作的锁;
3. 多列(data, lock, write);
4. 每一个维度的列都带时间戳;
5. 数据多版本(MVCC);
我们看看Google论文里面的伪代码示例:
Get函数伪代码:
一个读操作需要等待lock列的锁, 范围是早于读取的时间戳, 一个前次的事务有可能还在Commit阶段, 而且Commit的时间戳也是小于读取操作的时间戳的;
Prewrite函数, 注意, 这只是Prewrite函数不是Prewrite阶段
Commit函数, 里面实现了两阶段提交
一个事务的关键节点是--清除lock上的主锁, 并且在write列写入---这个操作是原子性的, 基于row事务---一旦这个操作完成, 事务必须完成, 即使事务的worker挂掉, 其他worker也有义务帮助这个事务完成前向滚动(rolled farward), 您可以把他看成是mysql的redo操作; 如果这个操作没有完成, 其他worker可以回滚掉这个事务, 一般是这个事务的worker产生了异常, 例如事务超过了一定的时限; 即使没有超过时限, 回滚也是安全的, 不违反一致性;
现在回到我们开始的问题;
1, 假设一个事务开始的时间戳是 T2 , 这个事务读取数据的原则是什么, 是读取最新的数据还是只能读取截止到 T2 的数据;
只能读取T2时间戳的数据, 依据write列的时间戳, 这样是为了在事务里面获得一致性的快照(snapshot); 一般叫做可重复读(Read Repeatable)
2, 假设一个事务里面需要访问很多表的记录, 而且都是截止到 T2 时间戳的快照, 怎么能获取到这些快照?
根据write列的时间戳来获取T2时间戳的快照;
3, 假设一个事务操作很多记录, 这些记录落在多台服务器上, 怎么能保证多台服务器上的记录操作都是在原子锁的情况下进行?
主锁(Primary lock)和write列是关键;
4, 假如有多个 Worker 操作多个服务器上的多条记录上的锁, 这些记录和锁属于一个事务, 怎么能保证这些记录全部提交, 或者这些记录全部回滚?
主锁和write列是判断事务成功提交的关键, 主锁和write列操作成功, 事务一定要提交, 如果提交事务的worker挂了, 其他的worker根据从锁(Secondary lock)帮助提交(rolled forward); 否则, 可以回滚(roll back), 回滚依赖于事务的超时时间和事务负责的worker的存活状态;
下篇博客, 我们一起看下TiDB里面分布式事务的实现代码;
Google关于Spanner的论文中分布式事务的实现的更多相关文章
- Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案
Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案 说明:Java生鲜电商平台中由于采用了微服务架构进行业务的处理,买家,卖家,配送,销售,供应商等进行服务化,但是不可避免存在 ...
- C#中分布式事务的超时处理问题
事务是个很精妙的存在,我们在数据层.服务层.业务逻辑层等多处地方都会使用到. 在这里我只说下TransactionScope这个微软推荐使用的隐式事务.它是从Framework 2.0开始引入的一个事 ...
- ASP.NET中分布式事务的使用
之前发表了一篇事务的存储过程,最近在做项目的时候遇到分布式事务,所有总结一下,跟大家分享和交流一下经验.首先说明为什么要分布式事务呢?先说说我在项目的哪里遇到分布式事务吧,我是在做网站后台开发的时候, ...
- [论文翻译] 分布式训练 Parameter Sharding 之 Google Weight Sharding
[论文翻译] 分布式训练 Parameter sharding 之 Google Weight Sharding 目录 [论文翻译] 分布式训练 Parameter sharding 之 Google ...
- j2ee中spring的分布式事务实现及解决方案
1 java事务类型 Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供 ...
- MySQL 中基于 XA 实现的分布式事务
1 XA协议 首先我们来简要看下分布式事务处理的XA规范可知XA规范中分布式事务有AP,RM,TM组成: 其中应用程序(Application Program ,简称AP):AP定义事务边界(定义事务 ...
- oracle分布式事务总结-转载
基本概念 Local Coordinator:在分布事务中,必须参考其它节点上的数据才能完成自己这部分操作的站点. Global Coordinator:分布事务的发起者,负责协调这个分布事务. Co ...
- Spring分布式事务实现
分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.JtaTransactionManager,提供了分布式事务支持.如果使用 ...
- Spring分布式事务实现(适用于spring-tx 2.5)
http://log-cd.iteye.com/blog/807607 分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.J ...
随机推荐
- DBUtils工具类
import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql. ...
- docker:学习笔记
docker run -itd --net=none 22565cef72c2 /usr/sbin/sshd -Dpipework br0 5a3e7bab4c5c5260a93e153aa7fec3 ...
- verilog 介绍
Verilog HDL Verilog HDL是在C语言的基础上发展起来的一种硬件描述语言,语法较自由.VHDL和Verilog HDL两者相比,VHDL的书写规则比Verilog HDL烦琐一些,但 ...
- centos7,zabbix3.2通过zabbix_java_gateway监控jmx[java/tomcat]
网络上很多教程也比较多和全了,但是自己做时候多多少少的坑备注下吧. 1,监控原理简单说一下,就是zabbix_server通过代理(zabbix_java_gateway)来获取agent端(tomc ...
- 魔力Python——一些基本概念
1.I/O操作 I/O输入/输出(input/output)的缩写. 概念I/O系统,英文全称为“Input output system”,中文全称为“输入输出系统”,由输入输出控制系统和外围设备两部 ...
- Winform 中写代码布局中遇到的控件遮盖问题
在winform中编程时,需要动态向主窗体中增加菜单栏和用户控件,菜单栏需要设置DockStyle为Top ,而设置用户控件的DockStyle为Fill,之后在加载的时候,出现了菜单栏遮盖用户控件的 ...
- C# 字符串按 ASCII码 排序,注意其中的小坑
https://www.cnblogs.com/similar/p/6739293.html 在和银行做数据对接时,涉及到数据传输时的验签及加密.其中数据签名方案中就要求数据项根据属性名按 ASCII ...
- redis数据转移随笔
生产环境有一批版本比较老的redis主从架构,是一主多从,版本是2.8 由于想迁移到阿里云上,那么问题来了,怎么把redis数据转移到阿里云上 为了省事,阿里云也是和生产环境一样的版本,架构也一致,其 ...
- register关键字
register关键字从c++11开始已经弃用了,但是在看SuRF代码(https://www.cnblogs.com/YuNanlong/p/10235793.html) 的时候,还是看到了这个关键 ...
- 《Dare To Dream 》第三次作业--团队项目的原型设计与开发
一.实验目的与要求 1.掌握软件原型开发技术: 2.学习使用软件原型开发工具: 二.实验内容与步骤 任务1:针对实验六团队项目选题,采用适当的原型开发工具设计团队项目原型: 任务2:在团队博客发布博 ...