Zookeeper系列介绍( 持续更新 )
Zookeeper提供了数据的发布/订阅功能,多个订阅者可同时监听某一特定主题对象,当该主题对象的自身状态发生变化时(例如节点内容改变、节点下的子节点列表改变等),会实时、主动通知所有订阅者。
Zookeeper采用了Watcher机制实现数据的发布/订阅功能。该机制在被订阅对象发生变化时会异步通知客户端,因此客户端不必在Watcher注册后轮询阻塞,从而减轻了客户端压力。
Watcher实现由三个部分组成:
客户端首先将Watcher注册到服务端,同时将Watcher对象保存到客户端的Watch管理器中。当ZooKeeper服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的Watch管理器会触发相关Watcher来回调相应处理逻辑,从而完成整体的数据发布/订阅流程。
Watcher是一个接口, 任何实现了Watcher接口的类就是一个新的Watcher 。Watcher内部包含了两个枚举类:KeeperState、EventType。
KeeperState是客户端与服务端连接状态发生变化时对应的通知类型。路径为org.apache.zookeeper.Watcher.Event.KeeperState,是一个枚举类,其枚举属性如下;
EventType是数据节点(znode)发生变化时对应的通知类型。 EventType变化时KeeperState永远处于SyncConnected通知状态下;当KeeperState发生变化时,EventType永远为None 。其路径为org.apache.zookeeper.Watcher.Event.EventType,是一个枚举类,枚举属性如下;
注 :客户端接收到的相关事件通知中只包含状态及类型等信息,不包括节点变化前后的具体内容,变化前的数据需业务自身存储,变化后的数据需调用get等方法重新获取;
Zookeeper是一个广受大家喜爱的框架,他能搞定分布式锁,也能实现服务之间更好的调用,而他是通过通知机制来实现的,那么他是怎么实现的呢?下面就来一步一步聊一聊
根据上面的知识基础,我们基本了解了zookeeper的面貌,下面就是他的通知机制的设计
zookeeper的客户端向zookeeper发送要执行的任务,发完了之后一种设计是每次客户端都去查询这个任务有没有被执行,这样查很多遍显然是不够聪明的
所以zookeeper采用了通知的机制,这种机制就是在zookeeper上设置一个监视点,当客户端第一次访问的时候把监视点watcher放到zookeeper上,然后客户端就不用管,这时候消费者,访问了zookeeper,处理了这个任务,那么watch就登场了,他会主动向客户端发送消息,告诉客户端任务被处理了,然后watch自己就移除掉,这样就不用客户端来没一次查询了。
这个就是watch的意义,是一种很聪明的做法,依据他就知道为什么代用zookeeper要使用watch。
2006年的时候Google出了Chubby来解决分布一致性的问题(distributed consensus problem),所有集群中的服务器通过Chubby最终选出一个Master Server ,最后这个Master Server来协调工作。简单来说其原理就是:在一个分布式系统中,有一组服务器在运行同样的程序,它们需要确定一个Value,以那个服务器提供的信息为主/为准,当这个服务器经过n/2+1的方式被选出来后,所有的机器上的Process都会被通知到这个服务器就是主服务器 Master服务器,大家以他提供的信息为准。很想知道Google Chubby中的奥妙,可惜人家Google不开源,自家用。但是在2009年3年以后沉默已久的Yahoo在Apache上推出了类似的产品ZooKeeper,并且在Google原有Chubby的设计思想上做了一些改进,因为ZooKeeper并不是完全遵循Paxos协议,而是基于自身设计并优化的一个2 phase commit的协议,如图所示:
ZooKeeper跟Chubby一样用来存放一些相互协作的信息(Coordination),这些信息比较小一般不会超过1M,在zookeeper中是以一种hierarchical tree的形式来存放,这些具体的Key/Value信息就store在tree node中。
当有事件导致node数据,例如:变更,增加,删除时,Zookeeper就会调用 triggerWatch方法,判断当前的path来是否有对应的监听者(watcher),如果有watcher,会触发其process方法,执行process方法中的业务逻辑
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)