资讯详情

分布式事务与分布式系统

一. 概述

我们将"业务系统"数据库等业务系统是协调员"参与者"。在整个事务过程中,协调员将参与者 A 然而,参与者提交了事务 B 未能提交事务。此时,协调者需要参与者 A 需要回滚,然而回滚失败,协调者该如何去处理该异常场景。例如,向参与者提供协调者 B 参与者是否已提交或未提交事务;这是微服务中常见的分布式事务问题。

当数据量大幅增加,访问量大时,单机服务器往往无法有效提供服务;当服务器停机时,无法提供服务。此时,提出了这样一个分布式系统的概念。在《分布式系统概念与设计》一书中,分布式系统的定义如下:分布式系统是一个分布在不同网络计算机上的硬件或软件组件,只通过信息传输相互通信和协调的系统。基于分布式系统,衍生出分布式事务的专业术语。

二. CAP 理论

CAP 理论有三个特性

  • Consistency 数据一致性:副本中的数据一致性;
  • Availability 可用性:当某个节点停机时,其他节点仍然可以提供服务
  • Partition Tolerance 分区容错:当网络抖动时,节点之间的通信短时间中断。

三. Base 理论

基于无法满足 CAP 提出了最终的一致性解决方案。它放弃了短期的不可用性。 现在说的 paxos 算法以及 raft 算法都是基于这样子理论进行设计,这纯属个人理解 。

  • 基本可用(Basically Available)
  • 软状态(Soft State)
  • 最终一致性(Eventually Consistent)

四. 分布式事务

分布式事务的解决方案。

分布式事务涉及几个关键概念,X/Open 组织(即现在 Open Group )定义了分布式事务处理模型。 X/Open DTP 模型( 1994 )包括应用程序( AP )、事务管理器( TM )、资源管理器( RM )、通信资源管理器( CRM )四部分。一般来说,常见的事务管理器( TM )是一种常见的资源管理器,是中间件( RM )是通信资源管理器的常见数据库( CRM )是消息中间件。

1. 协议在两个阶段提交

两阶段提交协议分为两个阶段进行,第一阶段是预处理阶段,也就是发送 SQL 验证业务系统验证数据库返回的响应。第二阶段是提交阶段,即发送 commit 指令给数据库。

  • 第一阶段 预处理阶段:交易协调员(交易管理器)将其发送给每个参与者(资源管理器) Prepare 每个参与者要么直接返回失败 ,或者在当地执行事务,写本地 redo 和 undo 但不提交日志。预处理分为三个子步骤:
  • 协调节点询问所有参与者的节点是否可以提交操作(vote),并开始等待参与者节点的响应。
  • 参与者节点执行查询发起之前的所有事务操作,并将 Undo 信息和 Redo 将信息写入日志。(注:如果成功,每个参与者实际上都在这里执行事务操作)每个参与者的节点响应协调者节点发起的询问。如果参与者节点的事务操作实际成功执行,则返回同意信息;如果参与者节点的事务操作实际执行失败,则返回暂停信息。
  • 第二阶段 提交阶段:如果协调员收到参与者的失败或加班,直接将回滚发送给每个参与者(rollback)操作;否则发送提交(commit)新闻;参与者根据协调员的指示提交或回滚,释放所有事务处理过程中使用的定资源。

无论最终结果如何,当前事务都将在第二阶段结束。

两个阶段有以下缺点:

  • 同步阻塞问题 。在执行过程中,所有参与节点都是交易堵塞。在第一阶段,预处理将锁定相应的资源,并在第二阶段收到协调员发送的信息 commit 或者 rollback 消息释放锁资源后,协调员发送回滚操作释放锁资源。从锁定资源到释放资源的过程将阻止第三方节点访问锁定资源。
  • 单点故障 。由于协调者的重要性,一旦协调者出现故障,事务操作就无法继续完成。
  • 数据不一致 。当协调员在第二阶段发送时 commit 消息请求后,局部网络异常或发送 commit 协调员在请求过程中出现故障,部分参与者会收到 commit 其他参与者未收到消息并提交 commit 消息无法提交,整个事务数据不一致。
  • 第二阶段无法解决的问题 。再次发出协调者 commit 消息关闭后,唯一收到消息的参与者也关闭了。因此,即使协调员通过选举协议产生了新的协调员,事务的状态也不确定,也没有人知道事务是否已经提交。

很少用于工程,但有一定的参考性;

2. 三阶段提交协议

基于两个阶段的问题,提出了三个阶段的协议,主要的变化点:

  • 同时,协调员和参与者都引入了超时机制
  • 在第一阶段和第二阶段插入准备阶段。确保参与者在最终提交阶段前的状态一致。

提交协议分为三个阶段,CanCommit 阶段、PreCommit 阶段、DoCommit 阶段。

简单理解,在日常开发中很少使用;我们专注于理解 TCC 协议

3. TCC 事务协议

