第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】

概述:

前面主要了解分布式理论,Zookeeper出现原因,正式学习Zookeeper,如何实现原生分布式。

1、Zookeeper Basics(Zookeeper基础)

很多应用其实可以暴露原始引用。这样缺点就是1、穷举所有原始引用,2、可扩展性不强    (类似java的类)

Zookeeper并不会暴露所有原始引用。而提供API接口,具体实现不管(类似java的接口)

操作最小数据节点称为znodes,它可以组织成一棵树

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】


本图截取Zookeeper书籍中。

/workers znode是所有工作者的根节点,如果子节点异常将会被移除

/tasks znode 是所有任务的根节点

/assign znode 是所有任务委派节点,只要将任务委派给一个工作者将会增加一个子节点

API Overview(API预览)

Znodes保存数据是字节数组,Zookeeper不直接提供解析字节数组包,关于序列化包有Protocol Buffer是, Thrift,Avro和MessagePack.

Zookeeper操作API

create /path data

创建一个znode名称为/path 数据为data

delete /path

删除 一个节点名称为/path

exists /path

判断 /path 节点是否存在

setData /path data

设置 节点/path的 值为data

getData /path

返回/path节点的数据

getChildren /path

返回一系列/path节点的子节点

注意:Zookeeper不允许部分写或读取节点数据

2、不同模式下znode

持久节点和瞬时节点

持久节点可以通过delete方法就行删除,瞬时节点不可以,它只能它自身奔溃或关闭连接Zookeeper

持久节点的好处就是能够保存应用在该节点进行所有操作信息。

瞬时节点:类似会话,只要会话结束,这个节点就结束了。这个一般用于工作者(worker),当工作者会话失效的时候会自动消失。

一般瞬时节点不会创建子节点。

sequential znode(时序节点)

也就是自动增加整数序列来创建独一无二节点。

总结四种节点模式:ephemeral(瞬时节点)、persistent(持久节点)、persistent_sequential(持久时序节点)、ephemeral_sequential(瞬时时序节点)

3、Watches and Notifications (观察和通知)

打比喻:例如你是否有拿快递经历,你到快递公司拿快递的时候,快递小哥告诉你还没到,你等明天再来拿,发现明天还没到,你是不是骂娘了。这几次是不是白跑了,你就直接跟快递小哥说快递到了打电话给我就行,省的每次跑。刚开始你主动,到后来你被动

Zookeeper也类似,它会取一次数据,发现没有,这时候注册一个观察者,如果有改变就立即通知我。

4、Versions(版本)

只有setDatadelete才会触发版本号增加

用版本号来避免并发数据不一致性。

  • 1、客户端C1写了第一个配置信息是版本号为1
  • 2、客户端C2读取配置信息时版本号为1,同时设置版本号为2
  • 3、客户端C1再次尝试改变配置文件,发现版本号2,表示已经被人改变,这时候就修改失败。

5、Zookeeper Architecture(Zookeeper架构)

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】

运行Zookeeper 服务器有两种模式:一种是单例,一种quorum(一组服务器)

一组服务器称为Zookeeper ensemble(Zookeeper集群)

6、Zookeeper Quorums(Zookeeper服务器群)

在更新数据的时候,并不需要等所有Zookeeper服务器都更新这个数据,只要保证最低数量服务器更新即可。类似投票选举,只要一方比另一方多一票,多一票将获胜,也就是服务更新数量至少比还没有更新多一台服务器。这样才能说更新数据成功。没有更新服务器可以在随后进行更新。

例如5台服务器,至少3台更新成功,也就是容许两台服务器down机,但是如果四台服务器只能允许一台down机

7、Sessions(会话)

所有操作都是通过客户端与服务端建立会话完成的

会话可以保证有序性,也就是它遵循FIFO(先进先出),但是如果一个客户端发起多个会话就不能保证有序性

例如:

  • 客户端创建一个会话有两个异步调用create /tasks 和 /workers
  • 第一个会话失效
  • 客户端建立另个会话,然后执行异步调用 create /assign

以上过程将可能产生可能的结果是只有/tasks和/assign被执行创建了。所以说有序性只是在单个会话中,而不是跨多个会话

8、开始使用Zookeeper

下载Zookeeper软件

官网地址, 给一个镜像下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.10/

使用window系统,下载完解压,(需要装jdk然后配置java环境变量,可以自行百度)

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】

可执行文件.sh表示Linux系统,.cmd表示window可执行文件

9、第一个Zookeeper会话

启动单例模式下Zookeeper然后创建会话,为了完成需要使用bin目录下的zkCli.cmd(客户端)和zkServer.cmd(服务端)

第一步复制配置文件zoo_sample.cfg并修改文件名为zoo.cfg

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】

第二步启动服务器也就打开zkServer.cmd (注意确定自己已经配置java环境)

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】


第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】

第三步启动客户端也就打开zKCli.cmd

不要关闭这个上面窗口,继续上面操作,执行客户端文件(zkCli.cmd)

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】


分析zkCli.cmd窗口的日志

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】


第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】


10、States and the Lifetime of a Session (一个会话的生命周期和状态)

会话状态和转换

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】

本图摘自Zookeeper书籍

一个会话首先初始化Zookeeper客户端是未连接状态转换为连接中(也就是1号),正常情况下,连接上Zookeeper服务器成功之后会话的状态转换为已连接(2号),当客户端与服务端断开连接,会话状态转换为连接中(箭头3)然后尝试去找其他Zookeeper服务器。如果找其他Zookeeper服务器或者重新连接成功,这时候状态转换为已连接(只要会话仍然有效),否则如果是失效将会转为已关闭状态(4号),客户端可以主动关闭会话(4号或5号)。

一个重要会话参数--会话超时:就是在一段时间内没有进行通讯的t,将会自动结束会话,客户端如果1/3t时间没有收到服务器端消息,将会主动发送心跳包,如果没有回复在2/3t之后将会寻找不同服务器。

注意:在重连之后保证连接服务器是最新的,也就是Zookeeper服务器已经知道客户端已经更新过了。

第二章 Getting to Grips with ZooKeeper(开始掌握Zookeeper)【上】