首页 > 编程语言 >深入理解分布式共识算法(一)——2pc_3pc

深入理解分布式共识算法(一)——2pc_3pc

时间:2024-04-29 16:33:20浏览次数:15  
标签:事务 协调者 回滚 2pc 提交 3pc 参与者 分布式

分布式事务问题

img

通常单节点事务比较简单,Spring 提供的 @Transaction 注解能够实现。但是在分布式场景下,比如 ServiceA 调用 ServiceBServiceC,每个服务分别操作各自的数据库,如果某个服务调用成功、另外一个调用失败,就会造成数据的不一致性,这就是分布式事务问题。

2PC

二阶段提交是一种 强一致性、中心化的原子提交协议

  • 强一致性:体现在所有的参与者都能实时保持一致的数据、一致的状态。
  • 中心化:分为协调者和参与者。
    • 协调者负责协调整个事务的提交和回滚操作,负责推进分布式事务;比如上图的 ServiceA;
    • 参与者是事务资源的拥有者,比如上图的 ServiceB、ServiceC;
  • 原子提交:分布式事务中所有协调者要么全部成功,要么全部失败。

准备阶段

img

  • 客户端发起一个分布式事务到协调者,协调者向所有的参与者广播 Prepare 请求;
  • 参与者在收到 Prepare 请求后会记录事务日志(RedoLogUndoLog),然后根据这个事务需要锁定的资源尝试去执行,根据是否能够执行事务反馈协调者 Yes/No 响应;
  • 协调者接收到所有参与者的响应,如果全部为 Yes,就会进入提交阶段。
  • 协调者如果接收到一个参与者的 No 响应,就会进入 global rollback 阶段,进行全局回滚。

提交阶段

img

  • 协调者通知所有参与者可以提交本次分支事务,发送 global commit 请求;
  • 参与者收到请求后,根据准备阶段记录的 RedoLog 日志,提交本地的分支事务;
  • 参与者在提交事务成功后,就会返回 ack 响应给协调者;
  • 协调者在接收到所有参与者成功的响应之后,返回给客户端成功。

全局回滚阶段

img

  • 协调者向所有参与者发送 global rollback 请求;
  • 参与者收到请求后,会根据本地的 undoLog 回滚本地事务,回滚成功后返回给协调者 ack 响应;
  • 协调者接收到所有 ack 响应之后,返回给客户端本次分布式事务执行失败。

隐藏问题

  • 数据不一致问题:二阶段回滚或者提交阶段,如果某个参与者回滚或者提交失败了,协调者可以采取一个定期重试来确保所有参与者回滚成功。
  • 同步阻塞问题:协调者必须等待所有参与者的 Yes/No 响应后,才能进入第二阶段;参与者必须等待协调者的 global commit/global rollback 请求后才能进入第二阶段;如果协调者出现宕机了,那么所有参与者都无法释放事务资源。
  • 单点问题/脑裂:整个分布式事务驱动都是基于协调者去做的,如果协调者出现问题,整个过程不可用。

3PC

三阶段提交是为了解决二阶段提交的 数据不一致、同步阻塞、单点等问题。

引入了超时机制

  • 参与者在等待协调者请求超时后,允许执行默认的操作;
  • 协调者在等待参与者响应超时后,允许执行默认的操作(发送中断事务)。

降低了事务资源的锁定范围

  • 新增了 CanCommit 阶段,不会像 2PC 一样一开始就锁定所有事务资源,而是排除掉个别不具备处理事务能力的参与者的前提下,再进入二阶段。

协商过程

img

区别于 2PC,只是在第一步先由协调者向所有参与者发送 CanCommit 请求,根据参与者的响应排除一些不具备事务处理能力的参与者,后续阶段和 2PC 相同。

3PC 相比 2PC 的优化

  • 增加了 CanCommit 阶段来减少事务资源的锁定范围,排除掉一些不具备事务资源能力的参与者;
  • 降低了同步阻塞,分别在参与者等待协调者请求、协调者在等待参与者响应 两个阶段新增超时机制。比如说参与者在等待协调者响应超时后默认执行提交操作,因为经过 CanCommit 阶段后事务成功提交的可能性已经很大了。