TCC 采用补偿机制,其核心思想是注册相应的确认和补偿(回滚)操作。它分为三个阶段:

  • Try 阶段:主要测试业务系统和预留资源
  • Confirm 阶段:主要是确认和提交业务系统,Try 成功实施阶段并开始实施 Confirm 阶段,默认 Confirm 阶段不会出错。也就是说, Try 成功,Confirm 一定会成功
  • Cancel 阶段:主要是在业务执行错误、需要回滚的情况下取消业务,释放预留资源。
  • 当其中一个子业务系统返回失败或超时时,事务将以失败处理 ,不到第二阶段。 然后需要向所有子业务系统发送回滚请求,使其子业务系统释放其资源 。 当发送回滚请求超时时,重复发送,以确保子业务系统的成功回滚 。在库存扣除方面,库存数量将被解冻。

补充:

  • 为避免重复发送消息,必须提供所有子业务系统 接口力等性原则 。
  • 为避免主业务系统停机,不了解事务的执行情况,需要提供记录事务执行状态的机制,在服务器提供服务或定期任务时定期处理事务后续行动,以确保 事务的完整性 。

问题:

  • 如何处理提交超时?

需要业务场景,是否需要回滚,还是继续提交。

  • 只要有一个子业务系统返回失败或超时,跳到 Cancel 阶段回滚后直接结束事务。如果回滚超时或失败,该怎么办?或者中途停机,该怎么办?

在业务系统中,需要记录事务的执行状态和子事务的执行状态;当发现加班或停机时,可以回复执行;

改善点:

在 Confirm 阶段、Cancel 是否需要异步执行阶段,可以有效地提供响应速度。

4. 尽量通知

请求确保通过异步或第三方组件向子业务系统发送消息。需要评估子业务必须成功执行的要求;否则子业务系统执行失败,主业务系统需要回滚,逻辑变得复杂;在什么情况下,将采用该机制?主要是在短信等必须成功执行的情况下;

4.1 本地消息表

将请求保存到本地数据库,并将请求推送到子业务系统。一般来说,设计重试 3 第二,当连续发送三次失败时,通知维人员跟进,具体原因是什么;如果涉及无限发送,业务系统压力过大;

4.2 半新闻/最终一致性

采用 MQ,redis 等待中间件,事务将要求推送子业务系统;前提是确保中间件是否支持事务操作。如果不支持,业务系统需要评估如何实现事务推送。例如 RocketMQ 在新闻中间,它支持事务操作,其原理是在业务系统中将新闻保存到临时队列中 commit 在操作过程中,消息从临时队列移出到目标队列。

五. 副本一致性

5.1 raft

算法中有三个角色,follower(跟随),candidate(候选人),Leader(领导者)

主要有两个环节,第一个环节是选举 Leader;第二环节是副本拷贝。

没有集群 Leader 时或者 Leader 宕机时, 有资格 的 follower 就会变为 candidate,接着会竞聘 Leader。谁先发起竞争,谁就有限当 Leader。至于谁先发送,它会给每个人 candidate 当时间到来时,设置一个随机时间尚未收到其他时间 candidate 如果有竞争请求,它将向每个人提出要求 candidate 发送竞争请求;超过一半,自动变成 Leader。

当客户端发送请求时,有 Leader 接收处理,广播给其他人 follower;当收到一半的回复成功时,可以确认请求处理成功。

5.2 paxos

5.2.1 目标

多节点之间的共识意味着大多数节点都接受提案。

5.2.2 角色

Proposer::提议者, 专门用于提案(一个值);当超过一半时,提案被选中。

Acceptor:接收人专门用于接收提案,判断是否通过提案;

Learner:习者,用来学习被选定的提案(个人理解,可有可无)。

5.2.3 basic-paxos

5.2.3.1 流程

其简单的流程图如下,这里不考虑异常,竞争下的场景;

在 prepare 阶段,Proposer 向 Acceptor 咨询自己是否有提议权(或者发表权)。一旦超过半数 Acceptor 回复 OK,则进入 accept 第二阶段。Proposer 发发送 accept 请求,超过 Acceptor 半数回复 OK。则结束这次提议。至于 Learner 通过谁去学习这个【proposal-value】,

  1. Acceptor 接收 prepare 请求的逻辑

如果 Acceptor 没有批准过提议权的,则无保留意见批准,并记录该 minProposal =【proposal-id】。

如果 Acceptor 之前已经批准过提议权 minProposal ,会与现在收到的提议权携带的【proposal-id】进行比较。 minProposal >=proposal-id,则拒绝该提议权;如果 minProposal <proposal-id,则批准该提议权,并记录该 minProposal =【proposal-id】。并将 Acceptor 自身的【proposal-value】以及【 minProposal 】发给 Proposer。这里留下一个提问, Acceptor 会返回不同的【 proposal-value 】麽?

  1. Proposer 处理 prepare 请求的响应的逻辑

prepare 响应中如果有【proposal-value】A,则设置 Proposer 的【proposal-value】为 A,否则自行做决定该值。

如果超过半数回复同意的,则进入第二阶段去发表意见。

否则重新发起提议,发送 prepare 消息获取提议权。

  1. Proposer 发送 accept 请求的逻辑

