Zookeeper

Zookeeper

1. 简介

😄 最初了解它是在研究生期间,搭建过Hadoop集群,它用于为分布式集群提供一致性服务。它的核心是:类似树形文件系统、通知机制。

下面先介绍几个小概念。

1.1. 节点类型

节点类型从两个维度可以划分为4种,分别是:临时/持久,有序/无序

  • 持久节点:(默认创建的就是持久节点)该数据节点被创建后,就会一直存在于zookeeper服务器上,直到有删除操作来主动删除这个节点。

  • 临时节点:临时节点的生命周期和客户端会话绑定在一起,客户端会话session失效,则这个节点就会被自动清除

  • 有序:(额外的特性)在ZK中,每个父节点会为它的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序(即,节点名后边会追加一个由父节点维护的自增整型数字)。基于这个特性,在创建子节点的时候,可以设置这个属性,那么在创建节点过程中,ZK会自动为给定节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。

☕️ 说明:这4中节点一定要深入理解,后面的分布式锁会使用到!

1.2. 角色类型

客户端:client,开发时,我们使用的就是客户端,向服务端发送MDL请求

服务端:包含3个角色,分别是leader、follower、observer

  • leader:集群必须有领导者,才能提供服务;它用于处理事务事件(更新写)

  • follower:同步leader数据到自己节点,提供非事务事件(读);参与投票选主

  • observer:与follower一样,唯一的不同是不参与投票选主,它的出现是为了提高集群读性能

2. 应用场景

2.1. 统一命名服务
2.2. 统一配置文件

集群中所有的节点都共享的配置信息,该配置文件会改变(如,集群各个节点的状态信息)。实现思路:在ZK上创建配置信息节点,并让各个主机监控节点事件;当节点配置信息发生修改时,会触发回调函数,所有的节点同步更新信息。

2.3. 节点上下线监控

采用临时节点特性。实现思路:节点上线时,与ZK建立连接并创建临时节点;当节点下线时,连接会断开,此时临时节点会被自动释放。

2.4. 发布订阅模式

采用经典的观察者模式,与Redis/ZeroMq的发布订阅模式原理类似。实现思路与2.2中的很像,2.4中的临时节点+分布式锁也应用到

2.5. ZK分布式锁

客户端加锁成功条件:客户端A创建了zknode,那么,锁就被客户端持有。

2.5.1. 持久节点

将zookeeper上的一个znode看作是一把锁,通过create_znode的方式来实现加锁,即:所有客户端都只创建 /distribute_lock节点,最先成功创建该节点的那个客户端就会拥有了这把锁。(再次期间,别的客户端想加锁,就会失败)。

客户端处理完后,要删除掉自己创建的/distribute_lock节点,即释放出锁。(之后,其他客户端可以加锁了)

🐤 使用套路

client_uuid = zk.lock();   // 加锁时,返回uuid
zk.unlock(client_uuid);    // 解锁时,通过该client_uuid判断,防止解开别的client的锁,造成锁失效
2.5.2. 持久有序节点

初始时,ZK上目录/distribute_lock已经预先存在,所有客户端在它下面创建一堆持久节点,它们是有序的;

🉑 为了避免“羊群”,每个节点都只会监控第一个比它大的节点。

编号最小的会获得锁,处理完业务逻辑后,删除节点(相当于解锁)。此时,会触发监听该节点的,触发回调函数,即下一个编号较小的节点会加锁失败。

3. ZAB一致性协议

🎃 Zookeeper中的过半原则

  • 选举票数过半的主机,成为master

  • 两阶段,follower执行事务成功的ACK次数过半,leader才会下发Commit信号

  • 集群存活主机数,必须过半,才能提供服务

ZAB一致性协议,主要包含两个方面,分别是:

  • 选举阶段

  • 数据同步阶段

3.1. 选举阶段
3.1.1. 选举发生场景

①集群刚启动时 ②leader宕机 ③follower下线,使得leader的follower数不过半

3.1.2. 选举竞争原则

👹 选谁的核心原则:就是谁最新,就选谁。

先介绍几个概念:epoch、ZXID、myid

  • epoch:译为“时代/纪元”。每个次leader在变更/切换时,epoch都会+1,标志一个leader所处的版本

  • ZXID:事务ID,ZK上的节点变化时,都是客户端发了事务操作导致的,对每一个事务操作,都用ZXID记录,每次发生事务,ZXID就+1

  • myid:服务端的配置信息,里面记录了各个ZK server的序号,一般,序号越大的server,越晚加入集群,它是最新的

    cd /tmp/zookeeper
    mkdir {zoo1,zoo2,zoo3}
    echo 1 > zoo1/myid
    echo 2 > zoo2/myid
    echo 3 > zoo3/myid

🍲 选举原则

  • 先选择epoch最大的

  • epoch相等时,选择ZXID最大的

  • epoch、ZXID相等时,选择myid最大的

3.1.3. 选举过程
  1. 生成选票:每个ZK server都采用上面的选举原则进行投票,一般都是先选择自己

  2. 更新选票:然后将自己的选票与其他ZK server交换,通过选举原则更新选票

  3. 确立leader:在更新过程中,如果发现某个ZK server的选票数过半,则该ZK server就成为leader

3.2. 数据同步阶段与2PC

数据同步采用的是一致性协议2PC,过程如下

  1. leader向follower发送事务执行指令,等待follower执行事务

  2. leader收集follower执行结果(follower将返回是否执行成功的标记):如果半数follower执行成功,leader就会发送commit事务的指令

😃 一些小小的知识点

  • follower执行成功,返回ACK的条件

    答:当follower写完事务日志后,将认为数据已经同步好了,就直接返回执行成功的ACK,无需等待所有数据都落盘


4. 深入思考

4.1. Zookeeper集群节点为什么要部署成奇数? (容错率)

节省资源,过半原则,5个机器,(过半,3)只允许挂2个机器;6个机器(过半,4),也只允许挂掉2个机器。因为5个机器和6个机器的分区容错性一致,所以,选奇数。

4.2. Zookeeper过半机制中为什么是大于,而不是大于等于?(脑裂)

答:防止脑裂 原因:两个机房通过一根网线相连接,每个机房6个主机,当断网后,各个机房主机都存活(符合半数存活,ZK可用原则),两个主机会各自选出leader,此时集群会出现双主,发生脑裂

4.3. 集群最少要几台机器,集群规则是怎样的?

2N+1 = 3

4.4. Zookeeper对节点的watch监听通知是永久的吗?为什么不是永久的?

官方声明:一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,该事件将不会继续被监听。 为什么不是永久的,举个例子,如果服务端变动频繁,而监听的客户端很多情况下,每次变动都要通知到所有的客户端,给网络和服务器造成很大压力。

4.5. 集群中为什么要有主节点?

读写分离特性,即:在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能,于是就需要进行 leader 选举。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值