-
CAP 理论是什么?
- C : Consistency 一致性,数据在多个副本之间似否能够保持一致的特性。
- A: Availability 可用性,系统服务必须一直处于可用状态,对每个请求总是在指定的时间返回结果。
- P:Partition tolerance 分区容错性,遇到分区网络故障时,仍能对外提供一致性和可用性的服务。
-
BASE 理论?
- 基本可用:系统出现不可预知的故障时,允许损失部分可用性。
- 弱(软)状态:数据的中间状态,并认为改状态存在不会一项系统整体可用性,允许不同节点数据副本数据同步过程中的延时。
- 最终一致性:系统中所有数据副本,在一段时间的同步后,最终数据能够到一致性的状态。
-
zookeeper提供了什么?
-
文件系统
Zookeeper提供一个多层级的节点命名空间(节点称为znode)。与文件系统不同的是,这些节点都可以设置关联的数据,而文件系统中只有文件节点可以存放数据而目录节点不行。Zookeeper为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构,这种特性使得Zookeeper不能用于存放大量的数据,每个节点的存放数据上限为1M。
-
PERSISTENT-持久化目录节点
客户端与zookeeper断开连接后,该节点依旧存在
-
PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
-
EPHEMERAL-临时目录节点
客户端与zookeeper断开连接后,该节点被删除
-
EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
-
-
通知机制
client端会对某个znode建立一个watcher事件,当该znode发生变化时,这些client会收到zk的通知,然后client可以根据znode变化来做出业务上的改变等。
-
-
Zookeeper做了什么?
-
命名服务(文件系统)
命名服务是指通过指定的名字来获取资源或者服务的地址,利用zk创建一个全局的路径,即是唯一的路径,这个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。
-
配置管理(文件系统、通知机制)
程序分布式的部署在不同的机器上,将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时,可以通过改变zk中某个目录节点的内容,利用watcher通知给各个客户端,从而更改配置。
-
集群管理(文件系统、通知机制)
- 是否有机器退出和加入:所有机器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个节点被删除
- 选举master:所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好
-
-
分布式锁(文件系统、通知机制)
-
zookeeper分布式锁实现原理
-
zookeeper 节点的特性来实现独占锁,
就是同级节点的唯一性,多个进程往 zookeeper 的指定节点下创建一个相同名称的节点,只有一个能成功,另外一个是创建失败;创建失败的节点全部通过 zookeeper 的 watcher 机制来监听 zookeeper 这个子节点的变化,一旦监听到子节点的删除事件,则再次触发所有进程去写锁。这种方式会产生惊群效应,当成功获取到锁的进程释放该节点后,所有处于等待状态的客户端都会被唤醒,这个时候 zookeeper 在短时间内发送大量子节点变更事件给所有待获取锁的客户端,然后实际情况是只会有一个客户端获得锁。如果在集群规模比较大的情况下,会对zookeeper 服务器的性能产生比较的影响。
-
有序节点来实现分布式锁
- 每个客户端都往指定的节点下注册一个临时有序节点,越早创建的节点,节点的顺序编号就越小,那么我们可以判断子节点中最小的节点设置为获得锁。如果自己的节点不是所有子节点中最小的,意味着还没有获得锁。这个的实现和前面单节点实现的差异性在于,每个节点只需要监听比自己小的节点,当比自己小的节点删除以后,客户端会收到 watcher 事件,此时再次判断自己的节点是不是所有子节点中最小的,如
果是则获得锁,否则就不断重复这个过程,这样就不会导致羊群效应,因为每个客户端只需要监控一个节点。
- 每个客户端都往指定的节点下注册一个临时有序节点,越早创建的节点,节点的顺序编号就越小,那么我们可以判断子节点中最小的节点设置为获得锁。如果自己的节点不是所有子节点中最小的,意味着还没有获得锁。这个的实现和前面单节点实现的差异性在于,每个节点只需要监听比自己小的节点,当比自己小的节点删除以后,客户端会收到 watcher 事件,此时再次判断自己的节点是不是所有子节点中最小的,如
-
curator 对于锁这块做了一些封装,curator 提供了InterProcessMutex 这样一个 api。除了分布式锁之外,还提供了 leader 选举、分布式队列等常用的功能。
- InterProcessMutex:分布式可重入排它锁
- InterProcessSemaphoreMutex:分布式排它锁
- InterProcessReadWriteLock:分布式读写锁
-
-
-
队列管理(文件系统、通知机制)
两种类型的队列:
- 同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。
- 队列按照 FIFO 方式进行入队和出队操作。和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。在特定的目录下创建PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点,创建成功时Watcher通知等待的队列,队列删除序列号最小的节点用以消费。此场景下Zookeeper的znode用于消息存储,znode存储的数据就是消息队列中的消息内容,SEQUENTIAL序列号就是消息的编号,按序取出即可。由于创建的节点是持久化的,所以不必担心队列消息的丢失问题。
-
zookeeper主要是用来解决什么问题的?
主要解决的是分布式协调的问题
- 防止单点故障
- 集群中要有主节点和从节点———1. 保证集群事物处理的顺序性 2.集群内部各服务器的调度者
- 集群要能做到数据同步,当主节点出现故障时,从节点能够顶替主节点继续工作,但是继续工作的前提是数据必须要主节点保持一致
- 主节点挂了以后,自动选举
- 防止单点故障
-
Zookeeper工作原理?
Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态
leader 节点可以处理事务请求和非事务请求,follower 节点只能处理非事务请求,如果 follower节点接收到非事务请求,会把这个请求转发给 Leader 服务器
-
消息广播实现原理?
消息广播的过程实际上是一个简化版本的二阶段提交(2pc)过程。
- leader 接收到消息请求后,将消息赋予一个全局唯一的64 位自增 id,叫:zxid,通过zxid 的大小比较既可以实现因果有序这个特征
- leader 为每个 follower 准备了一个 FIFO 队列(通过 TCP协议来实现,以实现了全局有序这一个特点)将带有 zxid的消息作为一个提案(proposal)分发给所有的 follower
- 当 follower 接收到 proposal,先把 proposal 写到磁盘,写入成功以后再向 leader 回复一个 ack
- 当 leader 接收到合法数量(超过半数节点)的 ACK 后,leader 就会向这些 follower 发送commit 命令,同时会在本地执行该消息
- 当 follower 收到消息的 commit 命令以后,会提交该消息
和完整的 2pc 事务不一样的地方在于,zab 协议不能终止事务,follower 节点要么 ACK 给leader,要么抛弃leader,只需要保证过半数的节点响应这个消息并提交了即可,虽然在某一个时刻 follower 节点和 leader 节点的状态会不一致,但是也是这个特性提升了集群的整体性能。 当然这种数据不一致的问题,zab 协议提供了一种恢复模式来进行数据恢复。
-
崩溃恢复的实现原理?
是一旦 Leader 节点崩溃,或者由于网络问题导致 Leader 服务器失去了过半的 Follower 节点的联系(leader 失去与过半 follower 节点联系,可能是leader 节点和 follower 节点之间产生了网络分区,那么此时的 leader 不再是合法的 leader 了),那么就会进入到崩溃恢复模式。崩溃恢复状态下 zab 协议需要做两件事
- 选举出新的 leader
- 数据同步
-
枚举算法应该满足什么需求?
-
已经被处理的消息不能丢
当 leader 收到合法数量 follower 的 ACKs 后,就向各个 follower 广播 COMMIT 命令,同时也会在本地执行COMMIT 并向连接的客户端返回「成功」。但是如果在各个 follower 在收到COMMIT 命令前 leader 就挂了,导致剩下的服务器并没有执行都这条消息。
ZAB 协议就需要确保事务Proposal2最终能够在所有的服务器上都能被提交成功,否则将会出现不一致
-
被丢弃的消息不能再次出现
当 leader接收到消息请求生成proposal后就挂了,其他follower并没有收到此proposal,因此经过恢复模式重新选了 leader后,这条消息是被跳过的。此时,之前挂了的leader 重新启动并注册成了follower,他保留了被跳过消息的proposal状态,与整个系统的状态是不一致的,需要将其删除。
zxid:事务 id,为了保证事务的顺序一致性,zookeeper 采用了递增的事务 id 号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了 zxid。实现中 zxid 是一个 64 位的数字,它高 32 位是 epoch(ZAB 协议通过 epoch 编号来区分 Leader 周期变化的策略)用来标识 leader 关系是否改变,每次一个 leader 被选出来,它都会有一个新的epoch=(原来的 epoch+1),标识当前属于那个 leader 的统治时期。低 32 位用于递增计数。
epoch:可以理解为当前集群所处的年代或者周期,每个leader 就像皇帝,都有自己的年号,所以每次改朝换代,leader 变更之后,都会在前一个年代的基础上加1。这样就算旧的 leader 崩溃恢复之后,也没有人听他的了,因为 follower 只听从当前年代的 leader 的命令。
- 如果 leader 选举算法能够保证新选举出来的 Leader 服务器拥有集群中所有机器最高编号(ZXID 最大)的事务Proposal,那么就可以保证这个新选举出来的 Leader 一定具有已经提交的提案。因为所有提案被 COMMIT 之前必须有超过半数的 follower ACK,即必须有超过半数节点的服务器的事务日志上有该提案的 proposal,因此,只要有合法数量的节点正常工作,就必然有一个节点保存了所有被 COMMIT 消息的 proposal 状态
- zxid 是 64 位,高 32 位是 epoch 编号,每经过一次 Leader 选举产生一个新的 leader,新的 leader会将 epoch 号+1,低 32 位是消息计数器,每接收到一条消息这个值+1,新 leader 选举后这个值重置为 0.这样设计的好处在于老的 leader 挂了以后重启,它不会被选举为 leader,因此此时它的 zxid 肯定小于当前新的leader。当老的 leader 作为 follower 接入新的 leader后,新的 leader 会让它将所有的拥有旧的 epoch 号的未被 COMMIT 的 proposal 清除
-
-
-
Zookeeper 下 Server工作状态?
- LOOKING:当前Server不知道leader是谁,正在搜寻
- LEADING:当前Server即为选举出来的leader
- FOLLOWING:leader已经选举出来,当前Server与之同步
-
zookeeper是选取主leader的具体流程?
-
Zookeeper选主流程(basic paxos)
- 当前Server发起选举的线程作为选举线程,负责统计投票结果。
- 选举线程对所有server包括自己发起询问
- 选举收到回复,验证zxid是否一致,记录回复id、zxid
- 计算出所有zxid中最大的一个成为下一次投票的server,zxid最大的成为推荐leader,如果获得n/2+1票,则成为leader。
-
Zookeeper选主流程fast paxos(zookeeper默认使用的算法)
某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。
-
-
Zookeeper同步流程
选完Leader以后,zk就进入状态同步过程。
- Leader等待server连接;
- Follower连接leader,将最大的zxid发送给leader;
- Leader根据follower的zxid确定同步点;
- 完成同步后通知follower 已经成为uptodate状态;
- Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。
-
zk节点宕机如何处理?
zk本身也是集群的,如果集群挂了也会发起选举。
-
zookeeper watch机制
一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。
网友评论