CAP 理论

CAP 理论指出对于一个分布式计算系统来说,不可能同时满足以下三点:

  • 一致性:在分布式环境中,一致性是指数据在多个副本之间是否能够保持一致的特性,等同于所有节点访问同一份最新的数据副本。在一致性的需求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态。
  • 可用性:每次请求都能获取到正确的响应,但是不保证获取的数据为最新数据。
  • 分区容错性:分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。

一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

在这三个基本需求中,最多只能同时满足其中的两项,P 是必须的,因此只能在 CP 和 AP 中选择,zookeeper 保证的是 CP,对比 spring cloud 系统中的注册中心 eureka实现的是 AP。

BASE 理论

BASE 是 Basically Available(基本可用)、Soft-state(软状态) 和 Eventually Consistent(最终一致性) 三个短语的缩写。

  • 基本可用:在分布式系统出现故障,允许损失部分可用性(服务降级、页面降级)。

  • 软状态:允许分布式系统出现中间状态。而且中间状态不影响系统的可用性。这里的中间状态是指不同的 data replication(数据备份节点)之间的数据更新可以出现延时的最终一致性。

  • 最终一致性:data replications 经过一段时间达到一致性。

BASE 理论是对 CAP 中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。

  • 强一致性:又称线性一致性(linearizability )

    1. 任意时刻,所有节点中的数据是一样的,
    2. 一个集群需要对外部提供强一致性,所以只要集群内部某一台服务器的数据发生了改变,那么就需要等待集群内其他服务器的数据同步完成后,才能正常的对外提供服务
    3. 保证了强一致性,务必会损耗可用性
  • 弱一致性:

    1. 系统中的某个数据被更新后,后续对该数据的读取操作可能得到更新后的值,也可能是更改前的值。
    2. 即使过了不一致时间窗口,后续的读取也不一定能保证一致。
  • 最终一致性:

    1. 弱一致性的特殊形式,不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化
    2. 存储系统保证在没有新的更新的条件下,最终所有的访问都是最后更新的值
  • 顺序一致性:

    1. 任何一次读都能读到某个数据的最近一次写的数据。
    2. 对其他节点之前的修改是可见(已同步)且确定的,并且新的写入建立在已经达成同步的基础上。

分布式一致性协议

2PC

2PC 全称:Two phase commit, 即两阶段提交协议。第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段) 同步阻塞问题/单点故障/数据不一致/二阶段无法解决的问题

3PC

3PC的CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。

PreCommit阶段(undo和redo信息记录到事务日志中)

doCommit阶段

ZAB

ZAB 协议其实是 2PC 协议的一个升级版 (利用 过半投票法 与 恢复策略 解决了 脑裂(数据不一致性) 和 单点问题(无限等待)等 2阶段提交协议所遇到的问题)

ZAB 协议中的一些名词:

  • Leader 领导者(处理 Client 发送的 request请求 , 请求这里指的是更改请求。向 Follower 发送协议 Proposal, 处理Follower 的ACK 信息。并对过半Follower 的ACK 发起 Commit )
  • Follower 跟随者 (作为Client 可以发起 Request 请求。处理 Leader 提出的 Proposal ,给出 ack. 接受Leader 提出的 Commit.)
  • Observer 观察者 (只做数据同步,转发请求,并不对 协议 Proposal 提出 ACK 等信息。也不参与 崩溃恢复阶段的 Leader 选举。)

