Zookeeper相关知识

ZooKeeper 的定义

总的来说,Zookeeper 是一个开源的分布式的,为分布式应用提供协调服务的 Apache 项目。具体来说,Zookeeper是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生了变化,Zookeeper 就负责通知已经在 Zookeeper 上注册的那些观察者做出相应的反应。

Zookeeper = 文件系统 + 通知机制。

Zookeeper的数据模型

ZooKeeper 的特点


(1)Zookeeper是由一个领导者(Leader)和多个跟随者(Follower)组成的集群。

(2)集群中只要有半数以上节点存活,Zookeeper 集群就能正常服务。

(3)全局数据一致性:每个 Server 保存一份相同的数据副本,Client 无论连接到哪个 server,数据都是一致的。

(4)更新请求 顺序性 ,来自同一个 Client 的更新请求按其发送顺序依次执行。

(5)数据更新原子性,一次数据更新要么成功,要么失败(保证了数据一致性)。

(6)实时性,在一定时间范围内,Client 能读到最新数据。

Zookeeper的分布式锁

ZooKeeper 的应用场景


(1)统一命名服务:在分布式环境下,经常需要对服务进行统一命名,便于识别,例如 ip 地址。

(2)统一配置管理:在一个集群中,要求所有节点的配置信息是一致的

(3)统一集群管理:在一个集群中,需要实时监控每个节点的状态变化

(4)负载均衡:在Zookeeper中记录每个服务器的访问次数,再次请求的时候,让访问次数最少得服务器去处理当前的请求。

你觉得Zookeeper比较重要的功能
ZooKeeper最重要的功能之一是提供分布式系统的协调和管理服务,它能够协调分布式系统中各个节点的状态,维护分布式系统的配置信息,帮助分布式系统实现同步和通信。

Zookeeper 的选举策略,leader 和 follower 的区别?


选举机制总原则:集群中的每台机器都参与投票,通过交换选票信息得到每台机器的最终得票, 一旦出现得票数超过机器总数 一半以上 数量,当前机器即为 leader。

在 zk 集群启动时候,需要确定一台 leader 服务器。首先确保集群之间可以相互通信

第一次选举:

假如集群有五台服务器:

服务器 1 启动时候,会投自己一票,此时不满半数,服务器 1 保持为 looking

服务器 2 启动时候,服务器 1 和服务器 2 交换信息,但服务器 1 发现服务器 2 的myid 比自己大,所以将自己的票投给服务器 2,此时服务器 1 有 0 票,服务器 2有两票,不满半数,都为 looking

服务器 3 启动时候,重复上述步骤,拥有 3 个选票,超过半数,当选为 leader,此时其他服务器状态为 following

第二次选举:

当集群中的 leader 挂掉之后,其他所有节点会把自己的状态设置为 looking,此时的选举规则为①EPOCH 大的直接胜出,②:EPOCH 相同,事务 id 大的胜出,

③:事务 id 相同,服务器 id 大的胜出

SID:服务器 ID。用来唯一标识一台 ZooKeeper 集群中的机器,每台机器不能重复,和 myid 一致。

ZXID:事务 ID。ZXID 是一个事务 ID,用来标识一次服务器状态的变更。在某一时

刻,集群中的每台机器的 ZXID 值不一定完全一致,这和 ZooKeeper 服务器对于客户端“更新请求”的处理逻辑有关。

Epoch:每个 Leader 任期的代号。没有 Leader 时同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加

Zookeeper 的节点类型有哪些?分别作用是什么?

持久节点类型:节点在创建后,一直存在,直到主动来删除这个节点,不会因为客户端会话失效而消失

持久顺序节点:和持久节点类似,

临时节点:临时节点的生命周期和客户端会话绑定,如果客户端会话失效,该节点消失

zookeeper主节点故障,如何重新选举?


当集群中的leader挂掉,集群会重新选出一个leader,此时首先会比较每一台机器的epoch,epoch大的直接选举为leader,epoch若是相同就比较每一台机器的事务id(zxid),zxid 最大的被选为 leader。极端情况,zxid 都相等的情况,那么就会直接比较服务器id(myid、sid)。