将【proposal-id】与【proposal-value】发送给 Acceptor。

  1. Acceptor 接收 accept 请求的逻辑

如果 Acceptor 当前的【proposal-ID】A 与这次 accept 请求中的【提议 ID】B 相比较,如果不相等,则回复【NO】。否则设置 Acceptor 的【proposal-value】的值为 accept 请求中的【proposal-value】,并回复【OK】响应。

  1. Proposer 接收 accept 请求的响应的处理逻辑

如果超过半数回复 OK 的,则不用管理其他回复【NO】响应,把该【proposal-value】发送给 Learner 进行学习。否则重新发送 prepare 消息,再进行一次提议;最终【proposal-value】是一致的。

5.2.3.2 深入探讨

  1. Acceptor 是否会存在多个不同的【proposal-value】?

答案:是不会存在多个不同【proposal-value】。因为在 prepare 阶段,如果 Acceptor 已经有【proposal-value】值,Proposal 会拿这个值在 accept 阶段进行发送;如果没有的话,Proposal 会自行生成一个【proposal-value】值到 accept 阶段进行发送;同时在 accpet 阶段,如果 Acceptor 会去校验【proposal-id】是否相同,相同则设置该【proposal-value】值。有点类似 乐观锁 的机制。

  1. 如果 Acceptor 小部分宕机,或者 Proposal 在提议过程中发生了宕机,会不会出现【proposal-value】不一致?

答案:不会。因为该协议是只要超过半数的 Acceptor 在运转,依然可以提供服务。而 Proposal 宕机,Proposal 重启进行下一轮提议或者交由其他 Proposer 提议,最终【proposal-value】是达成一致。

  1. 并发性问题,性能低效,以及容易出现活锁问题

在多个 Proposal 进行提议时,容易对【proposal-id】进行竞争,导致性能低效,极端情况下,出现活锁现象。以及为了达成共识,需要先 prepare 阶段以及 accept 阶段,会有损耗,也是导致性能低效的原因之一。

5.2.4 multi-paxos

这个就是基于 basic-paxos 中暴露的问题,提供出来的解决方案。

  • 添加一个 leader 角色,所有的提议都由 Leader 角色来发起,这样子有效的避免竞争带来的性能低效以及活锁现象。 但是从而导致 Leader 角色的服务压力过大 。
  • 有效的减少 Prepare 阶段,在满足特定的场景,Leader 可以直接跳过 prepare 阶段,直接到 accept 阶段,减少交互次数,可以有效的减少性能低效问题。

问题,

  1. 什么场景下,可以直接跳过 prepare 阶段?

只有当 Acceptor 自身发现只接收到一个 Leader 的请求时,就会告知 Leader,让其跳过 prepare 阶段;

  1. Leader 是如何选举出来的?

兰伯特博士提出比较简单的方式,就是哪个 server 的 ID 最大,谁就是最大。也可以采用 Raft 机制,谁先发起竞聘,谁就是 Leader。

  1. 出现网络分区,该怎么处理?

兰伯特博士提出一个 并发数 参数来 短时间 避免网络分区问题,当网络分区现象发生时,超过多少笔请求接收完后,网络分区才真正会出现;例如,有 9 个节点,当网络分区发生时,6 个节点互通,而另外 3 个节点互通。当请求过来时,切好落在 3 节点区域,这时该请求是无法通过的,因为当前节点数是 9,需要过半数才能通过;当请求数超过指定的并发数时,该 3 个节点才真正的形成集群,只要超过 2 个节点的通过,即可接收该请求。

5.2.5 总结

有关更多细节讲解的 paxos 文章,可以仔细查阅我引用的文章。

简单写了 paxos 的算法逻辑其目标是解决一致性问题,但还是不知道, 一致性是指数据的一致性呢,还是状态的一致性 ?如果是数据的一致性,那么并发情况下,所有的请求都会到 server 都会变成串行执行,性能肯定是不高;如果说状态的一致性,就说得通,只要各个 server 的状态是一致的,那么表明各个 server 下的数据就是一致的;至于在分布式系统如何使用 paxos 算法,还需要结合请求进行设计流程。 这只是我的理解,纯属参考 。

六. 分布式系统

我们所说的分布式系统,主要是解决计算、存储数据量的问题。无论是计算还是存储,其归根于如何拆分数据,让其数据均匀的分布在各个节点上;

  • 哈希方式 通过哈希算法将数据分布到不同的机器上
  • 按数据范围分布 有点类似与报表系统对数据量大的表按时间维度分区
  • 一致性哈希 结合哈希方式,采用环形的形式,将数据分布到各个节点上;其中提出了虚拟节点的方法,有效的避免数据不均匀的问题。

同时分布式系统也需要高可用,所以需要多副本,从而避免服务宕机,其他副本服务依然提供服务;至于如何保证副本一致性,可以看上面的讲解。

七. 总结

分布式事务,我们主要是采用 TCC 协议,保证事务的一致性;当个别场景可以采用第三方组件,从而减少服务的压力;

标签: 压力变送器tm21

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台