ZAB 协议的几个阶段:

  • 消息广播阶段:当即集群已经有过半的Follower 服务器完成了 和 Leader 服务器的状态同步,那么整服务架构 就可以进入消息广播模式了。消息广播阶段其实就是对 阶段提交协议 的 一个最主要的实现步奏。

    1. Client 在接收到 Request 后都会转发给 Leader 进行处理。Leader 发起一次预提交,先向集群中的Follow 发送 ZXID = curZXID + 1 的协议。
    2. 每个Follower 在接收到 事务 Proposal 之后, 都会首先将其以事务日志的形式写入到本地磁盘中,并且在写入成功后反馈给Leader 一个 Ack响应。
    3. 当Leader 在其接收到超过半数的Follower 的 Ack 响应后,就会广播一个 Commit 消息给所有的 Follow 服务器 以通知其进行事务提交,同时Leader 自身也会完成对事务的提交,而每一个服务器在接收到 Commit 消息后,也会完成对 事务 Proposal 的确认。
  • 崩溃恢复:当整个集群在启动过程中,或者是当Leader 服务器出现网络中断,崩溃退出 与 重启 等异常情况时,ZAB协议就会进入 恢复模式并产生新的Leader。

    1. 产生的条件:
      当Leader出现崩溃推出或机器重启
      集群中不存在过半的服务器与该Leader 保证正常通信
      在重新开始新一轮的原子广播事务操作之前,所有进程会 先使用崩溃恢复协议 来达到一个一致的状态,于是整个ZAB 流程进入到崩溃恢复模式。
    2. ZAB协议崩溃恢复要求满足下2个要求:
      确保已经被leader提交的proposal必须最终被所有的follower服务器提交
      确保丢弃已经被leader出的但是没有被提交的proposal
    3. 根据上述要求 ZXID
      新选举出来的leader不能包含未提交的proposal,即新选举的leader必须都是已经提交了的proposal的follower服务器节点。同时,新选举的leader节点中含有最高的ZXID。这样做的好处就是可以避免了leader服务器检查proposal的提交和丢弃工作。
    4. leader服务器发生崩溃时分为如下场景:
      ** leader在提出proposal时未提交之前崩溃,则经过崩溃恢复之后,新选举的leader一定不能是刚才的leader。因为这个leader存在未提交的proposal
      ** leader在发送commit消息之后,崩溃。即消息已经发送到队列中。经过崩溃恢复之后,参与选举的follower服务器(刚才崩溃的leader有可能已经恢复运行,也属于follower节点范畴)中有的节点已经是消费了队列中所有的commit消息。即该follower节点将会被选举为最新的leader。剩下动作就是数据同步过程。
  • 数据同步: 在集群中新加入节点 或者 新Leader 选举出来后,都需要进行数据同步。Leader 服务器需要确保 所有的 follower 能够接收到每一条事务 Proposal , 并且能够正确地将所有已经提交了的事务 Proposal 应用到内存中去。

    1. Leader 服务器会为每一个 Follower 准备一个队列,并将那些没有被 各Foliower 服务器同步的事务以 Proposal 发送给 Follower 服务器,并且在每一个 Proposal 发送一个 commit, 以表示该事务已经被提交。

Paxos 在古希腊有一个Paxos 的小岛,岛上采用议会的形式来通过法令,议会中的议员通过信使进行消息的传递。

Paxos 协议的 3个最主要的角色

  • Acceptor : 对协议进行批准 (一个提案被选定,需要半数以上的Acceptor 批准)
  • Proposer : 发起协议(当有多个Proposer 的时候,有可能出现始终无提案被选中的情况,这个时候,我们对Proposer 进行改进,确保只有一个Proposer 进行批准提案。)
  • Learner : 对通过的协议,更新自己的信息(获取一个已经被选定的提案的前提是,该提案已经被半数以上的Acceptor 批准。为了减少网络开销,我们可以通过将批准的提案发送给一个特定的Learner 集群的方式完成数据的更新。)

Rafa Raft的作者也说是被Paxos苦虐了无数个回合后,才设计出了Raft协议。作者的目标是设计一个足够详细并且简单易懂的“Paxos协议”

Paxos协议中有一个基本的假设前提:可能会同时有多个Leader存在。这里把Paxos协议执行的过程分为以下两个部分:

  • Leader选举
  • 数据广播

在《由浅入深理解Paxos协议(2)》的“Leader的选取”一节中提到过,Paxos协议并没有给出详细的Leader选举机制。Paxos对于Leader的选举没有限制,用户可以自己定义。这是因为Paxos协议设计了一个巧妙的数据广播过程,即Paxos的基本通讯协议(The Basic Protocol)。它有很强的数据一致性保障,即使在多个Leader同时出现时也能够保证广播数据的一致性。