3PC 引入的问题

  • 新增一轮消息,增加了复杂度和协商效率;
  • 数据不一致:如果第二阶段结束后,一部分参与者能够执行事务反馈 Yes,另一部分参与者不能执行事务反馈 No,此时协调者恰好宕机,那么参与者会因为等待超时而自动执行默认操作,这就导致了部分事务成功提交、部分事务回滚,产生数据不一致的问题。

标签:事务,协调者,回滚,2pc,提交,3pc,参与者,分布式
From: https://www.cnblogs.com/istitches/p/18166082

相关文章

  • 搭建单机版伪分布式Hadoop+Scala+spark
    搭建单机版伪分布式Hadoop+Scala+spark修改ip[root@master~]#nmcliconnectionaddifnameens32con-nameens32autoconnectyesipv4.methodmanualipv4.gateway192.168.130.2ipv4.addresses192.168.130.102/24ipv4.dns114.114.114.114[root@master~]#nmcliconu......
  • Linux系统下jmeter 分布式压测环境部署
    使用jmeter做分布式压测时,需要一台主机master做控制,以及需要至少一台以上slave机器来做负载机。只需要在master,slave的jmeter.properties做简单的配置就可实现(jmeter版本及jdk版本最好一致,避免出现不必要的兼容问题)例如用19.13.198.236作为master控制机,19.13.198.238/237......
  • Go+seata实现分布式事务-tcc
    上篇用的ta跟xa。这次试试tccclientpackagemainimport( "context" "flag" "fmt" "net/http" "time" "github.com/parnurzeal/gorequest" "github.com/seata/seata-go/pkg/client" "github.......
  • Redis分布式锁
    Redis分布式锁如何实现?在Redis中提供了一个命令setnx(SETifnotexists)由于Redis的单线程的,用了命令之后,只能有一个客户端对某一个key设置值,在没有过期或删除key的时候是其他客户端是不能设置这个key的。如何控制Redis实现分布式锁有效时长呢?Redis的setnx指令不好控制这个......
  • Go+seata实现分布式事务
    docker安装seataversion:'3'services:seata-server:image:seataio/seata-server:latestports:-"8091:8091"-"7091:7091"environment:-SEATA_PORT=8091-STORE_MODE=filemysql:ima......
  • 分布式事务之dtm
    github: https://github.com/dtm-labs/dtm 本人使用场景,目前微服务中存在的用户服务,商品服务,订单服务,支付服务,在进行下单操作的时候,需要创建订单并扣减库存,这个时候就需要保证事务的一致性,但是对于目前的微服务架构来说就需要一套分布式的事务来实现,于是引入DT......
  • 分布式事务的实现方式
    分布式事务的5种实现方式XA方案TCc方案本地方法表可靠性消息最终一致性方案最大努力通知方案1.两阶段提交/XA方案所谓的XA方案,即:两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复ok,那......
  • go实现分布式锁
    用Go语言&&Redis实现分布式锁,我还是第一次磊丰 Go语言圈 2024-04-1508:30 广东 1人听过Go语言圈Go语言开发者的学习好助手,分享Go语言知识,技术技巧,学习与交流Go语言开发经验,互动才有助于技术的提升,每天5分钟,助你GO语言技术快乐成长158篇原创内容公众号......
  • 为什么使用分布式锁
    为什么使用分布式锁为了保证一个方法或属性在高并发情况下的同一时间只能被同一个线程执行分布式锁应该具备哪些条件?1.在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行2.高可用的获取锁和释放锁3.高性能的获取锁和释放锁4.具备可重入特性5.具备锁实效......
  • 多线程、分布式处理事务
    分布式事务涉及到多个独立的数据库系统或者多个独立的事务处理,它们需要在一个全局事务中协调一致。这种事务通常用于分布式系统或者微服务架构中,其中不同的服务可能使用不同的数据库。在Python中,实现分布式事务通常需要依赖特定的分布式事务管理器或者框架。例如,可以使用两阶段......