原子性:2PC还是原子性协议的王者吗

86 阅读3分钟

面向应用层的 TCC

TCC 的整个过程由两类角色参与,一类是事务管理器,只能有一个;另一类是事务参与者,也就是具体的业务服务,可以是多个,每个服务都要提供 Try、Confirm 和 Cancel 三个操作。

try成功:

image.png

try失败:

image.png

TCC 仅是应用层的分布式事务框架,具体操作完全依赖于业务编码实现,可以做针对性的设计,但是这也意味着业务侵入会比较深。

此外,考虑到网络的不可靠,操作指令必须能够被重复执行,这就要求 Try、Confirm、Cancel 必须是幂等性操作,也就是说,要确保执行多次与执行一次得到相同的结果。显然,这又增加了开发难度。

2PC

2PC 的处理过程也分为准备和提交两个阶段,每个阶段都由事务管理器与资源管理器共同完成。其中,事务管理器作为事务的协调者只有一个,而资源管理器作为参与者执行具体操作允许有多个。

第一阶段成功:

image.png

第一阶段失败:

image.png

相比于 TCC,2PC 的优点是借助了数据库的提交和回滚操作,不侵入业务逻辑。但是,它也存在一些明显的问题:

  1. 同步阻塞,第一阶段要锁定对应的数据行
  2. 单点故障,事务管理器非常重要
  3. 数据不一致,第二阶段,发生局部网络异常,导致部分数据库接收到请求,会导致数据不一致。

分布式数据库的两个 2PC 改进模型

NewSQL 阵营:Percolator

image.png

第一,准备阶段,事务管理器向分片发送 Prepare 请求,包含了具体的数据操作要求。分片接到请求后要做两件事,写日志和添加私有版本。关于私有版本,你可以简单理解为,在 lock 字段上写入了标识信息的记录就是私有版本,只有当前事务能够操作,通常其他事务不能读写这条记录。主锁的选择是随机的,参与事务的记录都可能拥有主锁,但一个事务只能有一条记录拥有主锁,其他参与事务的记录在 lock 字段记录了指针信息“primary@Ming.bal”,指向主锁记录。

image.png

第二,提交阶段,事务管理器只需要和拥有主锁的分片通讯,发送 Commit 指令,且不用附带其他信息。还会有其他异步线程来更新小红的余额记录,最终变成下面的样子。

image.png

PGXC 阵营:GoldenDB 的一阶段提交

image.png image.png

第一阶段,GoldenDB 的协调节点接到事务后,在全局事务管理器(GTM)的全局事务列表中将事务标记成活跃的状态。这个标记过程是 GoldenDB 的主要改进点,实质是通过全局事务列表来申请资源,规避可能存在的事务竞争。

image.png

第二阶段,协调节点把一个全局事务分拆成若干子事务,分配给对应的 MySQL 去执行。如果所有操作成功,协调者节点会将全局事务列表中的事务标记为结束,整个事务处理完成。如果失败,子事务在单机上自动回滚,而后反馈给协调者节点,后者向所有数据节点下发回滚指令。

GoldenDB 的“一阶段提交”,本质上是改变了资源的申请方式,更准确的说法是,并发控制手段从锁调度变为时间戳排序(Timestamp Ordering)。这样,在正常情况下协调节点与数据节点只通讯一次,降低了网络不确定性的影响,数据库的整体性能有明显提升。因为第一阶段不涉及数据节点的操作,也就弱化了数据一致性和单点故障的问题。


此文章为6月Day10学习笔记,内容来源于极客时间《分布式数据库30讲》