而Raft协议走了完全相反的一个思路: 保证不会同时有多个Leader存在。因此Raft协议对Leader的选举做了详细的设计,从而保证不会有多个Leader同时存在。相反,数据广播的过程则变的简单易于理解了。

  • Raft的日志广播过程
    为了保证数据被复制到多数的节点上,Raft的广播过程尽管简单仍然要使用多数派协议,只是这个过程要容易理解的多:

    1. 发送日志到所有Followers(Raft中将非Leader节点称为Follower)。
    2. Followers收到日志后,应答收到日志。
    3. 当半数以上的Followers应答后,Leader通知Followers日志广播成功。

    日志和日志队列
    Raft将用户数据称作日志(Log),存储在一个日志队列里。每个节点上都有一份。队列里的每个日志都一个序号,这个序号是连续递增的不能有缺。

    日志队列里:

    1. 已提交日志:已经复制到超过半数节点的数据。这些日志是可以发送给应用程序去执行的日志。
    2. 未提交日志:还未复制到超过半数节点的数据。

    当Followers收到日志后,将日志按顺序存储到队列里。但这时Commit Index不会更新,因此这些日志是未提交的日志,不能发送给应用去执行。当Leader收到超过半数的Followers的应答后,会更新自己的Commit Index,并将Commit Index广播到Followers上。这时Followers更新Commit Index,未提交的日志就变成了已提交的日志,可以发送给应用程序去执行了。

  • Raft的Leader选举
    Raft称它的Leader为“Strong Leader”。Strong Leader 有以下特点:

    1. 同一时间只有一个Leader
    2. 只能从Leader向Followers发送数据,反之不行。

    Raft通过哪些机制来实现Strong Leader。

    1. 多数派协议
    2. 随机超时机制
    3. Candidate的日志长度要等于或者超过半数节点才能选为Leader 为什么不是检查Commit Index?因为Leader故障时,很有可能只有Leader的Commit Index是最大的。
    4. Followers日志补齐
    5. Followers未提交日志的更新
  • 新旧Leader的交替 (Raft有办法让Followers拒绝旧Leader的日志)
    新的Leader选出后,开始广播日志。这时如果旧的Leader故障恢复了(比如网络临时中断),并且还认为自己是Leader,也会广播日志。这不就导致了同时有两个Leader出现吗?是的,Raft也没办法让旧的Leader不发日志,但是Raft有办法让Followers拒绝旧Leader的日志。

  • Raft的实现
    论文中作者仅用了两个RPC就实现了Raft的功能,它们分别是:

    1. RequestVote() Candidate发起的投票请求
    2. AppendEntries() 将日志广播到Followers上 心跳、提交

Paxos, Zab , Raft 协议对比

Paxos

Paxos 可以说是 Zab, Raft 之前提出过半数投票的概念的分布式一致的算法模型

  1. Paxos 模型中有3个角色,Learner, Acceptor, Proposer , 对于 ZAB / Raft 对角色进行了细化,
    首先 Learner 与 Acceptor 进行了合并,在这2个协议中,都被称为 Follower.
    Proposer 也即协议的提交者 都被称为 Leader.
  2. Paxos 协议只是一个较为通用的模板,对很多地方没有细致的说明, 例如如何确保一个全局唯一的 Proposal 号。
    而 Zab / Raft 对其进行了细致的描述。
    Zab ZXID , 高32位表示 epoch 周期, 低32位表示了事务编号
    Raft Term 标识了全局唯一递增的序号。
  3. Paxos 协议 最令人诟病的一点就是 描述了 可能会存在 多个 Proposer, 而 多个Propser 的协调这点,并没有很好的描述。
    而 Zab , Raft 都放弃了多 Proposer , 都设计为 单 Leader , 并由该 Leader 进行协调。

Zab

  1. Zab协议与 Paxos 区别在上面已经表述了,这里不再做表述
  2. Zab / Raft 协议的区别, 这两个协议我认为大致的实现都是一样的,但也有区别
    首先 Raft 协议提出了 HW 的概念, HW 即 kafka 1.0.0 之前的水位模型,也即确认Commit ,跟总体 Index, 也即有一个指针表示当前已经确认的消息位置,另一个指向所有的消息
  3. Zab / Raft 的Leader 选举阶段 (故障恢复 / 初始阶段)
    • 故障恢复
      Zab 协议采取的策略,是之前已经确认最大的 ZXID 会成为 Leader
      Raft 采取的策略是 最大日志长度 会成为 Leader, 而不是 commit index . 为什么不是 commit index , 因为很有可能之前的 Leader 的 commit index 最大。
    • 初始阶段:Raft 针对于选举冲突,设置了加时竞票策略。

Raft

Raft 与 Paxos, Zab 的区别见上面的描述

Zookeeper 特性

  • 顺序一致性:从同一个客户端发起的事务请求,最终将会严格地按照其发起顺序被应用到Zookeeper中。
  • 原子性:所有事物请求的处理结果在整个集群中所有机器上的应用情况是一致的,也就是说,要么整个集群的所有机器都成功应用了某一个事务,要么都没有应用,要么都没有应用,一定不存在集群中部分应用了某一个事务,而另外一个部分没有应用的情况
  • 单一视图 (Single System Image):无论客户端连接的是那个Zookeeper 服务器,其看到的服务端数据模型都是一致的。
  • 可靠性:一旦服务端成功应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态将会一直保留下来,除非有另一个事务又对其进行了变更。
  • 实时性: Zookeeper 仅仅保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。

思考:zookeeper是强一致性吗?

Zookeeper 写操作强一致性(zab)

Zookeeper 读操作顺序一致性(可以读之前sync拉leader数据同步)

  • MongoDB
    写:Majority 强一致性
    读:单节点 最终一致性
    通过 写关注 和 读关注 节点拉数据响应保证读写强一致性

