zookeeper 面试题2 比较乱

Zookeeper是什么框架
分布式的、开源的分布式应用程序协调服务,本来是Hadoop、HBase的一个重要组件。它为分布式应用提供一致性服务的软件,包括:配置维护、域名服务、分布式同步、组服务等。
应用场景
Zookeeper的功能很强大,应用场景不少,结合我实际工做中使用Dubbo框架的状况,Zookeeper主要是作注册中心用。基于Dubbo框架开发的提供者、消费者都向Zookeeper注册本身的URL,消费者还能拿到并订阅提供者的注册URL,以便在后续程序的执行中去调用提供者。而提供者发生了变更,也会经过Zookeeper向订阅的消费者发送通知。
Paxos算法& Zookeeper使用协议
Paxos算法是分布式选举算法,Zookeeper使用的 ZAB协议(Zookeeper原子广播),两者有相同的地方,好比都有一个Leader,用来协调N个Follower的运行;Leader要等待超半数的Follower作出正确反馈以后才进行提案;两者都有一个值来表明Leader的周期。
不一样的地方在于:
ZAB用来构建高可用的分布式数据主备系统(Zookeeper),Paxos是用来构建分布式一致性状态机系统
Paxos算法、ZAB协议要想讲清楚可不是一时半会的事儿,自1990年莱斯利·兰伯特提出Paxos算法以来,由于晦涩难懂并无受到重视。后续几年,兰伯特经过好几篇论文对其进行更进一步g地解释,也直到06年谷歌发表了三篇论文,选择Paxos做为chubby cell的一致性算法,Paxos才真正流行起来。
对于普通开发者来讲,尤为是学习使用Zookeeper的开发者明确一点就好:分布式Zookeeper选举Leader服务器的算法与Paxos有很深的关系。
选举算法和流程
详情可参看我以前的文章《ZooKeeper集群安装配置使用》第6节“ZooKeeper选举机制”,有个简单的描述。
Zookeeper有哪几种节点类型
持久:建立以后一直存在,除非有删除操做,建立节点的客户端会话失效不影响此节点。
持久顺序:跟持久同样,就是父节点在建立下一级子节点的时候,记录每一个子节点建立的前后顺序,会给每一个子节点名加上一个数字后缀。
临时:建立客户端会话失效(注意是会话失效,不是链接断了),节点也就没了。不能建子节点。
临时顺序:不用解释了吧。
Zookeeper对节点的watch监听通知是永久的吗?
不是。官方声明:一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。
为何不是永久的,举个例子,若是服务端变更频繁,而监听的客户端不少状况下,每次变更都要通知到全部的客户端,这太消耗性能了。
通常是客户端执行getData(“/节点A”,true),若是节点A发生了变动或删除,客户端会获得它的watch事件,可是在以后节点A又发生了变动,而客户端又没有设置watch事件,就再也不给客户端发送。
在实际应用中,不少状况下,咱们的客户端不须要知道服务端的每一次变更,我只要最新的数据便可。
部署方式?集群中的机器角色都有哪些?集群最少要几台机器
单机,集群。Leader、Follower。集群最低3(2N+1)台,保证奇数,主要是为了选举算法
集群若是有3台机器,挂掉一台集群还能工做吗?挂掉两台呢?
记住一个原则过半存活便可用
集群支持动态添加机器吗?
其实就是水平扩容了,Zookeeper在这方面不太好。两种方式:
所有重启:关闭全部Zookeeper服务修改配置以后启动。不影响以前客户端的会话。
逐个重启:顾名思义。这是比较经常使用的方式。java

 

 

 

 

1. Zookeeper是什么框架

分布式的、开源的分布式应用程序协调服务,本来是Hadoop、HBase的一个重要组件。它为分布式应用提供一致性服务的软件,包括:配置维护、域名服务、分布式同步、组服务等。node

2. 应用场景

Zookeeper的功能很强大,应用场景不少,结合我实际工做中使用Dubbo框架的状况,Zookeeper主要是作注册中心用。基于Dubbo框架开发的提供者、消费者都向Zookeeper注册本身的URL,消费者还能拿到并订阅提供者的注册URL,以便在后续程序的执行中去调用提供者。而提供者发生了变更也会经过Zookeeper向订阅的消费者发送通知。算法

8. zookeeper是如何保证事务的顺序一致性的

