03丨分布式互斥:有你没我,有我没你

  • Q:分布式互斥(Distributed Mutual Exclusion)是什么?临界资源(Critical Resource)是什么?
    • 在分布式系统里要求同一时刻只能有一个程序能够访问一个共享资源,这种排他式的资源访问方式叫分布式互斥,这种被互斥访问的共享资源叫临界资源
  • Q:有哪3种分布式互斥方法?
    • 1.集中式方法
    • 2.分布式方法
    • 3.令牌环方法
  • Q:中央服务器算法或集中式算法是什么?
    • 每个程序在需要访问临界资源时,先给协调者发送一个请求。如果当前没有程序使用这个资源,协调者直接授权请求程序访问;否则,按照先来后到的顺序为请求程序排一个号。如果有程序使用完资源,则通知协调者,协调者从“排号”的队列里取出排在最前面的请求,并给它发送授权信息。拿到授权消息的程序,可以直接去访问临界资源
  • Q:集中式算法中每个程序完成一次临界资源访问需要进行哪3次消息交互?
    • 1.向协调者发送请求授权
    • 2.协调者向程序发放授权信息
    • 3.程序使用完临界资源后,向协调者发送授权
  • Q:集中式算法的优缺点和适用场景是什么?
    • 优点:直观、简单、信息交互量少、易于实现,并且所有程序只需和协调者通信,程序之间无需通信
    • 缺点:
    • 1.协调者会成为系统的性能瓶颈。即协调者处理的消息数量会随着需要访问临界资源的程序数量线性增加
    • 2.容易引发单点故障。若协调者故障会导致所有的程序均无法访问临界资源,导致整个系统不可用
    • 适用场景:
    • 在可靠性和性能有一定的保障时,如中央服务器计算能力强、性能高、故障率低,或者中央服务器进行了主备备份,主故障后背可以立马升为主,且数据可恢复的情况下可用集中式算法
  • Q:分布式算法或使用组播和逻辑时钟的算法是什么?
    • 当一个程序要访问临界资源时,先向系统中的其它程序发送一条请求消息,在接收到所有程序返回的同意消息后,才可以访问临界资源。其中,请求消息需要包含所请求的资源、请求者ID,以及发起请求的时间
    • 即根据“先到先得”和“投票全票通过”机制,让每个程序按时间顺序公平地访问资源
    • 适合节点数目少且变动不频繁的系统,且由于每个程序均需通信交互,因此适合P2P结构的系统
  • Q:分布式算法中,一个程序完成一次临界资源访问需要的消息交互:
    • 1.向其它n-1个程序发送临界资源的请求
    • 2.需要接收到其它n-1个程序回复的同意消息
    • 总共2*(n-1),在大型系统中使用分布式算法,消息数量会随着需要访问临界资源数量呈指数级增加
  • Q:分布式算法的可用性很低的两个原因是什么?有没有改进办法?
    • 1.当系统内需要访问临界资源的程序增多时,容易产生“信令风暴”,即程序收到的请求完全超过了自己的处理能力,而导致自己的正常业务无法开展
    • 2.一旦某一程序发生故障,无法发送同意消息,那么其它程序均处于等待回复的状态中,使得整个系统处于停滞状态,导致整个系统不可用
    • 改进方法:检测到一个程序故障,直接忽略这个程序,无需等待它的同意消息。但缺点是每个程序需要对其它程序进行故障检测会带来更大的复杂性
  • Q:HDFS的文件修改过程是怎样的?
    • 1.计算机1向计算机2、3发送文件修改请求
    • 2.计算机2、3发现自己不需要使用资源,因此同意计算机1的请求
    • 3.计算机1收到其它所有计算机的同意消息后,开始修改该文件
    • 4.计算机1修改完成后,向计算机2、3发送文件修改完成的消息,并发送修改后的文件数据
    • 5.计算机2和3收到计算机1的新文件数据后,更新本地的备份文件
  • Q:令牌环算法或基于环的算法是怎样的?
    • 所有程序构成一个环结构,令牌按照顺时针(或逆时针)方向在程序之间传递,收到令牌的程序有权访问临界资源,访问完成后将令牌传送到下一个程序;若该程序不需要访问临界资源,则直接把令牌传送给下一个程序
  • Q:令牌环方法的优缺点和适用场景是什么?
    • 优点:
    • 1.单个参与者通信效率较高
    • 2.可用性较高
    • 缺点:
    • 当参与者对临界资源适用频率较低时,会带来较多无用通信
    • 适用场景:系统规模较小,并且系统中每个程序使用共享资源频度较高且使用时间较短的场景