分布式框架(一):分布式协议相关推荐

  1. python 分布式框架_python分布式框架rq的使用

    RedisQueue是一款轻量级的分布式异步任务队列调度框架,基于redis数据库作为broker,生产端将任务job存储到redis数据库中,消费端监听队列并取出任务执行. 1.基础架构 rq框架使 ...

  2. 我的面试标准:第一能干活,第二Java基础要好,第三最好熟悉些分布式框架!...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:hsm_computer www.cnblogs.com/J ...

  3. 分布式概念-分布式事务,并发处理协议

    点击上方蓝色字体,选择"设为星标" 优质文章,及时送达 提到分布式系统,分布式事务是经常被大家提起的话题,也是经常在我们编码或是系统设计时遇到的问题,很常见. 如果让大家说一种解决 ...

  4. 前沪江高级架构师学习笔记分享:分布式框架设计与实现

    1.分布式服务框架设计 分布式服务框架一般可以分为以下几个部分, (1)RPC基础层: 包括底层通信框架,如NIO框架.通信协议,序列化和反序列化协议, 以及在这几部分上的封装,屏蔽底层通信细节和序列 ...

  5. Python 并行分布式框架 Celery

    Celery 官网:http://www.celeryproject.org Celery 官方文档英文版:http://docs.celeryproject.org/en/latest/index. ...

  6. 【Java从0到架构师】分布式框架通信核心基础 - 序列化(JDK、Protobuf)、远程过程调用 RMI

    分布式框架通信核心基础 序列化 JDK 的序列化 JDK 序列化的一些细节 Protobuf 序列化 Protobuf 环境搭建与操作 Protobuf 原理分析 实际数据传输 序列化技术选型 远程过 ...

  7. 基于SSM框架大型分布式电商系统开发(1-2)

    前言 开发个人的毕业设计,整个项目的静态页由别人提供,其余功能皆是自己开发,记录下开发流程. 第一章 分布式框架-Dubbox 1.Zookeeper 在Linux系统的安装(第一天) 1.1在Lin ...

  8. 使用LCN框架解决分布式事物

    使用LCN框架解决分布式事物 更多干货 分布式实战(干货) spring cloud 实战(干货) mybatis 实战(干货) spring boot 实战(干货) React 入门实战(干货) 构 ...

  9. SpringBoot使用Redis 数据访问(单点、集群、哨兵、连接池、Pipline、分布式框架Redisson、解决方案)

    目录 Redis 文献资料 用Redis编程 Redis模块API 教程和常见问题解答 管理 嵌入式和物联网 故障排除 Redis集群 其他基于Redis的分布式系统 在SSD和永久性存储器上进行Re ...

  10. Scrapy框架+Gerapy分布式爬取海外网文章

    Scrapy框架+Gerapy分布式爬取海外网文章 前言 一.Scrapy和Gerapy是什么? 1.Scrapy概述 2.Scrapy五大基本构成: 3.建立爬虫项目整体架构图 4.Gerapy概述 ...

最新文章

  1. 23 种设计模式实战 pdf(很全)
  2. mysql cmd终端服务无法启动
  3. [C++调试笔记]Main函数声明变量
  4. PHP面试题:PHP.ini路径?
  5. P4597-序列sequence【堆】
  6. 前端学习(3323):高级设计说闭包
  7. QT中信号和槽的简单解释
  8. 红黑树与平衡二叉树_百图详解红黑树,想不理解都难
  9. es6箭头函数_javascript-ES6函数进阶(箭头函数,默认参数)(笔记)
  10. VMware安装Ubuntu 18.04虚拟机(镜像下载、硬盘分区、创建虚拟机、安装系统、桥接模式网络配置)
  11. C++ 之父即将开始直播,请就位!
  12. java mapxtreme_MapXtreme Java Edition 4.8使用心得(一)
  13. Silverlight常见问题解决方法
  14. 从网上自学老男孩python全栈的笔记-经历
  15. 摄氏度和开氏度的换算_开氏度和摄氏度
  16. From Calcite to Tampering with Flink SQL
  17. 微信视频号如何申请认证,流程是什么?
  18. 关于iOS14 访问相册权限问题
  19. 手机status500_HTTP Status 500 - 是什么意思
  20. 【ROS】launch文件详解

热门文章

  1. python一个try块后接一个或多个finally块_五、Python try except finally:资源回收
  2. python fileinput_Python fileinput模块使用实例
  3. 笨办法学Python 3 ex35学习笔记
  4. sql取字段中的部分字符
  5. 【史诗级干货长文】HMM模型
  6. 离散傅里叶变换 - 快速计算方法及C实现 - 第一篇
  7. CCF NOI1053. 相似度
  8. 恭贺乔迁之喜,发几个视频!
  9. 关于苹果过审2.5.2 dlopen dlsym问题
  10. 3DGame-unity-HW9