分布式文件系统?
/data/host1
, /data/host2
, 这个路径也可以理解为是 Znode 的 Name/data/host1
, 其值是一个字符串 "192.168.0.1"
Zookeeper 是分布式的
首先呢, Zookeeper 是分为服务端和客户端的, 客户端有 Java 的客户端, 有 Shell 命令行的客户端等, 客户端通过一个类似于文件系统的 API 来访问 Zookeeper 集群
但是事实上, 客户端最终是直接访问 Zookeeper 集群, 集群中有两大类角色, 一类是 Leader, 一类是 Follower, 其实就是主从, Leader 负责读和写, Follower 只能读, 遇到会产生修改的请求会转发给 Leader 处理, 这是因为 Zookeeper 本质上就是为了在分布式环境中对消息的一致性的支持, 而 Zookeeper 所基于的 ZAB 协议是 Paxos 协议的一个变种, ZAB 协议中是有一个全局的事务生成者, 就是 Leader, 修改设计到在分布式环境下对事务达成一致, 必须由 Leader 发起
举个例子?
比如说一个常见的分布式主从系统, 如果有 ZK 在的话, 主节点不需要和每个从节点保持连接, 只需要监听从节点创建的 Znode, 便可以知道谁在线
Zookeeper 能做什么?
服务器IP | 主机名 | myid的值 |
---|---|---|
192.168.174.100 | node01 | 1 |
192.168.174.110 | node02 | 2 |
192.168.174.120 | node03 | 3 |
第一步:下载zookeeeper的压缩包,下载网址如下
http://archive.apache.org/dist/zookeeper/
我们在这个网址下载我们使用的zk版本为3.4.9
下载完成之后,上传到我们的linux的/export/softwares路径下准备进行安装
第二步:解压
解压zookeeper的压缩包到/export/servers路径下去,然后准备进行安装
cd /export/software
tar -zxvf zookeeper-3.4.9.tar.gz -C ../servers/
第三步:修改配置文件
第一台机器修改配置文件
cd /export/servers/zookeeper-3.4.9/conf/
cp zoo_sample.cfg zoo.cfg
mkdir -p /export/servers/zookeeper-3.4.9/zkdatas/
vim zoo.cfg
dataDir=/export/servers/zookeeper-3.4.9/zkdatas
# 保留多少个快照
autopurge.snapRetainCount=3
# 日志多少小时清理一次
autopurge.purgeInterval=1
# 集群中服务器地址
server.1=node01:2888:3888
server.2=node02:2888:3888
server.3=node03:2888:3888
第四步:添加myid配置
在第一台机器的
/export/servers/zookeeper-3.4.9/zkdatas /这个路径下创建一个文件,文件名为myid ,文件内容为1
echo 1 > /export/servers/zookeeper-3.4.9/zkdatas/myid
第五步:安装包分发并修改myid的值
安装包分发到其他机器
第一台机器上面执行以下两个命令
scp -r /export/servers/zookeeper-3.4.9/ node02:/export/servers/
scp -r /export/servers/zookeeper-3.4.9/ node03:/export/servers/
第二台机器上修改myid的值为2
echo 2 > /export/servers/zookeeper-3.4.9/zkdatas/myid
第三台机器上修改myid的值为3
echo 3 > /export/servers/zookeeper-3.4.9/zkdatas/myid
第六步:三台机器启动zookeeper服务
三台机器启动zookeeper服务
这个命令三台机器都要执行
/export/servers/zookeeper-3.4.9/bin/zkServer.sh start
查看启动状态
/export/servers/zookeeper-3.4.9/bin/zkServer.sh status
命令 | 说明 | 参数 |
---|---|---|
create [-s] [-e] path data acl | 创建Znode | -s 指定是顺序节点-e 指定是临时节点 |
ls path [watch] | 列出Path下所有子Znode | |
get path [watch] | 获取Path对应的Znode的数据和属性 | |
ls2 path [watch] | 查看Path下所有子Znode以及子Znode的属性 | |
set path data [version] | 更新节点 | version 数据版本 |
delete path [version] | 删除节点, 如果要删除的节点有子Znode则无法删除 | version 数据版本 |
rmr path | 删除节点, 如果有子Znode则递归删除 | |
setquota -n|-b val path | 修改Znode配额 | -n 设置子节点最大个数-b 设置节点数据最大长度 |
history | 列出历史记录 |
1:创建普通节点
create /app1 hello
2: 创建顺序节点
create -s /app3 world
3:创建临时节点
create -e /tempnode world
4:创建顺序的临时节点
create -s -e /tempnode2 aaa
5:获取节点数据
get /app1
6:修改节点数据
set /app1 xxx
7:删除节点
delete /app1 删除的节点不能有子节点
rmr /app1 递归删除
Znode 的特点
Znode
Znode
, 需要使用路径的形式, 例如 /test1/test11
Znode
中数据是有大小限制的, 最大只能为1M
Znode
是由三个部分构成 stat
: 状态, Znode的权限信息, 版本等data
: 数据, 每个Znode都是可以携带数据的, 无论是否有子节点children
: 子节点列表Znode 的类型
Znode
有两大特性, 可以构成四种不同类型的Znode
持久
客户端断开时, 不会删除持有的Znode临时
客户端断开时, 删除所有持有的Znode, 临时Znode不允许有子Znode有序
创建的Znode有先后顺序, 顺序就是在后面追加一个序列号, 序列号是由父节点管理的自增无序
创建的Znode没有先后顺序Znode
的属性 dataVersion
数据版本, 每次当Znode
中的数据发生变化的时候, dataVersion
都会自增一下cversion
节点版本, 每次当Znode
的节点发生变化的时候, cversion
都会自增aclVersion
ACL(Access Control List)
的版本号, 当Znode
的权限信息发生变化的时候aclVersion会自增zxid
事务IDctime
创建时间mtime
最近一次更新的时间ephemeralOwner
如果Znode
为临时节点, ephemeralOwner
表示与该节点关联的SessionId
通知机制
Watcher
, 当Znode发生变化的时候, WatchManager
会调用对应的Watcher
Watcher
会得到通知Watcher
的特点 Watcher
只会被触发一次, 如果需要继续监听, 则需要再次添加 Watcher
Watcher
得到的事件是被封装过的, 包括三个内容 keeperState, eventType, path
KeeperState | EventType | 触发条件 | 说明 |
---|---|---|---|
None | 连接成功 | ||
SyncConnected | NodeCreated | Znode被创建 | 此时处于连接状态 |
SyncConnected | NodeDeleted | Znode被删除 | 此时处于连接状态 |
SyncConnected | NodeDataChanged | Znode数据被改变 | 此时处于连接状态 |
SyncConnected | NodeChildChanged | Znode的子Znode数据被改变 | 此时处于连接状态 |
Disconnected | None | 客户端和服务端断开连接 | 此时客户端和服务器处于断开连接状态 |
Expired | None | 会话超时 | 会收到一个SessionExpiredException |
AuthFailed | None | 权限验证失败 | 会收到一个AuthFailedException |
会话
Session
中的, 客户端和服务器创建一个连接的时候同时也会创建一个Session
Session
会在不同的状态之间进行切换: CONNECTING
, CONNECTED
, RECONNECTING
, RECONNECTED
, CLOSED