04 | 分布式选举:国不可一日无君

  • Q:为什么要有分布式选举?
    • 主节点在一个分布式集群中负责对其它节点的协调和管理,它的存在可以保证其它节点的有序运行,以及数据库集群中的写入数据在每个节点上的一致性。(一致性是指,数据在每个集群节点中都是一样的,不存在不同的情况)
  • Q:Bully算法的选举原则和假设条件是什么?
    • 选举原则:“长者为大”,在所有活着的节点中,选取ID最大的节点作为主节点
    • 假设条件:集群中每个节点均知道其它节点的ID
  • Q:Bully算法中节点有哪两种角色?初始角色和变化过程是怎样的?
    • 普通节点和主节点
    • 初始化时,所有节点都是平等的,都是普通节点,并且都有成为主节点的权利
    • 当选主成功后,有且仅有一个节点成为主节点,其它节点都是普通节点。当且仅当主节点故障或与其它节点失去联系后,才会重新选主
  • Q:Bully算法选举过程中用到的3种消息是哪些?
    • Election消息:用于发起选举
    • Alive消息:对Election消息的应答
    • Victory消息:竞选成功的主节点向其它节点发送的宣誓主权的消息
  • Q:Bully算法的选举过程是怎样?
    • 1.集群中每个节点判断自己的ID是否为当前活着的节点中ID最大的,如果是,则直接向其它节点发送Victory消息,宣誓自己的主权
    • 2.如果自己不是当前活着的节点中ID最大的,则向比自己大的所有节点发送Election消息,并等待其它节点的回复
    • 3.若在给定的时间范围内,本节点没有收到其它节点回复的Alive消息,则认为自己成为主节点,并向其它节点发送Victory消息,宣誓自己成为主节点;若接收到来自比自己ID打的节点的Alive消息,则等待其它节点发送Victory消息
    • 4.若本节点收到比自己ID小的节点发送的Election消息,则回复一个Alive消息,告知其它节点,我比你大,重新选举
  • Q:Bully算法的优缺点是什么?
    • 优点:选举速度快、算法复杂度低、简单易实现
    • 缺点:
    • 1.需要每个节点有全局的节点信息,因此额外信息存储较多
    • 2.任意一个比当前主节点ID大的新节点或节点故障后恢复加入集群的时候,都可能会触发重新选举,成为新的主节点,如果该节点频繁退出、加入集群,就会导致频繁切主
  • Q:Bully算法的应用例子?
    • MongoDB的副本集故障转移功能:采用最后操作时间戳来表示ID,时间戳最新的节点其ID,时间戳最新的节点ID最大,即时间戳最新的、活着的节点是主节点
  • Q:Raft算法选举时,集群节点的角色有哪3种?
    • Leader:主节点,同一时刻只有一个Leader,负责协调和管理其它节点
    • Candidate:候选者,每一个节点都可以成为Candidate,节点在该角色下才可以被选为新的Leader
    • Follower:Leader的跟随者,不可以发起选举
  • Q:Raft选举的流程是怎样?
    • 1.初始化时,所有节点均为Follower状态
    • 2.开始选主时,所有节点的状态由Follower转化为Candidate,并向其它节点发送选举请求
    • 3.其它节点根据接收到的选举请求的先后顺序,回复是否同意成为主。注意这里的每一轮选举中,一个节点只能投出一张票
    • 4.若发起选举请求的节点获得超过一半的投票,则成为主节点,其状态转化为Leader,其它节点的状态则由Candidate降为Follower。Leader节点与Follower节点之间会定期发送心跳包,以检测主节点是否活着
    • 5.当Leader节点的任期到了,即发现其它服务器开始下一轮选主周期时,Leader节点的状态由Leader降级为Follower,进入新一轮选主
  • Q:Raft算法的应用例子?
    • Google 开源的 Kubernetes,擅长容器管理与调度,为了保证可靠性,通常会部署 3 个节点用于数据备份。这 3 个节点中,有一个会被选为主,其他节点作为备。Kubernetes 的选主采用的是开源的 etcd 组件。而,etcd 的集群管理器 etcds,是一个高可用、强一致性的服务发现存储仓库,就是采用了 Raft 算法来实现选主和一致性的
  • Q:Raft算法的优缺点是什么?
    • 优点:
      • 1.选举速度快、算法复杂度低、易于实现
      • 2.选举稳定性比Bully算法好,因为当有新节点加入或节点故障恢复后,会触发选主,但不一定会真正切主,除非新节点或故障后恢复的节点获得投票数过半,才会导致切主
    • 缺点:要求系统内每个节点都可以相互通信,且需要获得过半的投票数才能选主成功,因此通信量大
  • Q:ZAB算法选举时,集群有哪3种角色?
    • Leader: 主节点
    • Follower: 跟随者节点
    • Observer: 观察者,无投票权
  • Q:ZAB算法选举过程中,集群中的节点拥有哪4个状态?
    • Looking(选举)状态:当节点处于该状态时,它会认为当前集群中没有Leader,因此自己进入选举状态
    • Leading(领导者)状态:表示已经选出主,且当前节点为Leader
    • Following(跟随者)状态:集群中已经选出主后,其它非主节点状态更新为Following,表示对Leader的追随
    • Observing(观察者)状态:表示当前节点为Observer,持观望态度,没有投票权和选举权
  • Q:ZAB算法的节点的数据结构三元组(server_id, server_zxID, epoch)分别是什么意思?
    • server_id: 本节点的唯一ID
    • server_zxID: 本节点存放的数据ID,数据ID越大表示数据越新,选举权重越大
    • epoch: 当前选取轮数,一般用逻辑时钟表示
  • Q:ZAB算法的选举过程的数据结构(vote_id, vote_zxID)分别是什么意思?
    • vote_id: 被投票节点的ID
    • vote_zxID: 被投票节点的服务器zxID
  • Q:ZAB算法的核心和选主原则是什么?
    • 核心:少数服从多数,ID大的节点优先成为主
    • 选主原则:server_zxID最大者成为Leader, 若server_zxID相同,则server_id最大者成为Leader
  • Q:ZAB算法的选举过程是怎样?
    • 1.当系统刚启动时,3个服务器当前投票均为第一轮投票,即epoch=1, 且zxID均为0。此时每个服务器都推选自己,并将选票信息<epoch, vote_id, vote_zxID>广播出去
    • 2.根据判断规则,由于3个Server的epoch、zxID都相同,因此比较server_id,较大者即为推选对象,因此Server1和Server2将vote_id改为3,更新自己的投票箱并重新广播自己的投票
    • 3.此时系统内所有服务器都推选了Server3,因此Server3当选Leader,处于Leading状态,向其它服务器发送心跳包并维护连接;Server1和2处于Following状态
  • Q:ZAB算法的优缺点是什么?
    • 优点:
      • 1.性能高,对系统无特殊要求
      • 2.选举稳定性比较好,当有新节点加入或节点故障恢复后,会触发选主,但不一定会真正切主,除非新节点或故障后恢复的节点数据 ID 和节点 ID 最大,且获得投票数过半,才会导致切主
    • 缺点:
      • 1.采用广播方式发送信息,若节点中有n个节点,每个节点同时广播,则集群中信息量为n*(n-1)个消息,容易出现广播风暴
      • 2.除了投票,还增加了对比节点ID和数据ID,这就意味着还需要知道所有节点ID和数据ID,所以选举时间相对较长
  • Q:Bully、Raft、ZAB算法对比图?

