hadoop生态圈面试精华之zookeeper(二)

hadoop生态圈面试精华之zookeeper(二)

47.8 Watch机制简介
ZooKeeper 提供了分布式数据发布/订阅功能,一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅 者,使他们能够做出相应的处理。
在 ZooKeeper 中,引入了 Watch 机制来实现这种分布式的通知功能。
ZooKeeper 允许客户端向服务端注册一个 Watch 监听,当服务端的一些事件触发了这个 Watch ,那么就会向指定客户端发送一个事件通知,来实现分布式的通知功能。

47.9 ZooKeeper的Watch架构
Watch的整体流程如下图所示,客户端先向ZooKeeper服务端成功注册想要监听的节点状态,同时客户端 本地会存储该监听器相关的信息在WatchManager中,当ZooKeeper服务端监听的数据状态发生变化时, ZooKeeper就会主动通知发送相应事件信息给相关会话客户端,客户端就会在本地响应式的回调相关Watcher的Handler。
在这里插入图片描述
47.10 Watch机制的特点一次性触发
当Watch 的对象发生改变时,将会触发此对象上Watch 所对应的事件,这种监听是一次性的,后续再次发生同样的事件,也不会再次触发。
事件封装
ZooKeeper 使用WatchedEvent 对象来封装服务端事件并传递。该对象包含了每个事件的 3 个基本属性,即通知状态( keeperState )、事件类型( EventType )和节点路径( path )。
异步发送
Watch 的通知事件是从服务端异步发送到客户端的
先注册再触发
ZooKeeper 中的Watch 机制,必须由客户端先去服务端注册监听,这样才会触发事件的监听,并通知给客户端。
47.11 Watch 机制的通知状态和事件类型
同一个事件类型在不同的连接状态中代表的含义有所不同,下表列举了常见的连接状态和事件类型
连接状态 状态含义 事件类型 事件含义
Disconnected 连接失败 NodeCreated 节点被创建
SyncConnected 连接成功 NodeDataChanged 节点数据变更
AuthFailed 认证失败 NodeChildrenChanged 子节点数据变更
Expired 会话过期 NodeDeleted 节点被删除
从表可知, ZooKeeper 常见的连接状态和事件类型分别有 4 种,具体含义如下。
状态
当客户端断开连接,这时客户端和服务器的连接就是Disconnected 状态,说明连接失败;
当客户端和服务器的某一个节点建立连接,并完成一次version 、 zxid 的同步,这时客户端和服务器的连接状态就是SyncConnected ,说明连接成功;
当ZooKeeper 客户端连接认证失败,这时客户端和服务器的连接状态就是AuthFailed ,说明认证失败;
当客户端发送Request 请求,通知服务器其上一个发送心跳的时间,服务器收到这个请求后,通知客户端下ー个发送心跳的时间是哪个时间点。当客户端时间戳达到最后一个发送心跳的时间,而没 有收到服务器发来的新发送心跳的时间,即认为自己下线,这时客户端和服务器的连接状态就是Expired 状态,说明会话过期。
事件
当节点被创建时,NodeCreated 事件被触发;
当节点的数据发生变更时,NodeDataChanged 事件被触发;
当节点的直接子节点被创建、被删除、子节点数据发生变更时,NodeChildrenChanged 事件被触发; 当节点被删除时,NodeDeleted 事件被触发。

介绍下Zookeeper消息的发布订阅功能
问过的一些公司:字节参考答案:

