ZooKeeper面试题
ZooKeeper的五大特性(了解)
- 全局数据一致性:集群中每个服务器保存一份相同的数据副本,客户端无论连接到哪个服务器,展示的数据都是一致的
- 可靠性:如果消息被其中一台服务器接受,那么将被所有的服务器接受
- 顺序性:包括 “全局有序” 和 “偏序” 两种
-
- 全局有序:在一台服务器上,消息a比消息b先发布,则在所有服务器上a都比b先发布;
-
- 偏序:同一个发送者,先消息a后再发消息b,则a一定排比b先发布
- 数据更新原子性:一次数据更新要么成功(半数以上节点成功),要么失败,不存在中间状态;
-
- 假设一共有5个ZK节点,如果我们更新了一条数据(主服务器) => 同步到其他服务器,必须要保证3台机器全部同步成功,则最终这条数据才认为更新成功
- 实时性:ZooKeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息
ZooKeeper集群中有哪些角色?
【Leader】领导者角色,ZooKeeper集群工作的核心,主要用于接收和处理事务型操作(增、删、改);
【Follower】追随者角色
- 处理非事务型请求(读操作)
- 对于事务型请求,转发给Leader
- 当ZooKeeper集群中没有Leader,参与投票选举工作
【Observer】
此外,针对访问量比较大的ZooKeeper集群,还可新增观察者角色
观察者角色,和Follwer角色的工作基本相同,唯一的不同是不参与投票选举工作
ZooKeeper中有那些类型的节点, 各个类型有什么特点?
节点 | 是否依赖Session | 是否可以创建子节点 | 是否可以同名 |
---|---|---|---|
永久节点(PERSISTENT | ❌ | ✔ | ❌ |
临时节点(EPHEMERAL | ✔ | ❌ | ❌ |
永久节点序列化(PERSISTENT_SEQUENTIAL) | ❌ | ✔ | ✔ |
临时节点序列化(EPHEMERAL_SEQUENTIAL) | ✔ | ❌ | ✔ |
创建节点命令:create [-s] [-e] path data
- -e:临时节点
- -s:顺序节点,节点名称后面添加10位编号
- path:创建路径
- data:节点内容
可能涉及的问题
问题1:什么是序列化?
答:ZNode创建时候如果指定序列化,则该Znode的名字后面会自动追加一个不断增加的序列号。
序列号对于此节点的父节点来说是唯一的,这样便会记录每个子节点创建的先后顺序。它的格式为“%10d”(10位数字,没有数值的数位用0补充,例如“0000000001”)。
ZooKeeper如何进行选举 ?
需要记住的知识点
① myid代表服务器编号,每一个台服务器的myid编号都是唯一的
② zxid代表全局事务编号,每次对服务器进行增、删、改操作时,此编号都会+1。可以通过zxid编号来区分数据的同步情况,编号越高代表数据越新。
假设现在一共有5台服务器(2n+1)用于搭建ZK服务器的集群
第一种情况:首次启动,目前集群中没有产生过leader领导者
按顺序启动第1台服务器后,各个节点针对自己进行投票,然后进行广播操作。
但是此时只有一个节点,所以只能投票给自己。
接着通过广播告诉其他服务器自己的票数,由于此时节点数(1)小于ZK集群总节点数的一半(2.5),所以第1轮投票失败。
此时需要等待第2台服务器启动进行第2轮投票。该服务器状态为looking状态
第2台服务器启动后,首先给自己投一票。
接着通过广播告诉其他服务器自己的票数,在广播过程中发现第1个节点的myid < 第2个节点的myid,所以myid=1的节点将自己的票投myid=2的节点,此时第2个节点就拥有2张票。但是由于目前的票数(2)仍小于ZK集群总节点数的一半(2.5),所以则第2轮投票失败。
此时需要等待第3台服务器启动进行第3轮投票。myid = 1和 myid =2的机器处于looking状况
第3台服务器启动后,首先给自己投一票。
接着通过广播告诉其他服务器自己的票数,由于集群中myid=3的节点拥有的编号最大,所以前2台服务器把票都投给myid=3的节点。
此时由于票数超过了ZK集群节点数的一半,选举成功。myid=3的节点因此成为整个集群的leader,然后其他两台服务器由looking转为following状态,角色也立即更换为follower。
第4台机器启动时,首先给自己投一票。
接着通过广播告诉其他服务器自己的票数,但是广播过程中发现集群已经有一个leader角色,则自己只能充当follower,其他机器类似。
第二种情况:有Leader的集群,因为Leader宕机,导致重新选举
某台服务器因为网络故障或者网络波动导致无法与Leader进行通信,则会重新发起一轮投票。
首先判断剩余的主机是否过半,不过半则不进行选举,集群直接报废;
如果剩余的主机过半,则该服务器投票给自己,然后进行广播
- 如果在广播过程中发现集群中已经存在leader,则重新同步
- 如果没有Leader,则比较各服务器myid(服务器编号)和zxid(全局事物编号),zxid最大的成为Leader,如果zxid相同则myid编号大的成为Leader
可能涉及的问题
问题1:如果原来那个Leader服务器重新启动了,是争抢这个Leader还是只能充当Follower
答:只能充当Follower角色。
问题2:Observer算不算2n + 1?
答:不算,因为Observer不参与选举投票
问题3:2n + 1是如何确定的?
答:主要是根据zoo.cfg配置文件决定
Zookeeper中Watcher(监听)机制
图解:
原理说明
① ZooKeeper客户端(发布者)向ZooKeeper集群服务器发起连接,创建一个临时节点(create -e /kazi 临时节点)
② 其他的ZooKeeper客户端,可以向该临时节点进行订阅操作(get /kazi watch)
③ 当发布者触发事件时,会立即通知所有已订阅的客户端
④ 由于是一次触发机制,一旦节点watch机制触发了,则该触发机制就失效了
一次触发机制:发布者触发watch(修改节点内容,退出zookeeper操作)后watch event会被发送给订阅者。这种效果是一次性的,后续再次发生任何事件,都不会再次触发。想要再次触发必须重新执行发布订阅
概况总结
watch机制是一种数据发布/订阅模型,常用于Hadoop高可用的切换。
一般有四个关键点:
① 发布者必须使用临时节点
② 订阅者必须先订阅后触发
③ 一次触发机制
④ 采用异步通知的机制(不会阻塞订阅者的其他功能,发布者什么时候触发watch就订阅者就什么时候接收通知)