分布式事务:两阶段提交(2PC)

原子提交

事务的结果要么成功提交(所有事务的写入都是持久的),要么中止(此时所有事务的写入都被回滚)

  • 单节点

    对于在单个数据库节点上执行的事务,原子性通常由存储引擎来负责。当客户端请求数据库节点提交事务时,数据库首先使事务的写入持久化(通常保存在预写日志中),然后把提交记录追加写入到磁盘的日志文件中。

    如果数据库在该过程中发生了崩溃,那么当节点重启后,事务可以从日志中恢复:如果在崩溃之前提交记录已成功写入磁盘,则认为事务已安全提交;否则,回滚该事务的所有写入。

  • 分布式

    向所有节点简单地发送一个提交请求,然后各个节点独立执行事务提交是绝对不够的。这样做很容易发生部分节点提交成功,而其他一些节点发生失败,从而违反了原子性保证

    • 提交请求在网络中丢失

    • 节点在写入前发生崩溃

两阶段提交(2PC)

在多节点之间实现事务原子提交的算法,用来确保所有节点要么全部提交,要么全部中止。2PC是一种共识算法。

协调者

2PC引入了协调者,协调者通常实现为共享库,运行在请求事务相同进程中,也可以是单独的进程或服务。

当应用程序启动一个分布式事务时,它首先向协调者请求事务ID,该ID全局唯一。应用程序在每个参与节点上执行单节点事务,并将ID附到事务上

  • 阶段1: 当应用程序准备提交事务时,协调者发送一个准备请求到所有节点,并附带全局事务ID,询问他们是否可以提交。如果所有参与者回答“是”,协调者接下来在阶段2会发出提交请求,提交开始实际执行;如果有任何参与者回答“否”,则协调者在阶段2中通知所有参与者放弃事务。
  • 阶段2: 协调者的决定写入磁盘后,向所有参与者发送提交(或放弃)请求。如果此请求出现失败或超时,则协调者必须一直重试,直到成功为止。此时,所有节点不允许反悔,如果之前所有参与者都投票选择了“是”,那即使在此期间出现故障,在恢复之后也必须执行。

提交点: 当协调者在阶段1收到所有准备请求答复时,就是否提交事务要做出明确的决定,并把最后的决定写入磁盘的事务日志中,防止系统崩溃。

两条“不归路”

  • 当参与者投票“是”,它做出了肯定提交的承诺,不可撤销
  • 协调者做出了提交 / 放弃的决定,这个决定也不可撤销

协调者发生故障

假设在协调者向参与者发送提交请求时,数据库2收到了该请求,而紧接着协调者崩溃,数据库1没有收到该请求,此时参与者无法知道下一步行动。此时超时机制也无法解决问题:如果超时之后数据库1决定单方面中止,最终将与完成提交的数据库2不一致。

2PC能够顺利完成的唯一方法是等待协调者恢复,这就是协调者必须在向参与者发送提交 / 放弃请求之前将决定写入磁盘的原因:等协调者恢复后,通过读取事务日志来确定所有未决的事务状态。

2PC的问题

  • 同步阻塞问题:各个参与者在等待其他参与者响应的过程中,将无法进行其他的任务操作
  • 单点故障:一旦协调者出现问题,那么整个第二阶段提交流程将无法运转,其他的参与者将会处于锁定事务资源的状态中,而无法继续完成事务操作。
  • 无容错机制:当任意一个参与者节点宕机,那么协调者超时没收到响应,就会导致整个事务回滚失败。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值