`

zookeeper 客户端编程

 
阅读更多

zookeeper是一个分布式的开源的分布式协调服务,用它可以来现同步服务,配置维护。zookeeper的稳定性也是可以
保证的,笔者曾参与过的使用zookeeper的两个应用,一个是用zookeeper来做分布式锁,属于同步协调服务,另一个
是配置维护,三台机器运行了一年多了,没有出现什么问题。
------------------------
同步服务:利用zookeeper可以使机器之间的同步如同concurrent包下的同步器同步线程一样,
举两个互斥同步的例子
1.  应用系统部署在多台机器上,需要启动一个时间任务,而这个时间任务只能在一台机器上执行,否则会出现
脏读脏写,zookeeper可以实现。
2.  应用系统部署在多台机器上,需要暴露一个服务,而这个服务同样不是全部的机器都有暴露,例如MASTER,
而暴露这个服务的机器宕机后,其它的机器能自动的接替暴露这个服务,zookeeper可以实现。但是这协调中有一定
的时间差问题。
------------------------
配置维护:服务集群需要使用一组配置,为了保证配置在集群中的一致性,以及对配置更改后的立即响应要求,
使用zookeeper可以实现。hadoop的配置中心就是使用zookeeper来做管理的。
------------------------
zookeeper应用机器结构

客户端根据服务器地址随机的选择一个地址进行连接,如果连接出错会连接其他的地址,客户端一直连接这个地址
知道这个服务器不可用。客户端发送的指令,所有修改数据的指令都由其连接的服务器发送给LEADER进行处理,
查询指令则在其连接的机器上进行。
zookeeper数据组织形式

zookeeper上的数据结构类似于文件结构,每一个节点上都可以写入数据,可以创建叶子节点,也只能删除叶子节点
同时可以对任意路径进行监听各种类型的事件,当该事件在该路径发生时,连接的服务器会发送NOTIFY包过来通知
客户端进行注册的WATCHER的回调处理。

zookeeper上的数据操作主要有CREATE,DELETE,EXISTS,GETDATA,SETDATA,GETCHILDREN
-------------------
CREATE创建一个节点,并在这个节点处写入数据,创建节点有四种模式
1. PERSISTENT 创建持久化节点,对应机器关闭连接后节点/数据不会消失
2. PERSISTENT_SEQUENTIAL 如果PATH是以’/’结尾则以这个PATH作为父节点,创建一个子节点,其子节点名字是一个
按先后顺序排列的数值;否则创建一个名字是 ‘/’后面字符加上先后顺序排列的数值字符串的节点,同样创建
持久节点,例如:
path-------- PERSISTENT-------- PERSISTENT_SEQUENTIAL
/lock/------ error-----------------在/lock/下创建子节点: /lock/000001
/lock-------创建/lock节点-------创建节点 /lock000001
3. EPHEMERAL 创建瞬时节点,Zookeeper在感知连接机器宕机后会清除它创建的瞬节点
4. EPHEMERAL_SEQUENTIAL 穿件瞬时顺序节点,和PERSISTENT_SEQUENTIAL一样,区别在于它是瞬时的
-------------------
DELETE  -  删除一个节点
EXISTS  -  查看一个节点的状况,如果没有返回null,可注入watcher
GETDATA  -  获取一个节点的数据,可注入watcher
SETDATA  -  设置一个节点的数据
GETCHILDREN -  获取一个节点的子节点,可注入watcher
-------------------

Watcher种类
1. zookeeper实例化时注入的默认Watcher
2. dataWatchers 一个Map<string Set<Watcher>>数据结构,保存调用getData时 注入的Watcher或者调用exist时
path指定的节点存在
3. existWatchers 一个Map<string Set<Watcher>>数据结构,保存调用exits时对应的path节点不存在条件下注入
的Watcher
4. childWatchers一个Map<string Set<Watcher>>数据结构,保存调用getChildren 时注入的Watcher
默认Watcher主要是处理连接建立成功,连接断了-会重连,SESSION失效-这个需要重新实例zookeeper对象这些事件
其他的三个Watcher都是MAP<String, SET<Watcher>>结构的,MAP中的KEY是zookeeper数据路径,当调用
exists,getData,getChildren函数时会需要传入一个Watcher,对应的path上的数据发生改变时,zookeeper服务器
会发送NOTIFY包给客户端,客户端在收到NOTIFY包后根据包指明的path和事件类别回调有关Watcher的process函数。
所有需要系统的管理这些Watcher,故分成三个MAP来管理这些Watcher。
当调用getData时将注入的Watcher加入到dataWatchers.get(path)的SET里面,调用childWatchers时一样。需要
重点注意的是当调用exists时,如果path不存在则加入到existWatchers.get(path)的SET里面,否则加入到
dataWatchers.get(path)的SET里面,这样做的原因是为了保持和客户端接收到NOTIFY包时处理一致。

事件处理
NodeDataChanged & NodeCreated
回调dataWatchers.get(path) & existWatchers.get(path)得到的Watcher集合,同时会将path这一MAP映射
从dataWatchers&existWatchers里面清除
---------
NodeChildrenChanged
回调childWatchers.get(path得到的Watcher集合,同时会将path这一MAP映射从childWatchers.get里面清除
---------
NodeDeleted
回调dataWatchers.get(path) & childWatchers.get(path)得到的Watcher集合,同时会将path这一MAP映射从
dataWatchers& childWatchers里面清除,同时会将path这一MAP映射从existWatchers里面清除
上面提到过对于exists的Watcher,为了保证Watcher能被回调,如果节点原本不存在的话,那么这个节点就
只会有NodeCreated事件,故加入到existWatchers能找到,如果存在的话就可能是数据修改和删除事件了,
如果是数据修改同样可以监听到,存在是加入到dataWatchers里,同样可以监听到。
----------------------------------------------------
zookeeper客户端的一些细节问题

建立连接需要指定zookeeper集群的IP地址,SessionTimeout,默认的watcher。
在建立连接过程中根据集群的IP地址随机的选择一个地址,然后启动两个线程,一个做网络,一个处理事件回调的。
做网络线程SendThread建立网络连接是使用的非阻塞模式,当连接建立成功后,会把一个ConnectRequest包加入到
发送队列中,其中包括了客户端自己可能制定的sessionId, sessionPasswd,和自己指定的sessionTimeout,如果需要
验证信息的话,验证信息包也会加入到发送队列中。再到Selector上注册OP_READ|OP_WRITE事件;如果连接没建立
成功则等待Selector上OP_CONNECT事件,直到连接建立成功,进行上面提到的连接建立成功后的操作。
到目前为止ZooKeeper.States还是CONNECTING,接下来就是调用doIO()做读写操作,当前服务器是不会发送数据
过来的,故没有数据可读,当时发送队列里面已经包含至少一个数据包了,故将其发送出去。
接着就是读取服务器的对连接包和验证信息的响应数据了,首先会读取响应数据里面的negotiatedSessionTimeout值,
如果小于等于零,会做四件事,一是往事件队列里面添加Watcher.Event.KeeperState.Expired事件,再往事件队列里
面添加标记线程死亡的对象,三是抛出SessionExpiredException异常,再就是ZooKeeper.States=CLOSED,三让做
死循环逻辑的SendThread退到while语句处从而退出死循环,线程死掉。
如果negotiatedSessionTimeout是大于0的则进行本地逻辑数据的设置
readTimeout = negotiatedSessionTimeout * 2 / 3;
connectTimeout = negotiatedSessionTimeout / serverAddrs.size();
接着zooKeeper.state=CONNECTED。连接才真正建立成功,到这个点zookeeper提供的操作才可以使用。
接着SendThread走其正常的逻辑
--------------
1. 如果由于异常导致先前的连接断开,会重新走上面提到的建立连接的过程
2. 进行连接空闲事件或者READ空闲的事件的判断,如果zooKeeper.state不是CONNECTED,则用上次做写操作的
时间和当前时间的差值和connectTimeout作比较,如果大于的话会抛出SessionTimeoutException;如果上次
读的时间和当前时间差值大于readTimeout 同样抛出SessionTimeoutException,这样通知上层其正在做重连操作,
同时通知上层其正在等待响应的数据包和没有来得及发送的数据包。
3. 如果上次读的时间和当前时间差值大于readTimeout/2则会做发送PING数据包的操作。
4. 如果当前可读,则读取响应数据包,根据响应的数据类型进行处理,共分为四种,一种是对PING的响应;一种
是对于先前提到的验证的响应包,如果验证失败和Expired一样会导致SendThread退出;一种是NOTIFY数据包,
里面指定了路径和事件类型,根据上面提到的事件处理方式,往事件处理任务队列里添加这个事件给EventThread
线程处理;一种是用户操作返回的响应数据包,对于这种数据包要核对这个包的ID号和等待响应的数据包的队列的
第一个包的ID是否一致,如果一致则进行关于这个包的下一步的处理,如包含Watcher则加入到上面提到的Watcher
管理数据结构里面,再从等待响应的数据包的队列里移除,对于zookeeper数据结构的操作分为同步和异步,如果是
同步操作,提交操作数据包的线程还需要在此次唤醒,如果是异步则向事件处理任务队列里添加回调任务;如果ID
不一致则说明发送了错误,则抛出IOException异常,导致重新走上面提到的建立连接的过程。
zookeeper对于当个客户端提交的任务是FIFO的,用来保证其[sequential consistency for single client]。
5. 如果当前发送任务队列有数据则做发送操作,在发送时会为每个数据分配全局唯一的ID号,在发送完成后
将这个包移动到已经发送在等待回应的队列中去。
6. 做完IO后在回到1之前会进行是否退出的判断,如果zooKeeper.state是CLOSED|AUTH_FAILED会退出,否则回到1。
--------------
1. 在读取数据的过程中如果发送IO错误,或者逻辑错误而抛出的异常,都会被抓捕到,进行后续处理:
关闭当前的Socket的输入输出流和Socket,对于还在带发送队列里面和在已经发送出去的数据包,如果是同步
的需要唤醒这些提交包的线程,如果是异步的则将通知任务失败的任务提交到EventThread的任务队列里面,再
清除这两个队列。如果不是因为Expired或者验证失败则会通知默认的Watcher其重连,如果是因为这两个事件,
这个zookeeper对象已经不可用了,不会再重连了,客户端在接受到这两个事件时需要重新实例化zookeeper对象。
2. Watcher在被回调一次后会再 Watcher管理器中删除,如果想继续监听这个事件,需要继续注入。
3. 注意临时数据的问题,如果客户端创建了一个临时数据,然后重启了机器,在短时间内,这个时间跟服务器配置的
SESSIONTIMEOUT有关,是存在的,过了这个时间点就会消失,这个时间要注意。

分享到:
评论

相关推荐

    Zookeeper图形化客户端.zip

    Zookeeper图形化客户端.zip

    zookeeper 可视化、图形化展示工具 ZooInspector

    ZooInspector,工具图形化展示工具,zookeeper图形化的客户端工具(ZooInspector)。页面很形象,直观zookeeper 树节点

    ZooKeeper入门视频课程

    本课程以通俗易懂的方式讲解ZooKeeper技术,课程... 客户端操作、常用命令5. ZooKeeper集群(配置集群、集群特性、选举机制、监听机制) 6. Java访问ZooKeeper 教学全程采用笔记+代码案例的形式讲解,通俗易懂!!!

    新版Hadoop视频教程 段海涛老师Hadoop八天完全攻克Hadoop视频教程 Hadoop开发

    05-kafuka集群部署及客户端编程.avi 06-kafka消费者java客户端编程.avi 第八天 实战项目 01-项目背景及技术架构.avi 02-主要技术选型.avi 03-flume介绍及演示.avi 04-行为轨迹增强处理流程.avi 05-样本url...

    ECE419:ECE419S 2018分布式系统(云数据库)

    传统的一台服务器多客户端模型Key-Val数据库,其重点是套接字编程 介绍ECS(外部配置服务)和Apache ZooKeeper的概念。 服务器现在通过ZooKeeper与ECS进行通信,以进行初始化,启动,停止等操作。数据基于哈希环...

    Netty (netty-netty-4.1.74.Final.tar.gz)

    Netty (netty-netty-4.1.74.Final.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...

    JavaEE求职简历-姓名-JAVA开发工程师.doc

    熟练使用Java进行程序开发,有良好的编程思想和编码能力; 2.熟悉服务器、客户端、一般管理系统开发流程; 3.熟悉HTML、CSS、JS、jQuery、JSON、Ajax、easyUI、thymeleaf模板引擎; 4.熟练使用SSM框架进行项目开发;...

    rpcx:rpcx源码分析

    rpcx-gateway :您可以使用任何编程语言编写客户端,以通过调用rpcx服务http invoke :您可以使用相同的http请求访问rpcx网关Java客户端:您可以使用通过原始协议访问rpcx服务。 如果您可以编写Go方法,则还可以...

    kiwi:受kafka启发的简单消息队列

    Kiwi 为生产者和消费者公开了 http api,这使得将其集成到您的项目中变得更加容易,因为所有现代编程语言在 stdlib 中都有 http 客户端。入门项目用 Scala 编写并使用。 sbt assemblyjava -jar target/scala-2.11/...

    Fourinone分布式计算框架

    首先,对分布式协同方面,它实现了Zookeeper所有的功能,并且做了很多改进,包括简化Zookeeper的树型结构,用domain/node两层结构取代,简化Watch回调多线程等待编程模型,用更直观的容易保证业务逻辑完整性的内容...

    springboot+dubbo分布式架构,提供分布式缓存、分布式锁、分布式Session、读写分离

    - Java语言的分布式系统架构。 使用SpringBoot整合开源框架。 - 使用Maven对项目进行模块化管理,提高项目的易开发性、扩展性。 - 系统包括5个子模块:公共功能、平台管理、项目页面、统一管理平台、...适合接口编程。

    java8源码-SpringTree:互联网通用技术

    zookeeper mongodb kafka rocketmq memcached es lamda fork/join ThreadPool 微信支付 Elasticsearch 1:微信支付,暂时只支持公众号网页(调用微信客户端)支付,不支持二维码扫码支付 2:Lamda 函数式编程基础,...

    SpringAll_wuyouzhuguli.tar.gz

    Spring Boot 2.0 WebFlux编程 Spring Boot WebFlux增删改查样例 二、Spring Boot & Shiro教程 Spring Boot Shiro用户认证 Spring Boot Shiro Remember Me Spring Boot Shiro权限控制 Spring Boot Shiro Redis Spring...

    基于Python实现的一个简单的分布式高并发RPC框架+源代码+文档说明

    &gt; + 实现同样的功能,Python的代码量相较于C/C++要少很多,减少编程难度 ### 三、这个是原创的吗? &gt; + 永远站在巨人的肩膀之上,学习他人的代码,消化吸收,据为己用 ### 四、划重点 &gt; + 分布式和高并发是如何...

    Hyperf 协程框架 v2.1.10

    Jaeger) 客户端、Guzzle HTTP 客户端、Elasticsearch 客户端、Consul 客户端、ETCD 客户端、AMQP 组件、Nats 组件、Apollo、ETCD、Zookeeper 和阿里云 ACM 的配置中心、基于令牌桶算法的限流器、通用连接池、熔断器...

    微信小程序购物商城app设计带Java后端+sql数据库(毕业设计).zip

    【资源说明】 该项目代码主要针对计算机、自动化等相关专业的学生从业者下载使用,项目代码都经过严格调试,确保可以运行!...## web端技术: SpringMVC + Spring + Mybatis + Dubbo + Zookeeper + Redis

    Fourinone分布式并行计算四合一框架

     首先,对分布式协同方面,它实现了Zookeeper所有的功能,并且做了很多改进,包括简化Zookeeper的树型结构,用domain/node两层结构取代,简化Watch回调多线程等待编程模型,用更直观的容易保证业务逻辑完整性的内容...

    fourinone-3.04.25

    首先,对分布式协同方面,它实现了Zookeeper所有的功能,并且做了很多改进,包括简化Zookeeper的树型结构,用domain/node两层结构取代,简化Watch回调多线程等待编程模型,用更直观的容易保证业务逻辑完整性的内容...

    springCloud

    不同服务通过一些轻量级交互机制来通信,例如 RPC、HTTP 等,服务可独立扩展伸缩,每个服务定义了明确的边界,不同的服务甚至可以采用不同的编程语言来实现,由独立的团队来维护。简单的来说,一个系统的不同模块...

Global site tag (gtag.js) - Google Analytics