在 Zookeeper 集群中,epoch 是用来标识 Zookeeper 集群中的逻辑时期(epoch)。每当选举出一个新的 Leader 时,Zookeeper 集群的 epoch 就会增加,以标识当前的 Leader 任期。

ZooKeeper 的监听原理 ***


(1)首先要有一个 main() 线程

(2)在 main() 线程中创建 ZooKeeper 客户端,这时就会创建两个线程,一个负责网络连接通信(connet),一个负责监听(listener)

(3)客户端通过 connet 线程将注册的监听事件发送给服务端

(4)在 ZooKeeper 的注册监听器列表中将注册的监听事件添加到列表中

(5)ZooKeeper 监听到有数据或路径的变化,就会将这个消息发送给 listener 线程

(6) 客户端 listener 线程内部调用 process() 方法做出相应处理

Zookeeper分布式锁原理

zookeeper集群的节点数为什么建议奇数台 ***


(1)因为 zookeeper 中只要有半数以上的机器正常工作,那么整个集群对外就是可用的。比如说如果有 2 个 zookeeper,那么只要 1 个死了 zookeeper 就不能用了,因为 1没有过半,那么 zookeeper 的死亡容忍度为 0,同理,如果有 3 个 zookeeper,如果死了 1个,还剩2个
正常,还是过半的,所以 zookeeper 的死亡容忍度为 1,我之前算过 4 个5 个 6 个等情况下的死亡容忍度,发现了一个规律,2n 和 2n-1 的容忍度是一样的,所以为了节约资源,就选择奇数台。

(2)防止因为集群脑裂造成集群用不了。比如有 4 个节点,脑裂为 2 个小集群,都为 2 个节点,这时候,不能满足半数以上的机器正常工作,因此集群就不可用了,那么当有 5 个节点的时候,脑裂为 2 个小集群,分别为2和 3,这时候 3 这个小集群仍然可以选举出 leader,因此集群还是可用的。

ZooKeeper 的部署方式有哪几种?集群中的角色有哪些?集群最少需要几台机器?规则是怎样的?


(1)部署方式

单机模式:将Zookeeper运行在单台机器上,仅供学习和开发使用;
集群模式:zookeeper运行在多台机器上,每台机器上都运行一个zookeeper实例;
伪分布式模式:仍然只有一台物理机器,但是该机器运行了多个Zookeeper实例。
(2)zookeeper有三种角色:

老大Leader(领导者)
老二Follower (跟随者)
老三Observer(观察者)。Observer 接受客户端连接,将写操作转给Leader,但Observer不参与投票(即不参加一致性协议的达成),只同步Leader节点的状态,Observer角色是为集群系统扩展而生的。Follower和Observer归类为Learner(学习者)


(3)集群最少需要机器数:3,集群规则为2N+1台,N>0

ZooKeeper 的常用命令


(1) ls:查看当前 znode 的子节点

(2)create:创建节点

(3)set:设置节点的值

(4) get:获取节点的值

(5) stat:查看节点的状态

(6) delete:删除节点

(7) deleteall:递归删除节点

Zookeeper目录结构


ZooKeeper的目录结构采用类似Unix文件系统的树形结构。ZooKeeper 目录结构由 ZNode 组成,每个ZNode 默认情况下最多可以存储 1MB 的数据。ZNode是ZooKeeper中的基本数据单元,可以用于存储配置信息、状态信息等。

ZooKeeper目录结构的根节点为/,所有的ZNode都是以根节点为基础进行构建的。每个ZNode的名称是唯一的,并且可以包含多个子节点,每个子节点都是一个独立的ZNode。ZNode可以是永久节点,也可以是临时节点。

在ZooKeeper目录结构中,常用的ZNode包括:

/zookeeper:ZooKeeper的内部节点,用于存储ZooKeeper的配置信息和状态信息。
/brokers:Kafka集群中所有的Broker信息存储在该节点下。
/controller:Kafka集群中Controller的状态信息存储在该节点下。
/consumers:Kafka中所有的消费者组信息存储在该节点下。
/config:Kafka集群的配置信息存储在该节点下。
/admin:Kafka中所有的管理员操作信息存储在该节点下。
简述什么是CAP理论,zookeeper满足CAP的哪两个 ***
分布式系统有三个指标:

Consistency(一致性)
用户在访问分布式系统中的任意节点,得到的数据必须一致。


Availability(可用性)
用户访问集群中任意的健康节点,必须能得到响应,而不是超时或拒绝。


Paratition tolerance(分区容错性)
分区:因为网络故障或其他原因导致分布式系统中的部分节点与其他节点失去连接,形成独立的分区。
容错:在集群出现分区时,整个系统也要持续对外提供服务。
分布式系统无法同时满足这三个指标,这个结论就是 CAP 理论。


Zookeeper 符合一致性、分区容错性。(CP)

Paxos 算法 ***


Paxos 算法:一种基于消息传递且具有高度容错性的一致性算法。

Paxos 算法解决的问题:如何快速正确的在一个分布式系统中对某个数据的值达成一致,并且保证不论发生任何异常,都不会破坏整个系统的一致性。

在一个 Paxos 系统中,首先将所有的节点划分为Proposer(提议者)、Accepter(接受者)和 Learner(学习者)。(注意每个节点都可以身兼数职)

一个完整的 Paxos 算法流程分为三个阶段:

准备阶段
Proposer 向多个 Accepter 发出 Propose 请求Promise(承诺)
Accepter 针对收到的Propose请求进行Promise(承诺)
接受阶段
Proposer 收到多个Accepter的Promise(承诺)后,向Accepter发出Propose
Accepter 针对收到的Propose请求进行Accept处理
学习阶段
Proposer将形成的决议发送给所有的 Learner


ZAB协议/Zookeeper怎么保证一致性的 ***


依赖了 ZAB 协议,ZAB 协议借鉴了 Paxos 算法,是专门为 ZooKeeper 设计的支持崩溃恢复的原子广播协议。Paxos 算法中采用多个Proposer 会存在竞争 Acceptor 的问题,ZooKeeper 设计为只有一个 Leader 负责处理外部的写事务请求,然后 Leader 将数据同步到其他 Follower 节点。即,ZooKeeper 只有一个 Leader 可以发起提议。

ZAB 协议包括两种基本的模式:消息广播(正常)、崩溃恢复(异常)。

这两个模式是相辅相成的,消息广播模式就是 Zookeeper 不出现任何问题,并且正常工作的模式,崩溃恢复看字面意思就是当 Zookeeper 出现故障时用于恢复的。

(1)消息广播

(2)崩溃恢复


ZooKeeper 使用的ZAB协议与Paxo算法的异同?


相同点:

两者都存在一个类似于 Leader 进程的角色,由其负责协调多个 Follower 进程的运行
Leader 进程都会等待超过半数的 Follower 做出正确的反馈后,才会将一个提案进行提交
ZAB 协议中,每个 Proposal 中都包含一个 epoch 值来代表当前的 Leader 周期,Paxos 中名字为 Ballot
不同点:

ZAB(ZooKeeper Atomic Broadcast) 用来构建高可用的分布式数据主备系统(Zookeeper),Paxos 是用来构建分布式一致性状态机系统。而 Paxos 算法与 ZAB 协议不同的是,Paxos 算法的发起者可以是一个或多个。当集群中的 Acceptor 服务器中的大多数可以执行会话请求后,提议者服务器只负责发送提交指令,事务的执行实际发生在 Acceptor 服务器。这与 ZooKeeper 服务器上事务的执行发生在 Leader 服务器上不同。Paxos 算法在数据同步阶段,是多台 Acceptor 服务器作为数据源同步给集群中的多台 Learner 服务器,而 ZooKeeper 则是单台 Leader 服务器作为数据源同步给集群中的其他角色服务器。

注意:ZAB是在Paxos的基础上改进和演变过来的。

分布式集群中为什么会有主节点
在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能,于是就需要主节点。

节点挂掉的时候Zookeeper是如何发现的?
ZooKeeper提供了一种心跳机制,即每个节点都会定期向其他节点发送心跳消息,如果一个节点超过一定时间没有收到其他节点的心跳消息,就会判定这个节点已经下线了。

Leader一旦选出,如何让集群中所有Follow获悉
心跳机制

Zookeeper下 服务器的工作状态有几种
ZooKeeper 服务器有四种工作状态:

LOOKING:寻找 Leader 状态。当服务器处于该状态时,它会认为当前服务器没有 Leader,因此需要进入 Leader 选举状态。
FOLLOWING:跟随者状态。表明当前服务器角色是 Follower。
LEADING:领导者状态。表明当前服务器角色是 Leader。

ZK 中的脑裂问题

主要原因是Zookeeper集群和Zookeeper client判断超时并不能做到完全同步,也就是说可能一前一后,如果是集群先于client发现,那就会出现上面的情况。同时,在发现并切换后通知各个客户端也有先后快慢。一般出现这种情况的几率很小,需要leader节点与Zookeeper集群网络断开,但是与其他集群角色之间的网络没有问题,还要满足上面那些情况,但是一旦出现就会引起很严重的后果,数据不一致。
 

Zookeeper 脑裂解决方案:


要解决Split-Brain脑裂的问题,一般有下面几种种方法: Quorums (法定人数) 方式: 比如3个节点的集群,Quorums = 2, 也就是说集群可以容忍1个节点失效,这时候还能选举出1个lead,集群还可用。比如4个节点的集群,它的Quorums = 3,Quorums要超过3,相当于集群的容忍度还是1,如果2个节点失效,那么整个集群还是无效的。这是zookeeper防止"脑裂"默认采用的方法。

采用Redundant communications (冗余通信)方式:集群中采用多种通信方式,防止一种通信方式失效导致集群中的节点无法通信。

Fencing (共享资源) 方式:比如能看到共享资源就表示在集群中,能够获得共享资源的锁的就是Leader,看不到共享资源的,就不在集群中。

要想避免zookeeper"脑裂"情况其实也很简单,在follower节点切换的时候不在检查到老的leader节点出现问题后马上切换,而是在休眠一段足够的时间,确保老的leader已经获知变更并且做了相关的shutdown清理工作了然后再注册成为master就能避免这类问题了,这个休眠时间一般定义为与zookeeper定义的超时时间就够了,但是这段时间内系统可能是不可用的,但是相对于数据不一致的后果来说还是值得的。

1: zooKeeper默认采用了Quorums 这种方式来防止"脑裂"现象。即只有集群中超过半数节点投票才能选举出Leader。这样的方式可以确保leader的唯一性,要么选出唯一的一个leader,要么选举失败。在zookeeper中Quorums作用如下:

集群中最少的节点数用来选举leader保证集群可用。
通知客户端数据已经安全保存前集群中最少数量的节点数已经保存了该数据。一旦这些节点保存了该数据,客户端将被通知已经安全保存了,可以继续其他任务。而集群中剩余的节点将会最终也保存了该数据。
假设某个leader假死,其余的followers选举出了一个新的leader。这时,旧的leader复活并且仍然认为自己是leader,这个时候它向其他followers发出写请求也是会被拒绝的。因为每当新leader产生时,会生成一个epoch标号(标识当前属于那个leader的统治时期),这个epoch是递增的,followers如果确认了新的leader存在,知道其epoch,就会拒绝epoch小于现任leader epoch的所
有请求。那有没有follower不知道新的leader存在呢,有可能,但肯定不是大多数,否则新leader无法产生。Zookeeper的写也遵循quorum机制,因此,得不到大多数支持的写是无效的,旧leader即使各种认为自己是leader,依然没有什么作用。

zookeeper除了可以采用上面默认的Quorums方式来避免出现"脑裂",还可以可采用下面的预防措施:

2: 添加冗余的心跳线,例如双线条线,尽量减少“裂脑”发生机会。

3: 启用磁盘锁。 正在服务一方锁住共享磁盘,“裂脑"发生时,让对方完全"抢不走"共享磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的一方不主动"解锁”,另一方就永远得不到共享磁盘。现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。于是有人在HA中设计了"智能"锁。即正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁。平时就不上锁了。

4: 设置仲裁机制。 例如设置参考IP(如网关IP),当心跳线完全断开时,2个节点都各自ping一下 参考IP,不通则表明断点就出在本端,不仅"心跳"、还兼对外"服务"的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够ping通参考IP的一端去起服务。更保险一些,ping不通参考IP的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。
 

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值