1、发布订阅基本概念
发布订阅模式可以看成一对多的关系:多个订阅者对象同时监听一个主题对象,这个主题对象在自身状 态发生变化时,会通知所有的订阅者对象,使他们能够自动的更新自己的状态。
发布订阅模式,可以让发布方和订阅方,独立封装,独立改变,当一个对象的改变,需要同时改变其他 的对象,而且它不知道有多少个对象需要改变时,可以使用发布订阅模式
发布订阅模式在分布式系统的典型应用有:配置管理和服务发现。
配置管理:是指如果集群中机器拥有某些相同的配置,并且这些配置信息需要动态的改变,我们可以使 用发布订阅模式,对配置文件做统一的管理,让这些机器各自订阅配置文件的改变,当配置文件发生改 变的时候这些机器就会得到通知,把自己的配置文件更新为最新的配置
服务发现:是指对集群中的服务上下线做统一的管理,每个工作服务器都可以作为数据的发布方,向集 群注册自己的基本信息,而让模型机器作为订阅方,订阅工 作服务器的基本信息,当工作服务器的基本信息发生改变时如上下线,服务器的角色和服务范围变更,监控服务器就会得到通知,并响应这些 变化。
2、发布订阅的架构图
Zookeeper的消息订阅及发布最典型的应用实例是作为系统的配置中心,发布者将数据发布到ZK节点
上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服 务框架的服务地址列表等就非常适合使用。
Zookeeper 主要有两种监听方式,监听子节点状态,监听节点数据。下图中,work server节点可存储应用服务器元数据(如:服务器ip和端口等信息),查询server节点可获取服务器列表,创建zookeeper客户 端监听server节点的字节点状态,在应用服务器暂停使用(删除对应work server子节点)或增加应用服务器时(增加对应work server 子节点)时,zookeeper客户端可获及时的通知并进行处理。config节点可存储分布式集群的全局配置信息,在全局配置信息需要修改时,可将配置信息发布到config节点下,所 有对config节点数据进行监听的zookeeper客户端可及时收到通知并对服务器的配置信息进行修改。
在这里插入图片描述
3、Manager Server的工作流程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Zookeeper的分布式锁实现方式?
问过的一些公司:陌陌,小米,阿里x2,vivo,阿里,,快手,恒生电子,Shopee(2021.07) 参考答案:
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。
zookeeper有以下特点: 1)维护了一个有层次的数据节点,类似文件系统。

  1. 有以下数据节点:临时节点、持久节点、临时有序节点(分布式锁实现基于的数据节点)、持久有 序节点。
  2. zookeeper可以和client客户端通过心跳的机制保持长连接,如果客户端链接zookeeper创建了一个临 时节点,那么这个客户端与zookeeper断开连接后会自动删除。
  3. zookeeper的节点上可以注册上用户事件(自定义),如果节点数据删除等事件都可以触发自定义事 件。
  4. zookeeper保持了统一视图,各服务对于状态信息获取满足一致性。Zookeeper的每一个节点,都是一个天然的顺序发号器。
    在每一个节点下面创建子节点时,只要选择的创建类型是有序(EPHEMERAL_SEQUENTIAL 临时有序或者PERSISTENT_SEQUENTIAL 永久有序)类型,那么,新的子节点后面,会加上一个次序编号。这个次序编号,是上一个生成的次序编号加一。
    比如,创建一个用于发号的节点“/test/lock”,然后以他为父亲节点,可以在这个父节点下面创建相同前 缀的子节点,假定相同的前缀为“/test/lock/seq-”,在创建子节点时,同时指明是有序类型。如果是第一 个创建的子节点,那么生成的子节点为/test/lock/seq-0000000000,下一个节点则为/test/lock/seq- 0000000001,依次类推,等等。
    在这里插入图片描述
    如何使用Zookeeper实现分布式锁
    大致思想为:每个客户端对某个方法加锁时,在 Zookeeper 上与该方法对应的指定节点的目录下,生成一个唯一的临时有序节点。 判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。当释放锁的时候,只需将这个临时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产 生的死锁问题。
    1、排它锁
    排他锁,又称写锁或独占锁。如果事务T1对数据对象O1加上了排他锁,那么在整个加锁期间,只允许事 务T1对O1进行读取或更新操作,其他任务事务都不能对这个数据对象进行任何操作,直到T1释放了排他 锁。
    排他锁核心是保证当前有且仅有一个事务获得锁,并且锁释放之后,所有正在等待获取锁的事务都能够 被通知到。
    Zookeeper 的强一致性特性,能够很好地保证在分布式高并发情况下节点的创建一定能够保证全局唯一性,即Zookeeper将会保证客户端无法重复创建一个已经存在的数据节点。可以利用Zookeeper这个特 性,实现排他锁。
  5. 定义锁:通过Zookeeper上的数据节点来表示一个锁
  6. 获取锁:客户端通过调用 create 方法创建表示锁的临时节点,可以认为创建成功的客户端获得了锁,同时可以让没有获得锁的节点在该节点上注册Watcher监听,以便实时监听到lock节点的变更情况
  7. 释放锁:以下两种情况都可以让锁释放
    当前获得锁的客户端发生宕机或异常,那么Zookeeper上这个临时节点就会被删除 正常执行完业务逻辑,客户端主动删除自己创建的临时节点
    基于Zookeeper实现排他锁流程:
    在这里插入图片描述
    2、共享锁
    共享锁,又称读锁。如果事务T1对数据对象O1加上了共享锁,那么当前事务只能对O1进行读取操作, 其他事务也只能对这个数据对象加共享锁,直到该数据对象上的所有共享锁都被释放。
    共享锁与排他锁的区别在于,加了排他锁之后,数据对象只对当前事务可见,而加了共享锁之后,数据 对象对所有事务都可见。
  8. 定义锁:通过Zookeeper上的数据节点来表示一个锁,是一个类似于/lockpath/[hostname]-请求类型-
    序号的临时顺序节点
  9. 获取锁:客户端通过调用 create 方法创建表示锁的临时顺序节点,如果是读请求,则创建
    /lockpath/[hostname]-R-序号节点,如果是写请求则创建 /lockpath/[hostname]-W-序号节点
  10. 判断读写顺序:大概分为4个步骤
    ① 创建完节点后,获取 /lockpath 节点下的所有子节点,并对该节点注册子节点变更的Watcher监听
    ② 确定自己的节点序号在所有子节点中的顺序
    ③ 对于读请求:
    如果没有比自己序号更小的子节点,或者比自己序号小的子节点都是读请求,那么表明自己已经成 功获取到了共享锁,同时开始执行读取逻辑
    如果有比自己序号小的子节点有写请求,那么等待
    对于写请求,如果自己不是序号最小的节点,那么等待
    ④ 接收到Watcher通知后,重复步骤①
  11. 释放锁:与排他锁逻辑一致

