Zookeeper分布式技术

1.CAP表示: 一致性(Consistency),可用性(Availability)和分区容错性(Partition tolerance);

2.API概述
create /path data
创建一个名为/path的znode节点,并包含数据data
delete /path
删除一个名为/path的znode
exists /path
检查是否存在一个名为/path的节点
setData /path data
设置名为/path的节点的数据为data
getData /path
获取节点/path的节点信息
getChildren /path
获取节点/path下的所有子节点列表

当设置一个znode节点的数据或读取时,znode节点的数据会被全部替换或读取。

新建znode节点时,应当指定节点的类型,不同的节点的不同行为。znode有四种类型:持久的(persistent),临时的(ephemeral),持久有序的(persistent-sequential),临时有序的(ephemeral-sequential)。
持久的znode只能通过调用delete来删除,临时的znode节点,当创建该节点的客户端崩溃或关闭和zookeeper的连接时,节点就会删除。

3.监视和通知:
假定事件的发生顺序:
1客户端c1设置监控点来监控/task数据变化;
2客户端c2连接后向/task添加新任务;
3客户端c1接受到通知
4客户端c1设置新的监控点,在设置完成前,第三个客户端c3连接上来,向/task添加一个任务
客户端c1设置了一个新的监控点,由c3添加的任务并没有触发通知。在设置监控点前,需要读取节点的状态,因此c1不会错过任何变更。

对同一个znode操作,先向客户端发送通知,再对节点进行变更。

4.版本
每一个znode都有一个版本号,随着每次数据变化而递增。用来阻止并行操作的不一致性。

5.zookeeper架构
zookeeper服务器端运行于两种模式下:独立模式和仲裁模式
仲裁模式下,有一组zookeeper服务器,他们之间可以进行状态的复制;如果让一个客户端等待每个服务器完成数据保存后再继续,延迟问题就无法解决。
法定人数指zookeeper工作必须运行的服务器的最少数量。法定人数的数量要保证不管系统发生延迟或崩溃,服务主动确认的任何更新请求需要保持下去,直到另一个请求代替它。

6.会话
对zookeeper集合执行任何请求前,一个客户端必须和服务建立会话。
同一个会话的请求会以FIFO顺序执行

7.第一个zookeeper会话
进入conf文件夹下将zoo_sample.cfg 复制一份命名为 zoo.cfg;
在zoo.cfg文件中修改这个目录的位置:dataDir=f:/users/me/zookeeper
启动zkServer.cmd
启动客户端zkCli.cmd
要确认znode树为空,除了节点/zookeeper外。
使用命令ls /
创建一个名为/workers的节点 create /workers “”
删除节点delete /workers
退出zookeeper服务器 quit

8.会话的状态和生命周期
会话的状态:connecting, connected, closed, not_connected
状态的转换依赖于发生在客户端和服务之间的各种事件
一个会话从not_connected开始,客户端初始化连接后,转换到connecting,
成功建立连接,状态转换成connected,如果断开连接或无响应,状态转换成connecting;会话过期或关闭会话,状态转换成closed
创建一个会话时,你需要设置会话超时这个重要的参数,这个参数 设置了ZooKeeper服务允许会话被声明为超时之前存在的时间。

9.仲裁模式
可以在一个机器上运行多个服务器,使用以下配置:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=f:/data/z1
clientPort=2181
server.1=127.0.0.1:2222:2223
server.2=127.0.0.1:3333:3334
server.3=127.0.0.1:4444:4445
将zookeeper文件复制2份,配置修改dataDir=f:/data/z2 dataDir=f:/data/z3
clientPort=2182 clientPort=2183
在F盘下创建路径data/z1, data/z2 , data/z3
并分别在路径下创建文件myid, 其中z1下的myid输入1,z2下的myid输入2,z3下的myid输入3
相继启动zkServer.cmd, 开始会报错,3个服务全部启动后,就好了。

10.通过ZooKeeper实现锁
每个进程p尝试创建znode名为/lock, 如果成功创建znode表示它获得了锁并可以执行临界区的代码。为了避免进程p崩溃导致锁无法释放,引发系统因死锁而失灵,必须指定节点/lock为临时节点。
其他进程因znode存在而创建/lock失败。因此,进程监听/lock的变化,并在检测到/lock删除时再次尝试创建节点来获得锁。当收到/lock删 除的通知时,如果进程p还需要继续获取锁,它就继续尝试创建/lock的步骤,如果其他进程已经创建了,就继续监听节点。

11.一个主-从模式例子
主-从模式的模型中包括三个角色:
1主节点:主节点负责监视新的从节点和任务,分配任务给可用的从节点
2从节点:从节点会通过系统注册自己,以确保主节点看到它们可以执行任
务,然后开始监视新任务。
3客户端:客户端创建新任务并等待系统的响应

主节点角色:
create -e /master "master1.example.com:2223
创建主节点的znode,以便获得管理权。使用-e标志来表示创建的 znode为临时性的。
ls / 列出ZooKeeper树的根。
get /master 获取/master znode的元数据和数据。
再次尝试创建 create -e /master “abc”
提示Node already exists: /master

为了检测主节点可能发生的崩溃情况,需要在/master设置监视点。
stat /master true
创建/master的客户端关闭 quit
另一个客户端显示WatchedEvent state:SyncConnected type:NodeDeleted path:/master
再次创建create -e /master “” 创建成功

创建三个 重要的父znode,/workers、/tasks和/assign:
create /workers “”
create /tasks “”
create /assign “”
在主节点上调用stat命令前,我们使用可选的true参数调用 ls命令。通过true这个参数,可以设置对应znode的子节点变化的监视点。
主节点(主客户端)
ls /tasks
ls /workers
ls /assign
stat /tasks
stat / workers
stat /assign
从节点通过 在/workers子节点下创建临时性的znode来进行通知,并在子节点中使用
主机名来标识自己:create -e /workers/worker1.example.com “worker1.example.com:2224
之前主节点已经监 视了/workers的子节点变化情况。一旦从节点在/workers下创建了一个 znode,主节点就会观察到以下通知信息:
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/workers

从节点需要创建一个父znode/assign/worker1.example.com 来接收任务分配,并通过第二个参数为true的ls命令来监视这个节点的变化,以便等待新的任务
create /assign/worker1.example.com “”
ls /assign/worker1.example.com true

开启一个客户端,创建一个任务
create -s /tasks/task- “cmd”
ls /tasks/task-0000000000 true
我们需要按照任务添加的顺序来添加znode,其本质上为一个队列。客户端现在必须等待任务执行完毕。执行任务的从节点将任务执行 完毕后,会创建一个znode来表示任务状态。客户端通过查看任务状态 的znode是否创建来确定任务是否执行完毕,因此客户端需要监视状态 znode的创建事件。

一旦创建任务的znode,主节点会观察到以下事件:
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks
主节点之后会检查这个新的任务,获取可用的从节点列表,之后分 配这个任务给worker1.example.com
create /assign/worker1.example.com/task-0000000000 “”
从节点接收到新任务分配的通知:
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/assign/worker1.example.com
从节点之后便开始检查新任务,并确认该任务是否分配给自己:
ls /assign/worker1.example.com
一旦从节点完成任务的执行,它就会在/tasks中添加一个状态 znode:
create /tasks/task-0000000000/status “done”
之后,客户端接收到通知,并检查执行结果:
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks/task-0000000000
执行命令get /tasks/task-0000000000/status
看到任务成功执行,其状态为“done”。

猜你喜欢

转载自blog.csdn.net/zhanglinlove/article/details/83412645