2PC协议(2-phase-commit protocol)

本文深入探讨了两阶段提交协议(2PC),一种确保分布式事务强一致性的算法。详细介绍了其执行过程,包括请求阶段和提交阶段,以及协议特点和潜在问题。通过具体案例,阐述了2PC在实际应用中的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、协议概述

两阶段提交协议(2-phase-commit protocol,2PC)可以保证数据的强一致性,许多分布式关系型数据管理系统采用此协议来完成分布式事务。它是协调所有分布式原子事务参与者,并决定提交或回滚的分布式算法。也是解决一致性问题的一致性算法。为了能够使参与者从故障在恢复,采用日志记录协议的状态,虽然使用日志降低了性能但是节点能从故障中恢复。

在2PC中,系统一般含两类节点:

协调者 coordinator,通常一个系统中只有一个

参与者 workers,一般含多个,在数据存储系统中可以理解为数据副本的个数

协议中假设:

① 每个节点都记录写前日志并持久性存储,即使节点故障日志也不会丢失

② 节点不会发生永久性故障且任意两个节点间可以相互通信

当事务最后一步完成,协调者执行协议,参与者根据本地事务,能够成功完成回复同意提交事务或者回滚事务。

 

二、执行过程

两阶段提交由两个阶段组成:

1. 请求阶段(commit-request phase)

在此阶段,协调者通知事务参与者准备提交回滚事务,然后进入表决过程:在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或回滚(本地作业执行故障)

2. 提交阶段(commit phase)

在该阶段,协调者基于第一个阶段的结果进行决策:提交取消当且仅当所有参与者回复同意,才通知所有事务参与者提交事务,否则协调者将通知事务参与者回滚事务。参与者在接收到协调者发来的消息后执行相应的操作。

 

三、协议的特点

两阶段提交系统通过阻塞完成协议,在节点等待消息的时候处于阻塞状态,节点中其他进程需等待阻塞进程释放资源才能使用。如果协调器发生了故障,那么事务参与者则会一直等待。以下情况可能会导致节点发生永久阻塞

(1) 参与者发送同意提交消息给协调者,进程将阻塞直到协调者发消息。若协调者永久故障,参与者将一直等待。此问题可通过备份协调器解决。

(2)若协调器发送“请求提交”给所有参与者,它将被阻塞直到所有参与者回复。若某参与者永久故障,那么协调器也不会一直阻塞。在某一时间内还未收到某参与者消息,它将通知其他参与者回滚事务。

2PL没有容错机制,一个节点故障整个事务都回滚,代价较大。

 

四、工作过程

通过一个例子说明两阶段提交协议的工作过程:

A是保险公司销售小组组长,负责召开会议,B,C,D是苦逼的保险推销员。公司规定由组长召开小组会议,必须全员到场。A在星期六晚上发送下周一召开会议的通知给B,C,D。如果所有人周一都有时间来开会,那么会议将如期开展;若有任何一个有事不能在现场,则会议取消另定时间。用2PC算法解决过程:

A是协调者,B,C,D是该会议的参与者:

(1)请求阶段:

① A发送邮件给B,C,D,通知周一举行会议,询问是否都能到场。A此时等待B,C,D的回复邮件

② B,C,D分别查看自己的日程按排。B,C发现周一没有约见客户的日程安排,身为苦逼的员工当然得去开会!于是发邮件告诉A,会按时到场。由于某种原因,D白天没有查看邮件。那么此时A,B,C都需要等待。到晚上D发现了A的邮件,查看自己的日程安排,发现周一正好要去见客户,那么D就回复A:我要出外勤,无法参会,会议能不能改天?

(2)提交阶段(commit phase)

① A已经收到所有参与者的邮件,发现D因为公事无法参加周一的会议,于是 A发邮件通知 B,C,D。下周一的会议取消。

② 此时 B,C心里乐开了花,不用开会。至此事务结束。

 

通过上面的例子可以发现,2PC存在一定问题。如果D一直不回复邮件,那么A,B,C将一直处于等待状态。而且B,C所持有的资源,即周一不可以安排其他活动(见客户,上门推销保险...),一直不能释放。其他等待该资源释放的活动也不得不处于等待状态。

 

部分引用自:https://www.cnblogs.com/sunddenly/articles/4072882.html

03-19
### 什么是两阶段提交协议 (2PC) 两阶段提交协议(Two-Phase Commit Protocol,简称 2PC)是一种经典的分布式事务管理协议,旨在确保跨多个节点的操作具备原子性和一致性[^1]。其核心思想是将整个事务的提交过程划分为两个主要阶段:**准备阶段(Prepare Phase 或 Voting Phase)** 和 **提交阶段(Commit Phase 或 Execution Phase)**。 #### 准备阶段(Voting Phase) 在这个阶段中,协调者(Coordinator)向所有参与者发送 `prepare` 请求,询问它们是否准备好提交当前事务。每个参与者会执行本地操作并将结果保存到持久化存储中,但不会真正提交这些更改。如果成功,则返回“同意”;如果有任何错误发生或者无法满足条件,则返回“拒绝”。只有当所有参与者都回复“同意”时,才会进入下一阶段[^3]。 #### 提交阶段(Execution Phase) 一旦收到所有参与者的肯定答复,“协调者”就会广播一条全局性的 `commit` 命令给每一个涉及其中的服务端点。此时各服务端正式确认修改并释放锁资源等约束机制从而完成整体流程。反之亦然,只要有一个成员反对此次变更计划,则由管理者发出相应的撤销通知让其余部分也跟着撤回先前所做的预备工作以维持状态同步一致[^4]。 这种设计虽然有效保障了系统的可靠性以及数据之间的连贯性,但也存在一些局限之处比如性能开销较大、单点故障风险等问题[^2]。 ```python class TwoPhaseCommitProtocol: def __init__(self, participants): self.participants = participants def prepare(self): votes = [] for participant in self.participants: vote = participant.prepare() votes.append(vote) return all(votes) def commit(self): if not self.prepare(): raise Exception("Transaction cannot be committed due to failed preparation.") for participant in self.participants: participant.commit() def rollback(self): for participant in self.participants: participant.rollback() ``` 上述代码片段展示了一个简单的实现框架,展示了如何通过 Python 来模拟基本的两阶段提交逻辑。 --- ### 局限性与挑战 尽管 2PC 是一种强大的工具,但它并非完美无缺。以下是几个值得注意的地方: - 高延迟:由于需要等待所有站点响应,因此可能会增加处理时间。 - 单一失败点:如果协调器本身出现问题,那么整个系统可能陷入停滞状态直到问题得到解决为止。 - 死锁定情况下的复杂恢复过程:当某些组件暂时不可用而其他仍在线运行的情况下,可能导致死锁现象出现,这时往往需要人工干预来进行解锁操作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值