设为首页 收藏本站
查看: 984|回复: 0

[经验分享] zookeeper中Watcher和Notifications

[复制链接]

尚未签到

发表于 2015-9-6 10:32:20 | 显示全部楼层 |阅读模式
  问题导读:
1.zookeeper观察者什么时候调用?
2.传统远程轮询服务存在什么问题?
3.zk中回调服务的机制是什么?
4.zk中watcher为什么不永久注册?
5.什么是znode?


DSC0000.gif



在阅读之前首先明确个概念:
1.什么是znode?


2.什么是客户端?
我们使用znode这个术语来表示ZooKeeper的数据节点。


znode维持一个stat结构,它包含数据变化的版本号、ACL变化和时间戳,以允许cache校验和协调化的更新。每当znode的数据变化时,版本号将增加。一个客户端收到数据时,它也会收到数据的版本号。
保存在每个znode中的数据都是自动读写的。读操作获取znode的所有数据,写操作替换掉znode的所有数据。每个节点有一个访问控制表(ACL)来限制谁能做哪些操作。
  

Zookeeper中的角色主要有以下三类,如下表所示:
<ignore_js_op> DSC0001.jpg
系统模型如图所示:
<ignore_js_op> DSC0002.jpg DSC0003.gif

传统轮询远程service服务
传统远程的service往往是这样服务的,服务提供者在远程service注册自己的服务,服务调用者不断去远程service轮询看看是否服务提供者有没有提供服务或者更新服务。所以有弊端,就是延时比较高,而且因为很多不必要的空轮询带来高的负载和网络损耗,这种模式到zk里面就应该是这样。

<ignore_js_op> DSC0004.jpg

zk中异步回调服务
zk实际上的实现是异步回调来代替polling,引入一种机制是event inotifications:客户端首先注册到zk service从而可以接收znode的改变事件,也就是说一旦watch的znode变更了,客户端就会得到相应的通知,然后处理自己的业务逻辑。
<ignore_js_op> DSC0005.jpg



  • zk客户端可以通过exists,getChildren,getData可以注册观察者,观察者说白了就是指定一个callback
  • 那么观察者什么时候调用呢?一旦监听的znode变化了,zk service就会发送对应znode路径给客户端,客户端调用相应的之前注册的回掉函数处理。对于节点的create,delete,setData都会触发观察者,也就是这个callback()函数。
  
服务端只存储事件的信息,客户端存储事件的信息和Watcher的执行逻辑。客户端在注册watcher的时候,在客户端本地会维持对应znode path和callback()的对应关系。在服务端会维护对应连接session以及znode path和事件类型。服务端触发了对应的事件类型后,会发送给客户端事件类型和znode path,在客户端会根据映射关系调用相应的callback(),接下来的业务逻辑都是在客户端实现的。
zk中watcher单次触发问题
zk中的Watch是一次触发的,一次变更只会触发一个通知,要想下次还得到通知,就需要重新注册。为什么不是永久注册Watcher呢?这主要是考虑到性能上面的影响吧。看下面的情况


  • Client C1对于znode /Task 设置了一个watcher
  • Client C2来到然后对 /Task 增加znode
  • Client C1接收到了notifications,得知监控的znode变化了
  • Client C1在处理这个notifications,这时候Client C3又增加 /task 一个znode
  
在步骤3的时候C1已经触发了一次watcher,步骤四的时候没有watcher了,除非重新设置watcher,所以这个过过程中就会丢失一个notifications,这就是涉及到了CAP原理了。zookeeper只能保证最终一致性,不能保证强一致性,但是因为zk保证了顺序一致性,所以就能确保最终一致性。


  • 强一致性:分布式系统里面一个数据变更后,访问任一个服务都可以得到最新的数据
  • 弱一致性:一个数据变更后,其中部分服务可以得到最新数据,部分服务不能
  • 最终一致性:在更新某个数据后,可能在开始的时候得不到最新的数据,但是最终是可以呈现最新的数据
  • 顺序一致性:更新N份数据,能保证是服务是按照N份数据顺序更新提供服务的。
  其实对于上面的case也是有办法解决的,具体就是每次在注册watcher之后都getData,保证数据版本是最新的,但相比较传统的polling优势还是很明显的。
zk中Versions
每个znode一旦数据变化,都会有一个递增的版本号,在zk API执行的时候都需要指定版本号,客户端提供的版本号只有和服务端匹配了才能进行znode操作。在多个客户端都要操作同一个znode的时候版本号就很重要了。看下面的情况。


  • 比如Client C1写了一个znode /Nginx/conf的数据,写了一些配置信息,这时候/Nginx/conf版本号就从version1变成version2
  • 在上面的同时,Client C2也想写/Nginx/conf,因为C2的客户端版本还是version1,而服务端已经是version2了,此刻就会冲突,这个操作就会以失败告终。所以必须要先更新C2上到version2,然后再提交操作。


zk上更新version2到version3,C2本地更新至version3  


<ignore_js_op> DSC0006.jpg   

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-110037-1-1.html 上篇帖子: ZooKeeper 应用场景 下篇帖子: ZooKeeper开发手册中文翻译
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表