java基础巩固-宇宙第一AiYWM:为了维持生计,架构知识+分布式微服务+高并发高可用高性能知识序幕就此拉开(七:分布式解决方案【分布式事务、分布式锁...2PC、3PC、Paxos】)~整起

  • 搞了【垂直扩展集群,再拆分模块为微服务后】分布式集群后,传统的一些技术会失败
    • 比如传统的synchronized或者lock锁
    • 创建数据库的事务,多台主机的自增id怎么保证唯一,要不要保证id连续
      • 无法保证ACID,还有定时任务也可能会出现重复执行的问题
    • 故分布式解决方案应运而生。引入了分布式和集群之后咱们就要考虑解决分布式带来的一系列问题。比如各个分布式组件如何协调起来,如何减少各个系统之间的耦合度,分布式事务的处理,如何去配置整个分布式系统等等。ZooKeeper主要就是解决这些问题的。而且分布式系统【不是涉及到拆分和子模块集群嘛】,那数据方面最主要的一个问题就是各个子模块之间的数据一致性问题。或者说子模块之间的沟通问题。
  • 分布式事务
    • 什么是分布式事务?捡田螺的小男孩老师关于分布式事务的文章
      在这里插入图片描述
    • 分布式事务的几种解决方案:
      • 2PC(二阶段提交)方案、3PC。【一致性问题【实现分布式事务一致性(Consistency)的方法有哪些?最著名的就是二阶段提交协议、三阶段提交协议和Paxos算法。】,为了解决数据一致性问题,在科学家和程序员的不断探索中,就出现了很多的一致性协议和算法。比如 2PC(两阶段提交),3PC(三阶段提交),Paxos算法等等。】
        • 2PC(两阶段提交):两阶段提交是一种 保证分布式系统数据一致性的协议,现在 很多数据库都是采用的两阶段提交协议来完成 分布式事务 的处理
          • 我们所需要解决的是 在分布式系统整个调用链中,我们所有服务的数据处理要么都成功要么都失败,即所有服务的 原子性问题
            • 2PC(两阶段提交, phase-commit)只解决了各个事务的原子性问题,随之也带来了很多的问题
              • 单点故障问题,如果协调者挂了那么整个系统都处于不可用的状态了。
              • 阻塞问题,即当协调者发送 prepare 请求,参与者收到之后如果能处理那么它将会进行事务的处理但并不提交,这个时候会一直占用着资源不释放,如果此时协调者挂了,那么这些资源都不会再释放了,这会极大影响性能。
              • 数据不一致问题,比如当第二阶段,协调者只发送了一部分的 commit 请求就挂了,那么也就意味着,收到消息的参与者会进行事务的提交,而后面没收到的则不会进行事务提交,那么这时候就会产生数据不一致性问题。
          • 在两阶段提交中,主要涉及到两个角色,分别是协调者和参与者。
            在这里插入图片描述
            • 第一阶段【prepare(准备阶段)】:当要执行一个分布式事务的时候,事务发起者首先向协调者 发起事务请求,然后 协调者会给所有参与者 发送 prepare 请求(其中包括事务内容)告诉参与者你们需要执行事务了,如果能执行我发的事务内容那么就 先执行但不提交,执行后请给我回复。然后 参与者收到 prepare 消息后,他们会开始执行事务(但不提交),并将 Undo 和 Redo 信息记入事务日志中,之后参与者就向协调者反馈是否准备好了。
              在这里插入图片描述
            • 第二阶段【commit(提交阶段)】:第二阶段主要 是协调者根据参与者反馈的情况来决定接下来是否可以进行事务的提交操作,即提交事务或者回滚事务。【比如这个时候 所有的参与者 都返回了准备好了的消息,这个时候就进行事务的提交,协调者此时会给所有的参与者发送 Commit 请求 ,当参与者收到 Commit 请求的时候会执行前面执行的事务的 提交操作 ,提交完毕之后将给协调者发送提交成功的响应。而如果在第一阶段并不是所有参与者都返回了准备好了的消息,那么此时协调者将会给所有参与者发送 回滚事务的 rollback 请求,参与者收到之后将会 回滚它在第一阶段所做的事务处理 ,然后再将处理情况返回给协调者,最终协调者收到响应后便给事务发起者返回处理失败的结果。】
              在这里插入图片描述
        • 3PC(三阶段提交, phase-commit):
          • 2PC存在的一系列问题,比如单点,容错机制缺陷等等,从而产生了 3PC(三阶段提交)
          • 3PC 在很多地方进行了超时中断的处理,比如协调者在指定时间内为收到全部的确认消息则进行事务中断的处理,这样能 减少同步阻塞的时间 。还有需要注意的是,3PC 在 DoCommit 阶段参与者如未收到协调者发送的提交事务的请求,它会在一定时间内进行事务的提交。为什么这么做呢?是因为这个时候我们肯定保证了在第一阶段所有的协调者全部返回了可以执行事务的响应,这个时候我们有理由相信其他系统都能进行事务的执行和提交,所以不管协调者有没有发消息给参与者,进入第三阶段参与者都会进行事务的提交操作
            • 3PC的三个阶段:
              在这里插入图片描述
              • CanCommit阶段:协调者向所有参与者发送 CanCommit 请求,参与者收到请求后会根据自身情况查看是否能执行事务,如果可以则返回 YES 响应并进入预备状态,否则返回 NO 。
              • PreCommit阶段:协调者根据参与者返回的响应来决定是否可以进行下面的 PreCommit 操作。如果上面参与者返回的都是 YES,那么协调者将向所有参与者发送 PreCommit 预提交请求,参与者收到预提交请求后,会进行事务的执行操作,并将 Undo 和 Redo 信息写入事务日志中 ,最后如果参与者顺利执行了事务则给协调者返回成功的响应。如果在第一阶段协调者收到了 任何一个 NO 的信息,或者 在一定时间内 并没有收到全部的参与者的响应,那么就会中断事务,它会向所有参与者发送中断请求(abort),参与者收到中断请求之后会立即中断事务,或者在一定时间内没有收到协调者的请求,它也会中断事务。
              • DoCommit阶段:这个阶段其实和 2PC 的第二阶段差不多,如果协调者收到了所有参与者在 PreCommit 阶段的 YES 响应,那么协调者将会给所有参与者发送 DoCommit 请求,参与者收到 DoCommit 请求后则会进行事务的提交工作,完成后则会给协调者返回响应,协调者收到所有参与者返回的事务提交成功的响应之后则完成事务。若协调者在 PreCommit 阶段 收到了任何一个 NO 或者在一定时间内没有收到所有参与者的响应 ,那么就会进行中断请求的发送,参与者收到中断请求后则会 通过上面记录的回滚日志 来进行事务的回滚操作,并向协调者反馈回滚状况,协调者收到参与者返回的消息后,中断事务。
        • Paxos算法
          • 3PC 通过一系列的超时机制很好的缓解了阻塞问题,但是最重要的一致性并没有得到根本的解决,比如在 PreCommit 阶段,当一个参与者收到了请求之后其他参与者和协调者挂了或者出现了网络分区,这个时候收到消息的参与者都会进行事务提交,这就会出现数据不一致性问题。要解决一致性问题还需要靠 Paxos 算法
          • Paxos 算法是兰伯特在 1990 年提出了一种分布式系统共识算法【Paxos 不是一致性算法而是共识算法,一致性和共识并不是一个概念】。【Raft 算法、ZAB 协议、 Fast Paxos 算法都是基于 Paxos 算法改进而来
            • Paxos 算法是 基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一,Paxos 算法解决的问题就是在分布式系统中如何就某个值(决议)达成一致 。【Paxos 算法是 Leslie Lamport(莱斯利·兰伯特)在 1990 年提出了一种分布式系统 共识 算法。这也是第一个被证明完备的共识算法(前提是不存在拜占庭将军问题,也就是没有恶意节点)
              • 拜占庭条件:但是如果采用传纸条的方式去传播消息,那么就会出现一个问题——我咋知道我的小纸条有没有传到我想要传递的那个门店手中呢?万一被哪个小家伙给劫持篡改了呢,对吧?这个时候就引申出一个概念—— 拜占庭将军问题 【拜占庭将军问题 指在不可靠信道上试图通过消息传递的方式达到一致性是不可能的, 所以所有的一致性算法的 必要前提 就是安全可靠的消息通道。】。
                在这里插入图片描述
            • 共识算法:
              在这里插入图片描述
              • 共识是可容错系统中的一个基本问题:即使面对故障,服务器也可以在共享状态上达成一。。共识算法允许一组节点像一个整体一样一起工作,即使其中的一些节点出现故障也能够继续工作下去,其正确性主要是源于复制状态机的性质:一组Server的状态机计算相同状态的副本,即使有一部分的Server宕机了它们仍然能够继续运行
                • 分布式共识可以实现对服务器和网络故障做出反应并在几秒钟内自动适应,对客户来说的话,明显的中断通常是不可接受的。
              • 适用于实际系统的共识算法通常具有以下特性:
                • 安全。确保在非拜占庭条件(也就是上文中提到的简易版拜占庭)下的安全性,包括网络延迟、分区、包丢失、复制和重新排序。
                • 高可用。只要大多数服务器都是可操作的,并且可以相互通信,也可以与客户端进行通信,那么这些服务器就可以看作完全功能可用的。因此,一个典型的由五台服务器组成的集群可以容忍任何两台服务器端故障。假设服务器因停止而发生故障;它们稍后可能会从稳定存储上的状态中恢复并重新加入集群
                • 一致性不依赖时序。错误的时钟和极端的消息延迟,在最坏的情况下也只会造成可用性问题,而不会产生一致性问题
                • 在集群中大多数服务器响应,命令就可以完成,不会被少数运行缓慢的服务器来影响整体系统性能
          • 兰伯特当时提出的 Paxos 算法主要包含 2 个部分:Basic Paxos 算法和Multi-Paxos 思想。
            • Basic Paxos 算法 : 描述的是多节点之间如何就某个值(提案 Value)达成共识
              • 在 Paxos 中的Basic Paxos算法中主要 有三个角色,分别为 Proposer提案者、Acceptor表决者、Learner学习者
            • Multi-Paxos 思想 : 描述的是执行多个 Basic Paxos 实例,就一系列值达成共识。Multi-Paxos 说白了就是执行多次 Basic Paxos ,核心还是 Basic Paxos
              • Multi-Paxos 只是一种思想,这种思想的核心就是通过多个 Basic Paxos 实例就一系列值达成共识。因为兰伯特提到的 Multi-Paxos 思想,缺少代码实现的必要细节(比如怎么选举领导者),所以在理解上比较难。二阶段提交是达成共识常用的方式,Basic Paxos 就是通过二阶段提交的方式来达成共识。Basic Paxos 还支持容错,少于一般的节点出现故障时,集群也能正常工作
          • Paxos 算法和 2PC 一样,Paxos 算法也有两个阶段,分别为 Prepare 和 accept 阶段捡田螺的小男孩老师关于Paxos算法的详细讲述
            在这里插入图片描述
            • prepare 阶段
              在这里插入图片描述
              • Proposer提案者:负责提出 proposal,每个提案者在提出提案时都会首先获取到一个 具有全局唯一性的、递增的提案编号N,即在整个集群中是唯一的编号 N,然后将该编号赋予其要提出的提案,在第一阶段是只将提案编号发送给所有的表决者。
              • Acceptor表决者:每个表决者在 accept 某提案后,会将该提案编号N记录在本地,这样每个表决者中保存的已经被 accept 的提案中会存在一个编号最大的提案,其编号假设为 maxN。每个表决者仅会 accept 编号大于自己本地 maxN 的提案,在批准提案时表决者会将以前接受过的最大编号的提案作为响应反馈给 Proposer 。
            • accept 阶段
              在这里插入图片描述
              • 当一个提案被 Proposer 提出后,如果 Proposer 收到了超过半数的 Acceptor 的批准(Proposer 本身同意),那么此时 Proposer 会给所有的 Acceptor 发送真正的提案(你可以理解为第一阶段为试探),这个时候 Proposer 就会发送提案的内容和提案编号。
                • 过半通过,可以中和一致性和可用性
              • 表决者收到提案请求后会再次比较本身已经批准过的最大提案编号和该提案编号,如果该提案编号 大于等于 已经批准过的最大提案编号,那么就 accept 该提案(此时执行提案内容但不提交),随后将情况返回给 Proposer 。如果不满足则不回应或者返回 NO 。当 Proposer 收到超过半数的 accept ,那么它这个时候会向所有的 acceptor 发送提案的提交请求。需要注意的是,因为上述仅仅是超过半数的 acceptor 批准执行了该提案内容,其他没有批准的并没有执行该提案内容,所以这个时候需要向未批准的 acceptor 发送提案内容和提案编号并让它无条件执行和提交,而对于前面已经批准过该提案的 acceptor 来说 仅仅需要发送该提案的编号 ,让 acceptor 执行提交就行了。而如果 Proposer 如果没有收到超过半数的 accept 那么它将会将 递增 该 Proposal 的编号,然后 重新进入 Prepare 阶段
          • paxos 算法的死循环问题:有点类似于两个人吵架,小明说我是对的,小红说我才是对的。比如说,此时提案者 P1 提出一个方案 M1,完成了 Prepare 阶段的工作,这个时候 acceptor 则批准了 M1,但是此时提案者 P2 同时也提出了一个方案 M2,它也完成了 Prepare 阶段的工作。然后 P1 的方案已经不能在第二阶段被批准了(因为 acceptor 已经批准了比 M1 更大的 M2),所以 P1 自增方案变为 M3 重新进入 Prepare 阶段,然后 acceptor ,又批准了新的 M3 方案,它又不能批准 M2 了,这个时候 M2 又自增进入 Prepare 阶段。就这样无休无止的永远提案下去,这就是 paxos 算法的死循环问题。解决办法就是只允许一个提案就行了
        • Raft 算法、ZAB 协议、 Fast Paxos 算法都是基于 Paxos 算法改进而来【针对没有恶意节点的情况,除了 Raft 算法之外,当前最常用的 **一些共识算法** 比如 ZAB 协议、 Fast Paxos 算法都是基于 Paxos 算法改进的】
          • 针对存在恶意节点的情况,一般使用的是工作量证明(POW,Proof-of-Work)、权益证明(PoS,Proof-of-Stake )等共识算法这类共识算法最典型的应用就是区块链,就比如说前段时间以太坊官方宣布其共识机制正在从工作量证明(PoW)转变为权益证明(PoS)
            • 区块链系统使用的共识算法需要解决的核心问题是 拜占庭将军问题 ,这和我们日常接触到的 ZooKeeper、Etcd、Consul 等分布式中间件不太一样
          • ZAB:
          • Raft 算法
            • Raft 算法:2013 年才诞生了一个比 Paxos 算法更易理解和实现的共识算法—Raft 算法.Raft 是Multi-Paxos的一个变种,其简化了 Multi-Paxos 的思想,变得更容易被理解以及工程实现
            • 一个 Raft 集群包括若干服务器,以典型的 5 服务器集群举例。在任意的时间,每个服务器一定会处于以下三个状态中的一个
              在这里插入图片描述
              • Leader:负责发起心跳,响应客户端,创建日志,同步日志
                在这里插入图片描述
                • 领导人选举:raft 使用心跳机制来触发 Leader 的选举Leader 会向所有的 Follower 周期性发送心跳来保证自己的 Leader 地位。如果一个 Follower 在一个周期内没有收到心跳信息,就叫做选举超时,然后它就会认为此时没有可用的 Leader,并且开始进行一次选举以选出一个新的 Leader【为了开始新的选举,Follower 会自增自己的 term 号并且转换状态为 Candidate。然后他会向所有节点发起 RequestVoteRPC 请求】
              • Candidate:Leader 选举过程中的临时角色,由 Follower 转化而来,发起投票参与竞选
              • Follower:接受 Leader 的心跳和日志同步数据,投票给 Candidate。
                • 如果一台服务器能够收到来自 Leader 或者 Candidate 的有效信息,那么它会一直保持为 Follower 状态,并且刷新自己的 electionElapsed,重新计时。
            • Raft的任期&日志【javaGuide老师关于日志复制的详细文章
              在这里插入图片描述
              • entry:每一个事件成为 entry,只有 Leader 可以创建 entry。entry 的内容为<term,index,cmd>其中 cmd 是可以应用到状态机的操作
              • log:由 entry 构成的数组,每一个 entry 都有一个表明自己在 log 中的 index。只有 Leader 才可以改变其他节点的 log。entry 总是先被 Leader 添加到自己的 log 数组中,然后再发起共识请求,获得同意后才会被 Leader 提交给状态机。Follower 只能从 Leader 获取新日志和当前的 commitIndex,然后把对应的 entry 应用到自己的状态机中
            • Raft算法的安全性
              • 选举限制:Leader 需要保证自己存储全部已经提交的日志条目。这样才可以使日志条目只有一个流向:从 Leader 流向 Follower,Leader 永远不会覆盖已经存在的日志条目。Leader 需要保证自己存储全部已经提交的日志条目。这样才可以使日志条目只有一个流向:从 Leader 流向 Follower,Leader 永远不会覆盖已经存在的日志条目。Leader 需要保证自己存储全部已经提交的日志条目。这样才可以使日志条目只有一个流向:从 Leader 流向 Follower,Leader 永远不会覆盖已经存在的日志条目。
              • 节点崩溃:如果 Leader 崩溃,集群中的节点在 electionTimeout 时间内没有收到 Leader 的心跳信息就会触发新一轮的选主,在选主期间整个集群对外是不可用的。如果 Leader 崩溃,集群中的节点在 electionTimeout 时间内没有收到 Leader 的心跳信息就会触发新一轮的选主,在选主期间整个集群对外是不可用的
          • Fast Paxos 算法
      • TCC(Try、Confirm、Cancel)或者叫TCC(补偿机制)
        在这里插入图片描述
        在这里插入图片描述
        • TCC 采用了补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。TCC(Try-Confirm-Cancel)包括三段流程:
          • try阶段:尝试去执行,完成所有业务的一致性检查,预留必须的业务资源。
          • Confirm阶段:该阶段对业务进行确认提交,不做任何检查,因为try阶段已经检查过了,默认Confirm阶段是不会出错的
          • Cancel 阶段:若业务执行失败,则进入该阶段,它会释放try阶段占用的所有业务资源,并回滚Confirm阶段执行的所有操作
      • 本地消息表
      • 最大努力通知
      • seata事务

巨人的肩膀:
凤凰架构~大佬的书,跟深入理解JVM一样值得多次翻阅
Spring Cloud dalstoon版中文文档:https://www.apiref.com/spring-cloud-zh/dalston/#_router_and_filter_zuul
B站的各位大佬
JavaGuide
Zookeeper官方文档
Dubbo官方文档
https://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&mid=2247568029&idx=2&sn=9aae8d03e4e9c941db78a3673394e613&chksm=9bd26705aca5ee13a0b0a9ada7432741a7e5c11676e50661da34b7e7632f54882c66c4ce4d20&scene=178&cur_album_id=1776403731354337285#rd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值