zookeeper采用了递增的事务Id来标识,全部的proposal都在被提出的时候加上了zxid,zxid其实是一个64位的数字,高32位是epoch用来标识leader是否发生改变,若是有新的leader产生出来,epoch会自增,低32位用来递增计数。当新产生proposal的时候,会依据数据库的两阶段过程,首先会向其余的server发出事务执行请求,若是超过半数的机器都能执行而且可以成功,那么就会开始执行数据库

9. zookeeper是如何选取主leader的?

当leader崩溃或者leader失去大多数的follower,这时zk进入恢复模式apache

zk中znode类型有四种,持久化目录节点 持久化顺序编号目录节点(有顺序 可以在注册机器等许多场景用到) 临时目录节点 临时顺序编号节点服务器

zk的通知机制网络

client端会对某个znode创建一个watcher事件,当该znode发生变化时,这些client会收到zk的通知,而后client能够根据znode变化来作出业务上的改变等。session

zk的配置管理框架

程序分布式的部署在不一样的机器上,将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时,能够经过改变zk中某个目录节点的内容,利用water通知给各个客户端 从而更改配置。运维

zk的命名服务

命名服务是指经过指定的名字来获取资源或者服务的地址,利用zk建立一个全局的路径,这个路径就能够做为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。

分布式通知和协调

对于系统调度来讲:操做人员发送通知实际是经过控制台改变某个节点的状态,而后zk将这些变化发送给注册了这个节点的watcher的全部客户端

对于执行状况汇报:每一个工做进程都在某个目录下建立一个临时节点。并携带工做的进度数据,这样汇总的进程能够监控目录子节点的变化得到工做进度的实时的全局状况。

10. 机器中为何会有master;

在分布式环境中,有些业务逻辑只须要集群中的某一台机器进行执行,其余的机器能够共享这个结果,这样能够大大减小重复计算,提升性能,因而就须要进行master选举。

11. ZooKeeper集群中服务器之间是怎样通讯的?

Leader服务器会和每个Follower/Observer服务器都创建TCP链接,同时为每一个F/O都建立一个叫作LearnerHandler的实体。LearnerHandler主要负责Leader和F/O之间的网络通信,包括数据同步,请求转发和Proposal提议的投票等。Leader服务器保存了全部F/O的LearnerHandler。

12. zookeeper是否会自动进行日志清理?如何进行日志清理?

zk本身不会进行日志清理,须要运维人员进行日志清理

13. ZK选举过程

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式须要从新选举出一个新的leader,让全部的Server都恢复到一个正确的状态。Zk的选举算法使用ZAB协议:

① 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server

② 选举线程首先向全部Server发起一次询问(包括本身);

③ 选举线程收到回复后,验证是不是本身发起的询问(验证zxid是否一致),而后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中

④ 收到全部Server回复之后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;

⑤ 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,若是此时获胜的Server得到n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置本身的状态,不然,继续这个过程,直到leader被选举出来。

经过流程分析咱们能够得出:要使Leader得到多数Server的支持,则Server总数最好是奇数2n+1,且存活的Server的数目不得少于n+1

14. master/slave之间通讯

 

Storm:按期扫描

PtBalancer:节点监听

 

15. 节点变多时,PtBalancer速度变慢

 

相似问题:根据Netflix的Curator做者所说,ZooKeeper真心不适合作Queue,或者说ZK没有实现一个好的Queue,详细内容能够看https://cwiki.apache.org/confluence/display/CURATOR/TN4,

缘由有五:

① ZK有1MB 的传输限制。 实践中ZNode必须相对较小,而队列包含成千上万的消息,很是的大。

② 若是有不少节点,ZK启动时至关的慢。 而使用queue会致使好多ZNode. 你须要显著增大 initLimit 和 syncLimit.

③ ZNode很大的时候很难清理。Netflix不得不建立了一个专门的程序作这事。

④ 当很大量的包含成千上万的子节点的ZNode时, ZK的性能变得很差

⑤ ZK的数据库彻底放在内存中。 大量的Queue意味着会占用不少的内存空间。

尽管如此, Curator仍是建立了各类Queue的实现。 若是Queue的数据量不太多,数据量不太大的状况下,酌情考虑,仍是可使用的。

 

16. 客户端对ServerList的轮询机制是什么

 

随机,客户端在初始化( new ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) )的过程当中,将全部Server保存在一个List中,而后随机打散,造成一个环。以后从0号位开始一个一个使用。

两个注意点:

① Server地址可以重复配置,这样可以弥补客户端没法设置Server权重的缺陷,可是也会加大风险。(好比: 192.168.1.1:2181,192.168.1.1:2181,192.168.1.2:2181).