05 | 分布式共识:存异求同

  • Q:分布式选举问题的本质是什么?
    • 传统的分布式共识方法,主要是基于多数投票策略实现的
  • Q:什么是分布式共识?
    • 在多个节点均可独自操作或记录的情况下,使得所有节点针对某个状态达成一致的过程
    • 本质是“求同存异”
  • Q:分布式共识的两个关键点是什么?
    • 1.获得记账权
    • 2.所有节点或服务器达成一致
  • Q:区块链是什么?
    • 由包含交易信息的区块从后向前有序链接起来的数据结构
    • 其中区块是指很多交易数据的集合,每个区块包括区块头和区块体
      • 区块体包括前一区块的哈希值、本区块的哈希值和时间戳
      • 区块体用来存储交易数据
  • Q:有哪3种解决分布式在线记账一致性问题的共识技术?
    • PoW: Proof-of-Work, 工作量证明
    • PoS: Proof-of-Stake, 权益证明
    • DPoS: Delegated Proof of Stake, 委托权益证明
  • Q:PoW算法是什么?
    • 以每个节点或服务器的计算能力来竞争记账权的机制,即使用工作量证明机制的共识算法
  • Q:假设每个节点会划分多个区块用于记录用户交易,PoW算法获取记账权的原理是什么?
    • 利用区块的index、前一区块的哈希值、交易的时间戳、区块数据和nonce值,通过SHA256计算出一个哈希值
    • 判断前k个值是否都为0
      • 如果不是,递增nonce值,重新按照上述方法计算
      • 如果是,本次计算的哈希值为要解决的题目的正确答案
    • 谁最先计算出正确答案,谁就获得这个区块的记账权
    • 注:nonce值是用来找到一个满足哈希值的数字;k 为哈希值前导零的个数,标记了 计算的难度,0 越多计算难度越大
  • Q:达成共识的过程,其本质是?
    • 即获得记账权的节点将该区块信息广播给其它节点,其它节点判断该结点找到的区块中的所有交易都是有效且之前未存在过的,则认为该区块有效,并接受该区块
  • Q:基于PoW的共识记账过程是怎样的?(以分散在世界各地的 5 台服务器为例,假设客户端A产生一个新的交易)
    • 1.客户端A产生新的交易,向全网进行广播,要求对交易进行记账
    • 2.每个记账节点接收到这个请求后,将受到的交易信息放入一个区块中
    • 3.每个节点通过PoW算法,计算本节点的区块的哈希值,尝试找到一个具有足够工作量难度的工作量证明
    • 4.若节点D找到了一个工作量证明向全网广播。当且仅当包含在该区块中的交易都是有效且之前未存在过的,其它节点才会认同该区块的有效性
    • 5.其它节点接收到广播信息后,若该区块有效,接受该区块,并跟随在该区块的末尾,制造新区块延长该链条,将被接受的区块的随机哈希值视为新区块的随机哈希值
    • 核心:谁的计算能力强,获得记账权的可能性就越大。但必须保证其记 账的区块是有效的,并在之前未存在过,才能获得其他节点的认可
  • Q:PoW机制的优缺点?
    • 优点:实现了相对的公平。PoW 的容错机制允许全网 50% 的节点出错,如果要破坏系统,则需要投入极大成本(若你有全球 51% 的算力,则可尝试攻击比特币)
    • 缺点:共识达成的周期长、效率低,资源消耗大。每次达成共识需要全网共同参与运算,增加了每个节点的计算量。如果题目过难,会导致计算时间长、资源消耗多;而如果题目过于简单,会导致大量节点同时获得记账权,冲突多。这些问题,都会增加达成共识的时间
  • Q:PoS算法的核心原理?
    • 由系统权益代替算力来决定区块记账权,拥有的权益越大获得记账权的概率就越大
    • 权益,即每个节点占有货币的数量和时间,而货币就是节点所获得的奖励
  • Q:基于 PoS 算法获得区块记账权的方法相比基于 PoW 的方法的不同之处是?
    • PoS是根据结点拥有的股权或权益进行计算的
  • Q:通过 PoS 算法决定区块记账权的流程和 PoW 算法的唯一不同的是?
    • 每个节点在计算自己记账权的时候,通过计算自己的股权或权益来评估,如果发现自己权益最大,则将自己的区块广播给其它节点,当然必须保证该区块的有效性
  • Q:PoS算法的优缺点?
    • 优点
      • 1.将算力竞争转变成权益竞争。与 PoW 相比,PoS 不需要消耗大量的电力就能够保证区块链网络的安全性
      • 2.不需要在每个区块中创建新的货币来激励记账者参与当前网络的运行,这也就在一定程度上缩短了达成共识所需要的时间
    • 缺点
      • PoS 算法中持币越多或持币越久,币龄就会越高,持币人就越容易挖到区块并得到激 励,而持币少的人基本没有机会
      • 整个系统的安全性实际上会被持币数量较大的一部分 人掌握,容易出现垄断现象
  • Q:DPoS(委托权益证明法)是什么?
    • 由被社区选举的可信账户(受托人,比如得票数排行前 101 位)来拥有记账权
    • 为了成为正式受托人,用户要去社区拉票,获得足够多的信任。用户根据自己持有的货币数量占总量的百分比来投票
    • 根据自己拥有的权益,投票选出可代表自己的受托节点,受托节点之间竞争记账权
    • 通常会选出k(如101)个受托结点,它们的权利是完全相等的。受托节点之间争取记账权也是根据算力进行竞争的。只要受托节点提供的算力不稳定,计算机宕机或者利用手中的权力作恶,随时可以被握着货币的普通节点投票踢出整个系统,而后备的受托节点可以随时顶上去
  • Q:DPos的优缺点是什么?
    • 优点
      • 1.由投票选举出的若干信誉度更高的受托人记账,解决了所有节点均参与竞争导致消息量大、达成一致的周期长的问题。DPoS 能耗更低,具有更快的交易速度
      • 2.每隔一定周期会调整受托人,避免受托人造假和独权
    • 缺点
      • 1.由于大多数持币人通过受托人参与投票,投票的积极性并不高
      • 2.一旦出现故障节点,DPoS 无法及时做出应对,导致安全隐患
  • Q:PoW、PoS和DPoS三种共识算法的对比图
  • Q:一致性和共识的区别是什么?
    • 一致性:分布式系统中的多个节点之间,给定一系列的操作,在约定协议的保障下,对外界呈现的数据或状态时一致的
    • 共识:分布式系统中多个节点之间,彼此对某个状态达成一致结果的过程
    • 一致性强调结果,共识强调达成一致的过程,共识算法是保障系统满足不同程度一致性的核心技术