在这里插入图片描述
基于Zookeeper实现共享锁流程:
在这里插入图片描述
Zookeeper怎么保证一致性的
问过的一些公司:阿里,快手参考答案:
依赖了ZAB协议
ZAB协议是伪分布式协调服务Zookeeper专门设计的一种崩溃恢复的原子广播协议
它有两种基本的模式:
崩溃恢复消息广播
这两个模式是相辅相成的,消息广播模式就是zookeeper不出现任何问题,并且正常工作的模式,崩溃 恢复看字面意思就是当Zookeeper出现故障时用于恢复的。
当出现故障时这两种模式怎么用?(不故障时就一种都没必要说)
当整个zookeeper集群刚刚启动或者Leader服务器宕机、重启或者网络故障导致不存在过半的服务器与Leader服务器保持正常通信时(Leader选举,必须要存在过半的服务器),所有进程(服务器)进入崩溃 恢复模式,首先选举产生新的Leader服务器,然后集群中Follower服务器开始与新的Leader服务器进行 数据同步,当集群中超过半数机器与该Leader服务器完成数据同步之后,退出恢复模式进入消息广播模 式,Leader服务器开始接收客户端的事务请求生成事物提案来进行事务请求处理。

Zookeeper的zab协议(原子广播协议)?
可回答:说下Zookeeper的一致性算法问过的一些公司:海康(2021.08)
Zab协议是Zookeeper保证数据一致性的核心算法,Zab借鉴了Paxos算法,但又不像Paxos那样,是一种 通用的分布式一致性算法,基于该协议,zk实现了一种主备模型(即Leader和Follower模型),保证了 事务的最终一致性。
ZAB协议介绍
ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。
Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服务。在解决分布式一致性方面,
Zookeeper 并没有使用Paxos ,而是采用了ZAB协议。
ZAB 协议定义:ZAB 协议是为分布式协调服务 Zookeeper 专门设计的一种支持崩溃恢复和原子广播协议。
基于该协议,Zookeeper 实现了一种主备模式的系统架构来保持集群中各个副本之间数据一致性
在这里插入图片描述
首先客户端所有的写请求都由一个Leader接收,而其余的都是Follower(从者)。
Leader 负责将一个客户端事务请求,转换成一个事务Proposal,并将该Proposal分发给集群中所有的Follower(备份),也就是向所有Follower节点发送数据广播请求(或数据复制)记住这里发送给的不光 是数据本身,还有其他的,相当于包装。
分发之后Leader需要等待所有Follower的反馈(Ack请求),在Zab协议中,只要超过半数的Follower进行 了正确的反馈后(也就是收到半数以上的Follower的Ack请求),那么 Leader 就会再次向所有的Follower 发送Commit消息,要求其将上一个事务proposal进行提交,就是相当于通过,如果是用dubbo进行微服 务就是zookeeper这个协调服务通过了,开始往服务端发送数据。
ZAB协议的两种模式:崩溃恢复和消息广播
当整个集群正在启动时,或者当Leader节点出现网络中断、崩溃等情况时,ZAB协议就会进入恢复模式 并选举产生新的Leader,当Leader服务器选举出来后,并且集群中有过半的机器和该Leader节点完成数 据同步后(同步指的是数据同步,用来保证集群中过半的机器能够和Leader服务器的数据状态保持一 致),ZAB协议就会退出恢复模式。
当集群中已经有过半的Follower节点完成了和Leader状态同步以后,那么整个集群就进入了消息广播模 式。这个时候,在Leader节点正常工作时,启动一台新的服务器加入到集群,那这个服务器会直接进入 数据恢复模式,和Leader节点进行数据同步。同步完成后即可正常对外提供非事务请求的处理。
消息广播(原子广播)
消息广播实际上是一个简化版的2PC提交过程。
在这里插入图片描述
过程如下:

  1. leader接收到消息请求后,将消息赋予一个全局唯一的64位自增id,叫:zxid,通过zxid的大小比较就 可以实现因果有序这个特征。
  2. leader为每个follower准备了一个FIFO队列(通过TCP协议来实现,以实现全局有序这一个特点)将带 有zxid的消息作为一个提案(proposal)分发给所有的 follower。
  3. 当follower接收到proposal,先把proposal写到磁盘,写入成功以后再向leader回复一个ack。
  4. 当leader接收到合法数量(超过半数节点)的ack后,leader就会向这些follower发送commit命令,同 时会在本地执行该消息。
  5. 当follower收到消息的commit命令以后,会提交该消息。
    崩溃恢复(数据恢复)
    ZAB协议的这个基于原子广播协议的消息广播过程,在正常情况下是没有任何问题的,但是一旦Leader 节点崩溃,或者由于网络问题导致Leader服务器失去了过半的Follower节点的联系(leader失去与过半follower节点联系,可能是leader节点和 follower节点之间产生了网络分区,那么此时的leader不再是合法的leader了),那么就会进入到崩溃恢复模式。在ZAB协议中,为了保证程序的正确运行,整个恢复过 程结束后需要选举出一个新的Leader。
    为了使leader挂了后系统能正常工作,需要解决以下两个问题:
    48 已经被处理的消息不能丢失
    当leader收到合法数量follower的ack后,就向各个follower广播commit命令,同时也会在本地执行commit并向连接的客户端返回「成功」。但是如果各个follower在收到commit命令前leader就挂了,导 致剩下的服务器并没有执行到这条消息。
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据小理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值