ZooKeeper
2021-04-14 11:24:54 0 举报
AI智能生成
zookeeper图谱
作者其他创作
大纲/内容
zookeeper
Zookeeper 简介
一致性
顺序一致性
zk 接收到的 N 多个事务请求(写操作请求),其会被严格按照接收顺序应用到 zk 中。
原子性
所有事务请求的结果在 zk 集群中每一台主机上的应用情况都是一致的。要么全部应用成功,要么全部失败。
单一视图
无论 Client 连接的是 zk 集群中的哪个主机,其看到的数据模型都是一致的。
可靠性
一旦 zk 成功应用了某事务,那么该事务所引发的 zk 状态变更会被一直保留下来,直到另一个事务将其修改
最终一致性
Paxos算法
Paxos 与拜占庭将军问题
拜占庭将军问题是由 Paxos 算法作者莱斯利·兰伯特提出的点对点通信中的基本问题。该问题要说明的含义是, 在不可靠信道上试图通过消息传递的方式达到一致性是不可能的。 所以, Paxos 算法的前提是不存在拜占庭将军问题,即信道是安全的、可靠的,集群节点间传递的消息是不会被篡改的。一般情况下,分布式系统中各个节点间采用两种通讯模型:共享内存(Shared Memory)、消息传递(Messages Passing)。而 Paxos 是基于消息传递通讯模型的
算法描述
三种角色
Proposer:提案者
Acceptor:表决者
Learner:学习者,同步者
Paxos 算法的一致性
每个提案者在提出提案时都会首先获取到一个递增的、全局唯一的提案编号 N,然后将该编号赋予其要提出的提案
每个表决者在 accept 某提案后,会将该提案的编号 N 记录在本地,这样每个表决者中保存的已经被 accept 的提案中会存在一个编号最大的提案,其编号假设为 maxN。 每个表决者仅会 accept 编号大于自己本地 maxN 的提案。
在众多提案中最终只能有一个提案被选定。
一旦一个提案被选定,则其它学习者会主动同步(Learn)该提案到本地
没有提案被提出则不会有提案被选定。
2PC与3PC
2PC: Two Phase Commit,即 prepare -> accept
3PC: Three Phase Commit,即 prepare -> accept -> commit。
它们的区别主要就在于 accept 阶段中是否包含 commit 功能
3PC 算法过程描述
准备阶段 prepare
提案者(Proposer)准备提交一个编号为 N 的提议,于是其首先向所有表决者(Acceptor)发送 prepare(N)请求,用于试探集群是否支持该编号的提议。
每个表决者(Acceptor)中都保存着自己曾经 accept 过的提议中的最大编号 maxN。当一个表决者接收到其它主机发送来的 prepare(N)请求时,其会比较 N 与 maxN 的值。有以下几种情况:
若 N 小于 maxN,则说明该提议已过时,当前表决者采取不回应或回应 Error 的方式来拒绝该 prepare 请求;
在 prepare 阶段 N 不可能等于 maxN。这是由 N 的生成机制决定的。要获得 N 的值,其必定会在原来数值的基础上采用同步锁方式增一。
接受阶段 accept
若提案者没有接收到超过半数的表决者的 accept 反馈,则有两种可能的结果产生。一是放弃该提案,不再提出;二是重新进入 prepare 阶段,递增提案号,重新提出 prepare请求。
提交阶段 commit
若提案者接收到的反馈数量超过了半数,则其会向外广播两类信息:
向曾 accept 其提案的表决者发送“可执行数据同步信号”,即让它们执行其曾接收到的提案;
向未曾向其发送 accept 反馈的表决者发送“提案 + 可执行数据同步信号”,即让它们接受到该提案后马上执行。
2PC 算法过程描述
2PC 与 3PC 的区别是,在提案者接收到超过半数的表决者对于 parepare 阶段的反馈后,其会向所有表决者发送真正的提案 proposal。当表决者接受到 proposal 后就直接将其同步到了本地,不用再等待 commit 消息了。那么,为什么不直接使用 2PC,而要使用 3PC 呢?是因为 2PC 中存在着较多的弊端(这里就不再展开来说了)。所以很多 Paxos 工业实现使用的都是 3PC 提交。但 2PC 提交的效率要高于 3PC 提交,所以在保证不出问题的情况下,是可以使用 2PC 提交的
Paxos 算法的活锁问题
前面所述的Paxos算法在实际工程应用过程中,根据不同的实际需求存在诸多不便之处,所以也就出现了很多对于基本 Paxos 算法的优化算法,以对 Paxos 算法进行改进, 例如, MultiPaxos、 Fast Paxos、 EPaxos。例如, Paxos 算法存在“活锁问题”, Fast Paxos 算法对 Paxos 算法进行了改进:只允许一个进程提交提案,即该进程具有对 N 的唯一操作权。该方式解决了“活锁”问题。
ZAB协议
简介
ZAB , Zookeeper Atomic Broadcast, zk 原子消息广播协议,是专为 ZooKeeper 设计的一种支持崩溃恢复的原子广播协议,在 Zookeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性。Zookeeper 使用一个单一主进程来接收并处理客户端的所有事务请求,即写请求。当服务器数据的状态发生变更后,集群采用 ZAB 原子广播协议, 以事务提案 Proposal 的形式广播到所有的副本进程上。 ZAB 协议能够保证一个全局的变更序列,即可以为每一个事务分配一个全局的递增编号 xid。当 Zookeeper 客户端连接到 Zookeeper 集群的一个节点后,若客户端提交的是读请求,那么当前节点就直接根据自己保存的数据对其进行响应;如果是写请求且当前节点不是Leader,那么节点就会将该写请求转发给 Leader, Leader 会以提案的方式广播该写操作,只要有超过半数节点同意该写操作,则该写操作请求就会被提交。然后 Leader 会再次广播给所有订阅者,即 Learner,通知它们同步数据。
ZAB 与 Paxos 的关系
ZAB 协议是 Paxos 算法的一种工业实现算法。但两者的设计目标不太一样。 ZAB 协议主要用于构建一个高可用的分布式数据主从系统,即 Follower 是 Leader 的从机, Leader 挂了,马上就可以选举出一个新的 Leader,但平时它们都对外提供服务。而 Fast Paxos 算法则是用于构建一个分布式一致性状态机系统,确保系统中各个节点的状态都是一致的。另外, ZAB 还使用 Google 的 Chubby 算法作为分布式锁的实现,而 Google 的 Chubby 也是 Paxos 算法的应用。zk 集群对于事务请求的处理是 Fast Paxos 算法的体现,即只允许 Leader 提出提案。其属于 3PC 提交。但 Leader 选举是 Paxos 算法的体现,因为 Leader 宕机后,所有 Follower 均可提交提案,它们在最初都是“我选我”。其属于 2PC 提交
三类角色
Leader: zk 集群中事务请求的唯一处理者;其也可以处理读请求。
Follower:处理读请求;将事务请求转发给 Leader;对 Leader 发起的提案进行表决;同步 Leader 的事务处理结果;在 Leader 的选举过程中具有选举权与被选举权
Observer:不具有表决权,且在 Leader 选举过程中没有选举权与被选举权的 Follower。
Learner:学习者,同步者。 Learner = Follower + ObserverQuorumPeer = Participant = Leader + Follower
三个数据
zxid: 64 位长度的 Long 类型,其高 32 位为 epoch,低 32 位为 xid。
epoch:每一个新的 Leader 都会有一个新的 epoch
xid:其为一个流水号
三种模式
恢复模式:其包含两个重要阶段: Leader 的选举,与初始化同步
广播模式:其可以分为两类:初始化广播,与更新广播
同步模式:其可以分为两类:初始化同步,与更新同步
四种状态
LOOKING:选举状态
FOLLOWING: Follower 的正常工作状态
OBSERVING: Observer 的正常工作状态
LEADING: Leader 的正常工作状态
同步模式与广播模式
初始化同步
前面我们说过,恢复模式具有两个阶段: Leader 选举与初始化同步。当完成 Leader 选举后,此时的 Leader 还是一个准 Leader,其要经过初始化同步后才能变为真正的 Leader。
Leader 将那些没有被各个 Learner 同步的事务封装为 Proposal
Leader 将这些 Proposal 逐条发给各个 Learner,并在每一个 Proposal 后都紧跟一个COMMIT 消息,表示该事务已经被提交, Learner 可以直接接收并执行
Learner 接收来自于 Leader 的 Proposal,并将其更新到本地
当 Learner 更新成功后,会向准 Leader 发送 ACK 信息
Leader 服务器在收到来自 Learner 的 ACK 后就会将该 Learner 加入到真正可用的 Follower列表或 Observer 列表。没有反馈 ACK,或反馈了但 Leader 没有收到的 Learner, Leader不会将其加入到相应列表。
消息广播算法
Leader 接收到事务请求后,为事务赋予一个全局唯一的 64 位自增 id,即 zxid,通过zxid 的大小比较即可实现事务的有序性管理,然后将事务封装为一个 Proposal
Leader 根据 Follower 列表获取到所有 Follower,然后再将 Proposal 通过这些 Follower 的队列将提案发送给各个 Follower。
当 Follower 接收到提案后,会先将提案的 zxid 与本地记录的事务日志中的最大的 zxid进行比较。若当前提案的 zxid 大于最大 zxid,则将当前提案记录到本地事务日志中,并向 Leader 返回一个 ACK。(提问学员)
当 Leader 接收到过半的 ACKs 后, Leader 就会向所有 Follower 的队列发送 COMMIT消息,向所有 Observer 的队列发送 Proposal。
当 Follower 收到 COMMIT 消息后,就会将事务正式更新到本地。当 Observer 收到Proposal 后,会直接将事务更新到本地
无论是 Follower 还是 Observer,在同步完成后都需要向 Leader 发送成功 ACK。
Observer 的数量问题
Observer 数量并不是越多越好,一般与 Follower 数量相同。 因为 Observer 数量的增多虽不会增加事务操作压力,但其需要从 Leader 同步数据, Observer 同步数据的时间是小于等于 Follower 同步数据的时间的。当 Follower 同步数据完成, Leader 的 Observer 列表中的Observer 主机将结束同步。那些完成同步的 Observer 将会进入到另一个对外提供服务的列表。那么,那些没有同步了数据无法提供服务的 Observer 主机就形成了资源浪费。所以,对于事务操作发生频繁的系统,不建议使用过多的 Observer。
Leader 中保存的 Observer 列表其实有两个:all:包含所有 Observer。service:已经完成了从 Leader 同步数据的任务。 service <= all。其是动态的。
Leader 中保存的 Follower 列表其实也有两个:all:要求其中必须有过半的 Follower 向 Leader 反馈 ACKservice:
Leader的选举机制
Leader 选举中的基本概念
serverId
逻辑时钟
逻辑时钟, Logicalclock,是一个整型数,该概念在选举时称为 logicalclock,而在选举结束后称为 epoch。即 epoch 与 logicalclock 是同一个值,在不同情况下的不同名称。
Leader 选举算法
集群启动中的 Leader 选举
宕机后的 Leader 选举
恢复模式的三个原则
Leader 的主动出让原则
若集群中 Leader 收到的 Follower 心跳数量没有过半,此时 Leader 会自认为自己与集群的连接已经出现了问题,其会主动修改自己的状态为 LOOKING,去查找新的 Leader。而其它 Server 由于有过半的主机认为已经丢失了 Leader,所以它们会发起新的 Leader选举,选出一个新的 Leader。
已被处理的消息不能丢
正常情况下,当 Leader 收到超过半数 Follower 的 ACKs 后,就向各个 Follower 广播COMMIT消息,批准各个 Server执行该写操作事务。当各个 Server 在接收到Leader的 COMMIT消息后就会在本地执行该写操作,然后会向客户端响应写操作成功。但是如果在非全部 Follower 收到 COMMIT 消息之前 Leader 就挂了,这将导致一种后果:部分 Server 已经执行了该事务,而部分 Server 尚未收到 COMMIT 消息,所以其并没有执行该事务。当新的 Leader 被选举出,集群经过恢复模式后需要保证所有 Server 上都执行了那些已经被部分 Server 执行过的事务
被丢弃的消息不能再现
当在 Leader 新事务已经通过,其已经将该事务更新到了本地,但所有 Follower 还都没有收到 COMMIT 之前, Leader 宕机了,此时,所有 Follower 根本就不知道该 Proposal 的存在。当新的 Leader 选举出来,整个集群进入正常服务状态后,之前挂了的 Leader 主机重新启动并注册成为了 Follower。若那个别人根本不知道的 Proposal 还保留在那个主机,那么其数据就会比其它主机多出了内容,导致整个系统状态的不一致。所以,该 Proposa 应该被丢弃。类似这样应该被丢弃的事务,是不能再次出现在集群中的,应该被清除。
数据模型znode
节点类型
持久节点
持久顺序节点
临时节点: 临时节点只能是叶子节点, 不能创建子节点
临时顺序节点
节点状态
cZxid: Created Zxid,表示当前 znode 被创建时的事务 ID
ctime: Created Time,表示当前 znode 被创建的时间
mZxid: Modified Zxid,表示当前 znode 最后一次被修改时的事务 ID
mtime: Modified Time,表示当前 znode 最后一次被修改时的时间
pZxid: 表示当前 znode 的子节点列表最后一次被修改时的事务 ID。注意,只能是其子节点列表变更了才会引起 pZxid 的变更,子节点内容的修改不会影响 pZxid。
cversion: Children Version,表示子节点的版本号。该版本号用于充当乐观锁。
dataVersion: 表示当前 znode 数据的版本号。该版本号用于充当乐观锁。
aclVersion: 表示当前 znode 的权限 ACL 的版本号。该版本号用于充当乐观锁
ephemeralOwner: 若当前 znode 是持久节点,则其值为 0;若为临时节点,则其值为创建该节点的会话的 SessionID。当会话消失后,会根据 SessionID 来查找与该会话相关的临时节点进行删除
dataLength: 当前 znode 中存放的数据的长度
numChildren: 当前 znode 所包含的子节点的个数
会话:
会话状态
CONNECTING: 在连接 zk 时, 客户端会首先创建一个 zk 对象。 其会首先将提供给客户端的 zk 集群地址打散, 然后再通过轮询方式逐个尝试着连接
CONNECTED: 若客户端与 zk 连接成功, 则会话状态就变为了 connected。 此时会将该连接的一些临时性数据写入到 zk 对象中。
CLOSED: 客户端主动关闭, 或会话超时, 或权限验证失败等, 会话状态就变为了 closed。此时客户端的 zk 对象消失
会话连接超时管理
当客户端向 zk 发出连接请求后,是如何知道是否连接成功的呢?当 zk 接收到某客户端会话连接后,其会向该客户端发送连接成功 ACK。当客户端接收到 ACK 后,就知道自己已经与 zk 建立了连接。若 zk 没有收到连接请求,或客户端没有收到 zk 发送的 ACK 怎么办呢?客户端就需要进行等待,直到发生会话连接超时。然后再进行下一次连接尝试。当然,尝试一直连接不上怎么办?这就依赖于连接时设置的超时重试策略了会话连接超时是由客户端维护的
会话空闲超时管理
分桶策略:将空闲超时时间相近的会话放到同一个桶中来进行管理,以减少管理的复杂度。在检查超时时,只需要检查桶中剩下的会话即可,因为在该桶的时间范围内没有超时的会话已经被移出了桶,而桶中存在的会话就是超时的会话。
分桶依据
会话连接事件
连接丢失
会话转移
会话失效
ACL
简介:ACL 全称为 Access Control List(访问控制列表),是一种细粒度的权限管理策略,可以针对任意用户与组进行细粒度的权限控制。 zk 利用 ACL 控制 znode 节点的访问权限,如节点数据读写、节点创建、节点删除、读取子节点列表、设置节点权限等。
zk的ACL维度:Unix/Linux 系统的 ACL 分为两个维度:组与权限。
授权策略:scheme:授权策略用于确定权限验证过程中使用的检验策略(简单地说就是,通过什么来验证权限,即一个用户要访问某个 znode,如何验证其身份)
IP:根据IP进行权限验证
digest:根据用户名和密码进行验证
world:对所有用户不做任何验证
授权对象id:授权对象指的是权限赋予的用户。不同的授权策略具有不同类型的授权对象。下面是各个授权模式对应的授权对象 id
IP:授权对象是ip地址
digest:授权对象是“用户名 +密码”
world:其授权对象只有一个:anyonoe
super:与digest相同,极权对象是“用户名+密码”
权限Permission:授权策略用于确定权限验证过程中使用的检验策略(简单地说就是,通过什么来验证权限,即一个用户要访问某个 znode,如何验证其身份),在 zk 中最常用的有四种策略
c:create,允许授权对象在当前节点下创建子节点
d:delete,允许授权对象删除当前节点
r:read,允许授权对象读取当前节点的数据内容,及子节点列表
w:write,允许授权对象修改当前节点的数据内容,及子节点列表
a:acl,允许极权对象对当前节点进行acl相关设置
watcher:zk 通过 Watcher 机制实现了发布/订阅模式
watcher 工作原理
watcher 事件:对于同一个事件类型,在不同的通知状态中代表的含义是不同的。
watcher 特性:zk 的 watcher 机制具有以下几个特性。
一次性:一旦一个watcher而被触发,zk就会将其从客户端的watcherManager中删除,服务器端也会删除该watcher。zk的watcher机制不适合监听变化非常频繁的场景
串行性:对同一场景的相同事件类型的watcher回调方法的执行是串行的
轻量级:真正传递给server的是一个简易版的watcher,回调逻辑存放在客户端,没有在服务端。
会话
CONNECTING
CONNECTED
CLOSED
会话连接超时管理
当客户端向 zk 发出连接请求后,是如何知道是否连接成功的呢?当 zk 接收到某客户端会话连接后,其会向该客户端发送连接成功 ACK。当客户端接收到 ACK 后,就知道自己已经与 zk 建立了连接。若 zk 没有收到连接请求,或客户端没有收到 zk 发送的 ACK 怎么办呢?客户端就需要进行等待,直到发生会话连接超时。然后再进行下一次连接尝试。当然,尝试一直连接不上怎么办?这就依赖于连接时设置的超时重试策略了。会话连接超时是由客户端维护的
基本概念
分桶策略是指,将空闲超时时间相近的会话放到同一个桶中来进行管理,以减少管理的复杂度。在检查超时时,只需要检查桶中剩下的会话即可,因为在该桶的时间范围内没有超时的会话已经被移出了桶,而桶中存在的会话就是超时的会话。zk 对于会话空闲的超时管理并非是精确的管理,即并非是一超时马上就执行相关的超时操作。
子主题
现要在计算当前的会话需要存放到哪个会话桶中进行管理。分桶的计算依据为:ExpirationTime= CurrentTime + SessionTimeoutBucketTime = (ExpirationTime/ExpirationInterval + 1) * ExpirationInterval从以上公式可知,一个桶的大小为 ExpirationInterval 时间。只要 ExpirationTime 落入到同一个桶中,系统就会对其中的会话超时进行统一管理。
会话连接事件:客户端与服务端的长连接失效后,客户端将进行重连
Paxos 故事:1、有一个叫做 Paxos 的小岛(Island)上面住了一批居民,岛上面所有的事情由一些特殊的人决定,他们叫做议员(Senator)。2、议员的总数(SenatorCount)是确定的,不能更改。3、岛上每次环境事务的变更都需要通过一个提议(Proposal),每个提议都有一个编号(PID),这个编号是一直增长的,不能倒退。4、每个提议都需要超过半数((SenatorCount)/2+1)的议员同意才能生效。5、每个议员只会同意大于当前编号的提议,包括已生效的和未生效的。6、如果议员收到小于等于当前编号的提议,他会拒绝,并告知对方:你的提议已经有人提过了。这里的当前编号是每个议员在自己记事本上面记录的编号,他不断更新这个编号。整个议会不能保证所有议员记事本上的编号总是相同的。现在议会有一个目标:保证所有的议员对于提议都能达成一致的看法。好,现在议会开始运作,所有议员一开始记事本上面记录的编号都是 0。有一个议员发了一个提议:将电费设定为 1 元/度。他首先看了一下记事本,嗯,当前提议编号是 0,那么我的这个提议的编号就是 1,于是他给所有议员发消息: 1 号提议,设定电费 1 元/度。其他议员收到消息以后查了一下记事本,哦,当前提议编号是 0,这个提议可接受,于是他记录下这个提议并回复:我接受你的 1 号提议,同时他在记事本上记录:当前提议编号为 1。发起提议的议员收到了超过半数的回复,立即给所有人发通知: 1 号提议生效!收到的议员会修改他的记事本,将 1 好提议由记录改成正式的法令,当有人问他电费为多少时,他会查看法令并告诉对方: 1 元/度。现在看冲突的解决:假设总共有三个议员 S1、 S2 与 S3, S1 和 S2 同时发起了一个提议:设定电费,提议编号均为 1。 S1 想设为 1 元/度, S2 想设为 2 元/度。此时 S3 先收到了 S1 的提议,于是他一查记事本,发现提议编号 1 大于当前的编号 0,所以同意了该提议。紧接着他又收到了 S2 的提议,结果他再查记事本,发现这个提议的编号等于当前记录的编号 1,于是他拒绝了这个提议:对不起,这个提议先前提过了。于是 S2 的提议被拒绝, S1 正式发布了提议: 1 号提议生效。 S2 向 S1 或者 S3 打听并更新了 1 号法令的内容,然后他可以选择继续发起 2 号提议。Paxos 对外是如何工作的:情况一:屁民甲(Client)到某个议员(ZKServer)那里询问(Get)某条法令的情况(ZNode 的数据),议员毫不犹豫的拿出他的记事本(localStorage),查阅法令并告诉他结果。情况二:屁民乙(Client)到某个议员(ZKServer)那里要求政府归还欠他的一万元钱,议员让他在办公室等着,自己到议会将这个作为一个提议发给了所有议员。多数议员表示欠屁民的钱一定要还,于是该访问从国库中拿出一万元还债,国库总资产由 100 万变成 99 万。屁民乙拿到钱回去了(Client 函数返回)
高可用集群的容灾
服务器数量的奇数与偶数
前面我们说过,无论是写操作投票,还是 Leader 选举投票,都必须过半才能通过,也就是说若出现超过半数的主机宕机,则投票永远无法通过。基于该理论,由 5 台主机构成的集群,最多只允许 2 台宕机。而由 6 台构成的集群,其最多也只允许 2 台宕机。即, 6 台与5 台的容灾能力是相同的。 基于此容灾能力的原因, 建议使用奇数台主机构成集群,以避免资源浪费。但从系统吞吐量上说, 6 台主机的性能一定是高于 5 台的。所以使用 6 台主机并不是资源浪费
容灾设计方案
对于一个高可用的系统,除了要设置多台主机部署为一个集群避免单点问题外,还需要考虑将集群部署在多个机房、多个楼宇。对于多个机房、楼宇中集群也是不能随意部署的,下面就多个机房的部署进行分析。在多机房部署设计中,要充分考虑“过半原则”,也就是说,尽量要确保 zk 集群中有过半的机器能够正常运行。
三机房部署
在生产环境下,三机房部署是最常见的、容灾性最好的部署方案。三机房部署中要求每个机房中的主机数量必须少于集群总数的一半。
双机房部署
zk 官方没有给出较好的双机房部署的容灾方案。只能是让其中一个机房占有超过半数的主机,使其做为主机房,而另一机房少于半数。当然,若主机房出现问题,则整个集群会瘫痪。
CAP 定理
CAP 定理又称 CAP 原则,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、 Partition tolerance(分区容错性),三者不可兼得。对于分布式系统,网络环境相对是不可控的,出现网络分区是不可避免的,因此系统必须具备分区容错性。但其并不能同时保证一致性与可用性。 CAP 原则对于一个分布式系统来说,只可能满足两项,即要么 CP,要么 AP。
一致性(C):分布式系统中多个主机之间是否能够保持数据一致的特性。即,当系统数据发生更新操作后,各个主机中的数据仍然处于一致的状态。
可用性(A):系统提供的服务是否一直处于可用的状态,即对于用户的每一个请求,系统是否总是可以在有限的时间内对用户做出响应。
分区容错性(P):分布式系统在遇到任何网络分区故障时,仍能够保证对外提供满足一致性和可用性的服务。分区是网络分区。
BASE 理论
BASE 是 Basically Available(基本可用)、 Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的简写。BASE 理论的核心思想是:即使无法做到实时一致性,但每个系统都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
基本可用
基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性。损失响应时间:损失功能:
软状态
软状态,是指允许系统数据存在的中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统主机间进行数据同步的过程存在一定延时。软状态,其实就是一种灰度状态,过渡状态
最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的一致性
总结
从达到一致性的时间角度来划分,可以分为:实时一致性:单机情况下可以实现实时一致性最终一致性:经过一段时间后可以达到一致性
单从客户端访问到的内容角度来划分,可以分为:强一致性(严格一致性):弱一致性:允许客户端访问不到部分或全部更新过的数据。
ZK 与 CP
zk 遵循的是 CP 原则,即保证了一致性,但牺牲了可用性。体现在哪里呢?当 Leader 宕机后, zk 集群会马上进行新的 Leader 的选举。但选举时长一般在 200 毫秒内,最长不超过 60 秒,整个选举期间 zk 集群是不接受客户端的读写操作的,即 zk 集群是处于瘫痪状态的。所以,其不满足可用性
zk 可能会存在脑裂:这里说的 zk 可能会引发脑裂,是指的在多机房部署中,若出现了网络连接问题, 形成多个分区,则可能会出现脑裂问题,可能会导致数据不一致。
情况一
B机房无法对外提供服务,A和C正常运行
情况二
1、会出现短暂脑裂,且有可能会出现短暂的数据不一致情况2、很快A机房不发对外提供服务,但B与C会选举出新的Leader并正常运行
情况三
A会对外提供短暂的服务,很快三机房均无法对外提供服务
情况四
B无法对外提供服务,但A和C都可以正常运行
情况五
整个集群都可以对外提供服务,不受影响
收藏
收藏
0 条评论
回复 删除
下一页