06 | 分布式事务:All or nothing

  • Q:事务和分布式事务是什么?
    • 事务:包含一系列操作的、一个有边界的工作序列,有明确的开始和结束标志,且要么被完全执行,要么完全失败,通常指本地(或单机)事务
    • 分布式事务:在分布式系统中运行的事务,由多个本地事务组合而成
  • Q:分布式事务基本特征ACID是什么?
    • 原子性(Atomicity):事务的最终状态只有两种,全部执行成功和全部不执行。若处理事务的任何一项操作不成功,就会导致整个事务失败。一旦操作失败,所有操作都会被取消(回滚)
    • 一致性(Consistency):事务操作前和操作后,数据的完整性保持一致或满足完整性约束
    • 隔离性(Isolation):当系统内多个事务并发执行时,多个事务不会相互干扰,即一个事务内部的操作及使用的数据,对其它并发事务是隔离的
    • 持久性(Durability):一个事务完成了,那么它对数据库所做的更新就被永久保存下来了。即使发生系统崩溃或宕机等故障,只要数据库能够被重新访问,那么一定能够将其恢复到事务完成时的状态
  • Q:刚性事务和柔性事务是什么?
    • 刚性事务:遵循ACID原则,具有强一致性。如数据库事务
    • 柔性事务:根据不同的业务场景使用不同的方法实现最终一致性。即可根据业务的特性做部分取舍,容忍一定时间内的数据不一致,遵循BASE理论
  • Q:BASE理论是什么?
    • 基本可用(Basically Available):分布式系统出现故障的时候,允许损失一部分功能的可用性
    • 柔性状态(Soft State):在柔性事务中,允许系统存在中间状态,且这个中间状态不会影响系统整体可用性。如数据库读写分离,写库(主库)同步到读库(从库)会有一个延时,就是柔性状态
    • 最终一致性(Eventual Consistency):事务在操作过程中可能由于同步延迟导致不一致,但最终状态下,数据都是一致的
    • BASE理论为了支持大型分布式系统,通过牺牲强一致性,保证最终一致性,来获得高可用性
  • Q:分布式事务主要解决的问题,以及实现方法有哪3种?
    • 主要解决:在分布式环境下,组合事务的一致性问题
    • 方法:
    • 1.基于XA协议的二阶段提交协议方法(强一致性,遵从ACID)
    • 2.三阶段提交协议方法(强一致性,遵从ACID)
    • 3.基于消息的最终一致性方法(最终一致性,遵从BASE理论)
  • Q:XA组成有什么?
    • 事务管理器(协调者):负责各个本地资源的提交和回滚
    • 资源管理器(参与者):通常由数据库实现
  • Q:两阶段提交协议如何保证分布在不同节点上的分布式事务的一致性呢?
    • 引入一个协调者来管理所有的节点,并确保这些节点正确提交操作结果,若提交失败则放弃事务
  • Q:两阶段提交协议的执行过程
    • 第一阶段:投票(voting)
      • 协调者(Coordinator,即事务管理器)会向事务的参与者(Cohort,即本地资源管理器)发起执行操作的CanCommit请求,并等待参与者的响应。参与者接收到请求后,会执行请求中的事务操作,记录日志信息但不提交,待参与者执行成功,则向协调者发送「Yes」消息,表示同意操作;若不成功,则发送「No」消息,表示终止操作
    • 第二阶段:提交(commit)
      • 当所有的参与者都返回了操作结果(Yes 或 No 消息)后,系统进入了提交阶段。在提交阶段,协调者会根据所有参与者返回的信息向参与者发送 DoCommit 或 DoAbort 指令:
        • 若协调者收到的都是「Yes」消息,则向参与者发送「DoCommit」消息,参与者会完成剩余的操作并释放资源,然后向协调者返回「HaveCommitted」消息
        • 如果协调者收到的消息中包含「No」消息,则向所有参与者发送「DoAbort」消息,此时发送「Yes」的参与者则会根据之前执行操作时的回滚日志对操作进行回滚,然后所有参与者会向协调者发送「HaveCommitted」消息
        • 协调者接收到「HaveCommitted」消息,就意味着整个事务结束了
  • Q:二阶段提交的算法思路概要
    • 协调者下发请求事务操作,参与者将操作结果通知协调者,协调者根据所有参与者的反馈结果决定各参与者是要提交操作还 是撤销操作
  • Q:基于 XA 的二阶段提交算法的不足
    • 同步阻塞问题:二阶段提交算法在执行过程中,所有参与节点都是事务阻塞型的。也就是说,当本地资源管理器占有临界资源时,其他资源管理器如果要访问同一临界资源,会处于阻塞状态
    • 单点故障问题:基于 XA 的二阶段提交算法类似于集中式算法,一旦事务管理器发生故障,整个系统都处于停滞状态。尤其是在提交阶段,一旦事务管理器发生故障,资源管理器会由于等待管理器的消息,而一直锁定事务资源,导致整个系统被阻塞
    • 数据不一致问题:在提交阶段,当协调者向参与者发送 DoCommit 请求之后,如果发生了局部网络异常,或者在发送提交请求的过程中协调者发生了故障,就会导致只有一部分参与者接收到了提交请求并执行提交操作,但其他未接到提交请求的那部分参与者则无法执行事务提交。于是整个分布式系统便出现了数据不一致的问题
  • Q:三阶段提交协议(Three-phase commit protocol,3PC)相对二阶段提交(2PC)的改进是什么
    • 为了解决两阶段提交的同步阻塞和数据不一致问题,三阶段提交引入了超时机制和准备阶段
    • 同时在协调者和参与者中引入超时机制。如果协调者或参与者在规定的时间内没有接收到来自其他节点的响应,就会根据当前的状态选择提交或者终止整个事务
    • 在第一阶段和第二阶段中间引入了一个准备阶段,也就是在提交阶段之前,加入了一个预提交阶段。在预提交阶段排除一些不一致的情况,保证在最后提交之前各参与节点的状态是一致的
  • Q:三阶段提交协议的详细过程
    • 1.CanCommit阶段
      • 协调者向参与者发送请求操作(CanCommit请求),询问参与者是否可以执行事务提交操作,然后等待参与者的响应;参与者收到 CanCommit 请求之后,回复 Yes,表示可以顺利执行事务;否则回复 No
      • CanCommit 阶段不同节点之间的事务请求成功和失败的流程,如图
    • 2.PreCommit阶段
      • 协调者根据参与者的回复情况,来决定是否可以进行 PreCommit 操作
        • 如果所有参与者回复的都是“Yes”,那么协调者就会执行事务的预执行:
          • 发送预提交请求:协调者向参与者发送 PreCommit 请求,进入预提交阶段
          • 事务预提交:参与者接收到 PreCommit 请求后执行事务操作,并将 Undo 和 Redo 信息记录到事务日志中
          • 响应反馈:如果参与者成功执行了事务操作,则返回 ACK 响应,同时开始等待最终指令
        • 假如任何一个参与者向协调者发送了“No”消息,或者等待超时之后,协调者都没有收到参与者的响应,就执行中断事务的操作:
          • 发送中断请求:协调者向所有参与者发送“Abort”消息
          • 终断事务:参与者收到“Abort”消息之后,或超时后仍未收到协调者的消息,执行事务的终断操作
      • 预执行阶段,不同节点上事务执行成功和失败的流程,如图
    • 3.DoCommit阶段
      • DoCmmit 阶段进行真正的事务提交,根据 PreCommit 阶段协调者发送的消息,进入执行提交阶段或事务中断阶段
      • 执行提交阶段:
        • 发送提交请求:协调者接收到所有参与者发送的 Ack 响应,从预提交状态进入到提交状态,并向所有参与者发送 DoCommit 消息
        • 事务提交:参与者接收到 DoCommit 消息之后,正式提交事务。完成事务提交之后,释放所有锁住的资源。
        • 响应反馈:参与者提交完事务之后,向协调者发送 Ack 响应
        • 完成事务:协调者接收到所有参与者的 Ack 响应之后,完成事务
      • 事务中断阶段:
        • 发送中断请求:协调者向所有参与者发送 Abort 请求
        • 事务回滚:参与者接收到 Abort 消息之后,利用其在 PreCommit 阶段记录的 Undo 信息执行事务的回滚操作,并释放所有锁住的资源
        • 反馈结果:参与者完成事务回滚之后,向协调者发送 Ack 消息
        • 终断事务:协调者接收到参与者反馈的 Ack 消息之后,执行事务的终断,并结束事务
      • 执行阶段不同节点上事务执行成功和失败 (事务终断) 的流程,如图
  • Q:2PC 和 3PC 这两种方法的两个共同的缺点是什么
    • 1.都需要锁定资源,降低系统性能
    • 2.没有解决数据不一致的问题
  • Q:基于分布式消息的最终一致性方案的核心思想是什么
    • 将需要分布式处理的事务通过消息或者日志的方式异步执行,消息或日志可以存到本地文件、数据库或消息队列中,再通过业务规则进行失败重试
    • 基于分布式消息的最终一致性方案的事务处理,引入了一个消息中间件(Message Queue,MQ),用于在多个应用之间进行消息传递
  • Q:以网上购物为例,阐述分布式消息的最终一致性方案的事务处理
    • 假设用户 A 在某电商平台下了一个订单,需要支付 50 元,发现自己的账户余额共 150 元,就使用余额支付,支付成功之后,订单状态修改为支付成功,然后通知仓库发货
    • 在该事件中,涉及到了订单系统、支付系统、仓库系统,这三个系统是相互独立的应用,通过远程服务进行调用
    • 整个购物流程如下
      1. 订单系统把订单消息发给消息中间件,消息状态标记为“待确认”
      1. 消息中间件收到消息后,进行消息持久化操作,即在消息存储系统中新增一条状态为“待发送”的消息
      1. 消息中间件返回消息持久化结果(成功 / 失败),订单系统根据返回结果判断如何进行业务操作。失败,放弃订单,结束(必要时向上层返回失败结果);成功,则创建订单
      1. 订单操作完成后,把操作结果(成功 / 失败)发送给消息中间件
      1. 消息中间件收到业务操作结果后,根据结果进行处理:失败,删除消息存储中的消息,结束;成功,则更新消息存储中的消息状态为“待发送(可发送)”,并执行消息投递
      1. 如果消息状态为“可发送”,则 MQ 会将消息发送给支付系统,表示已经创建好订单,需要对订单进行支付。支付系统也按照上述方式进行订单支付操作
      1. 订单系统支付完成后,会将支付消息返回给消息中间件,中间件将消息传送给订单系统。订单系统再调用库存系统,进行出货操作
  • Q:三种分布式事务的实现方式对比图
  • Q:刚性事务和柔性事务是什么?
    • 刚性事务,遵循 ACID 原则,具有强一致性。比如,数据库事务
    • 柔性事务,其实就是根据不同的业务场景使用不同的方法实现最终一致性,即可根据业务的特性做部分取舍,容忍一定时间内的数据不一致
  • Q:BASE理论是什么?
    • 基本可用(Basically Available):分布式系统出现故障的时候,允许损失一部分功能的可用性
    • 柔性状态(Soft State):在柔性事务中,允许系统存在中间状态,且这个中间状态不会影响系统整体可用性。比如,数据库读写分离,写库同步到读库(主库同步到从库)会有一个延时,其实就是一种柔性状态
    • 最终一致性 (Eventual Consistency):事务在操作过程中可能会由于同步延迟等问题导致不一致,但最终状态下,数据都是一致的
    • BASE 理论为了支持大型分布式系统,通过牺牲强一致性,保证最终一致性,来获得高可用性,是对 ACID 原则的弱化
Last Updated:
Contributors: Shiqi Lu