② 若是客户端在进行Server切换过程当中耗时过长,那么将会收到SESSION_EXPIRED. 这也是上面第1点中的加大风险之处。

17. 客户端如何正确处理CONNECTIONLOSS(链接断开) 和 SESSIONEXPIRED(Session 过时)两类链接异常

在ZooKeeper中,服务器和客户端之间维持的是一个长链接,在 SESSION_TIMEOUT 时间内,服务器会肯定客户端是否正常链接(客户端会定时向服务器发送heart_beat),服务器重置下次SESSION_TIMEOUT时间。所以,在正常状况下,Session一直有效,而且zk集群全部机器上都保存这个Session信息。在出现问题状况下,客户端与服务器之间链接断了客户端所链接的那台zk机器挂了,或是其它缘由的网络闪断),这个时候客户端会主动在地址列表(初始化的时候传入构造方法的那个参数connectString)中选择新的地址进行链接。

 

好了,上面基本就是服务器与客户端之间维持长链接的过程了。在这个过程当中,用户可能会看到两类异常CONNECTIONLOSS(链接断开) 和SESSIONEXPIRED(Session 过时)。

 

CONNECTIONLOSS发生在上面红色文字部分,应用在进行操做A时,发生了CONNECTIONLOSS,此时用户不须要关心个人会话是否可用,应用所要作的就是等待客户端帮咱们自动链接上新的zk机器,一旦成功链接上新的zk机器后,确认刚刚的操做A是否执行成功了。

18. 一个客户端修改了某个节点的数据,其它客户端可以立刻获取到这个最新数据吗

ZooKeeper不能确保任何客户端可以获取(即Read Request)到同样的数据,除非客户端本身要求:方法是客户端在获取数据以前调用org.apache.zookeeper.AsyncCallback.VoidCallback, java.lang.Object) sync.

一般状况下(这里所说的一般状况知足:1. 对获取的数据是不是最新版本不敏感,2. 一个客户端修改了数据,其它客户端是否须要当即可以获取最新),能够不关心这点。

在其它状况下,最清晰的场景是这样:ZK客户端A对 /my_test 的内容从 v1->v2, 可是ZK客户端B对 /my_test 的内容获取,依然获得的是 v1. 请注意,这个是实际存在的现象,固然延时很短。解决的方法是客户端B先调用 sync(), 再调用 getData().

19. ZK为何不提供一个永久性的Watcher注册机制

不支持用持久Watcher的缘由很简单,ZK没法保证性能

使用watch须要注意的几点

① Watches通知是一次性的,必须重复注册.

② 发生CONNECTIONLOSS以后,只要在session_timeout以内再次链接上(即不发生SESSIONEXPIRED),那么这个链接注册的watches依然在。

③ 节点数据的版本变化会触发NodeDataChanged,注意,这里特地说明了是版本变化。存在这样的状况,只要成功执行了setData()方法,不管内容是否和以前一致,都会触发NodeDataChanged。

④ 对某个节点注册了watch,可是节点被删除了,那么注册在这个节点上的watches都会被移除

⑤ 同一个zk客户端对某一个节点注册相同的watch,只会收到一次通知

⑥ Watcher对象只会保存在客户端,不会传递到服务端。

20. 我可否收到每次节点变化的通知

若是节点数据的更新频率很高的话,不能。

缘由在于:当一次数据修改通知客户端,客户端再次注册watch,在这个过程当中,可能数据已经发生了许屡次数据修改,所以,千万不要作这样的测试:”数据被修改了n次,必定会收到n次通知”来测试server是否正常工做。(我曾经就作过这样的傻事,发现Server一直工做不正常?其实不是)。即便你使用了GitHub上这个客户端也同样。

21. 能为临时节点建立子节点吗

不能。

22. 是否能够拒绝单个IP对ZK的访问,操做

ZK自己不提供这样的功能,它仅仅提供了对单个IP的链接数的限制。你能够经过修改iptables来实现对单个ip的限制,固然,你也能够经过这样的方式来解决。https://issues.apache.org/jira/browse/ZOOKEEPER-1320

23. 在getChildren(String path, boolean watch)是注册了对节点子节点的变化,那么子节点的子节点变化能通知吗

不能

24. 建立的临时节点何时会被删除,是链接一断就删除吗?延时是多少?

链接断了以后,ZK不会立刻移除临时数据,只有当SESSIONEXPIRED以后,才会把这个会话创建的临时数据移除。所以,用户须要谨慎设置Session_TimeOut

相关文章
相关标签/搜索