Zookeeper面试总结,年后涨薪轻而易举
云之遥^_^ 人气:0此文不是入门教程,是需要一定的zookeeper基础的
zookeeper应用
同意命名服务
在分布式系统中,各个系统都有可能做为服务提供者,可以向外提供服务,这个时候就需要对服务的名字进行统一规划,比如"应用+组+服务名+版本号",而Zookeeper的目录式结构存储特点,则正好提供了这种命名方式的支持。比如Dubbo里在用Zookeeper做注册中心时就利用了Zookeeper的这一特性。
配置中心
在分布式系统中,特别是集群环境下,配置是一个公共资源,其最重要的一个特征是配置的变化需要通知使用配置的变化需要通知使用者,Zookeeper可以作为公共资源存储的数据库,Zookeeper的数据会持久化,但同时也会在内存中存在,数据的读操作是直接读取的内存数据,配置的使用量肯定是读>写的,所以性能方面是没有问题的,并且自带的Watch机制正好提供了数据发布与订阅数据发布与订阅功能,Zookeeper上存储的配置信息发生了改变,使用该配置的应用程序是可以接收到相应的变化通知的。
集群管理
利用Zookeeper可以对集群进行监控,比如每台服务器对应一个Zookeeper中的临时节点,这些节点的父节点为/WatchNode,那么监控平台可以监听/WatchNode下节点的变化,增加一台机器,或挂掉一台机器都可以反应到Zookeeper节点的变化,从而达到监控的目的。
集群中的服务器,通常是处理相同的业务,但是可能有些业务是IO比较重或CPU比较重,这个时候可以利用Zookeeper来实现一个领导者选举,从集群中选出一个领导者,这个领导者是唯一的,所以将由它来执行这个特殊的任务,这里说的领导者选举并不是指Zookeeper实现原理中的领导者选举,Zookeeper实现原理中的领导者选举是比较复杂的,是对算法的一个代码实现,而上面的说的利用Zookeeper来实现一个领导者选举是比较容易的,其实核心就是选出一个唯一点,比如,集群中的服务器可以同时去创建同一个名字的节点,由于Zookeeper的一致性,最终只会有一个客户端创建成功,谁成功了谁就是领导,这是一种方法,还有一种就是,集群中的服务器也是去Zookeeper中创建节点,每个服务器都将会创建成功,只是创建的节点是顺序节点,从这些顺序节点中按一个简单的规则(比如最大,最小)选出一个节点,该节点为领导。
分布式锁
在分布式系统中,某些公共资源是需要具有独占性的,这个时候就需要用到分布式锁,利用Zookeeper的临时顺序节点以及Watch机制可以实现分布式锁。
- 首先定义一个节点/Lock作为某个资源的锁
- 所有需要用到该资源的服务器在/Lock节点下去创建临时顺序节点
- 顺序最小的节点代表相应服务器获取到了锁
- 服务器主动释放或服务器挂掉都会引起对应节点的删除,从而其他服务器利用Watch机制重新比较节点的大小判断自己是否获取到了锁
zookeeper底层原理
一致性
Zookeeper利用ZAB算法实现了强一致性,Zookeeper在接收到客户端请求后,会先将请求放入一个队列中,然后再以单线程从队列中拿出请求进行处理,这样就避免的并发的问题,对于类似写、更新、删除等事务性操作,在Zookeeper集群中都会交由Leader节点进行处理,Leader节点在处理事务性请求时,会进行类似两阶段提交,先询问,再提交,在Zookeeper中Leader并不会等待所有节点都告诉Leader可提交,而是会进行一个过半机制的验证,只要超过半数的节点认为可提交,Leader就会向所有节点发送提交事务的请求,其他所有节点就会进行提交。
从Zookeeper底层原理上来讲,可以把Zookeeper看做是一个数据库,类似Mysql,每一次数据库操作都会存日志,所以Zookeeper也是一样,服务器在接收到事务性请求时,会先持久化一份事务日志,再更新内存数据,所以对于Zookeeper中的两阶段分别是:1. 持久化事务日志,2.更新内存。实际上,只有更新了内存,Zookeeper客户端才会真正获取到最新的数据。
watch机制
在Zookeeper中,客户端进行定义监听器,并绑定到某个节点,客户端自己负责存储某个节点对应了哪些监听器这个信息,服务端不需要存储这个信息,服务端只需要抛出对节点的操作事件,而不关心有哪些客户端监听了这个事件,客户端收到这个事件后,根据之前保存的节点监听器对应关系,触发相应的监听器,这里需要注意Zookeeper的原生客户端的Watch是一次性的,也就是说节点的监听器在被触发了一次之后就会被原生客户端自动删除掉,而Zkclient以及Curator都是做了处理的,可以重复使用。
领导者选举
首先领导者选举并不是独立的,它是属于ZAB协议中的一个步骤,因为ZAB协议主要是用来保证集群的一致性,而保证一致性最关键的一步是需要有一个Leader来对集群进行统一管理,这样集群的一致性才能得到保证,所以领导者选举就是为了选出这个Leader。
领导者选举一般发生在整个集群启动,或者说Leader挂掉的时候,或者说Follower挂掉后Leader发现已经没有过半的Follower跟随自己了从而重新开始选举。
领导者选举的过程实际上就是比较哪台服务器比较强,比较规则是:1. 谁的数据比较新谁当领导(zxid),2.据都一样则看谁的服务器Id(myid)比较大谁就是领导;这个过程是通过各个服务器之间相互投票来进行的,每台服务器会接收其他服务器的投票,在投票信息里就会包含上面说的两个信息zxid, myid,然后进行PK,选出谁比较强,而PK中弱的那一方修改自己的投票,改为投刚刚和自己PK赢的一方,所以按照这个规则,每台服务器都会有一个自己认为最强的那个人,而在整个投票的过程中,每台服务器内部都会存在一个投票箱,该投票箱内存放了其他服务器当前投给了谁,所以每台服务器可以根据这个投票箱内的数据来看是否有超过半数的服务器和我当前投的最强者是同一台服务器,如果超过了则认为选出了Leader(自己当前所投的那个最强者即为Leader),如果发现自己就是这个最强者,则进行领导,如果自己不是,则进行跟随(Follower)。
观察者
观察者(Observer)是不参与选举的,也不参与过半机制的验证,所以Leader在处理事务性请求时,只需要验证是否有超过一半的Follower同意这次请求,而不用判断观察者是否同意,观察者只需最后去同步数据即可。
如果想提高Zookeeper集群的读性能,需要去增加节点,如果增加的是Follower节点,虽然提高了读性能,但是因为Follower需要进行过半机制的验证,所以会导致Leader在接收Follower的反馈时,需要等待更多的Follower的结果,这个过程不管是领导者选举,还是在进行事务性请求时都是存在的,都会增加耗时。比如领导者选举时,需要等待更多节点的投票结果,需要去跟更多节点进行相互投票;比如在进行写操作时,Leader需要等待更多Follower节点的能否提交的反馈,从而影响写操作的性能。
而如果增加的是Observer节点,则不会影响过半机制,同时可以提高读性能,虽然会在同步数据的消耗一点性能,但是优点是比缺点大很多的。
本文由博客一文多发平台 OpenWrite 发布!
加载全部内容