文章目录
- Zookeeper
-
- 一、zk简介
- 二、数据模型
-
- 2.1、模型结构
- 2.2、模型的特点
- 2.3、节点的分类
-
- 2.3.1、持久节点(PERSISTENT)
- 2.3.2、持久顺序节点(PERSISTENT_SEQUENTIAL)
- 2.3.3、临时节点(EPHEMERAL)
- 2.3.4、临时顺序节点(EPHEMERAL_SEQUENTIAL)
- 三、安装
-
- 3.1、linux系统安装
- 3.2、docker安装zookeeper
- 3.3、配置文件详解
- 四、客户端基本指令
- 五、节点监听机制 watch
- 六、java 操作 ZK
- 七、zk的集群
-
- 7.1、集群
- 7.2、集群架构
- 7.3、集群搭建
- 7.4、操作zk集群
Zookeeper
一、zk简介
Zookeeper(动物园管理者)简称ZK,一个分布式的,开发源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组装件。Zookeeper使用Java所编写,但是支持 Java 和 C 两种编程语言。
二、数据模型
2.1、模型结构
2.2、模型的特点
- 每个子目录如 /node1 都被称作一个 znode(节点)。这个znode是它所在的路径唯一标识
- znode可以有子节点目录,并且每个znode可以存储数据
- znode 是有版本的,每个znode中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据
- znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端
2.3、节点的分类
2.3.1、持久节点(PERSISTENT)
是指在节点创建后,就一直存在,直到有删除操作来主动删除这个节点——不会因为创建该节点的客户端失效而消失。
2.3.2、持久顺序节点(PERSISTENT_SEQUENTIAL)
该类节点的基本特征和上面的结点类型是一致的。额外的特性是,在zk中 ,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。基于这个特性,在创建子节点的时候,可以设置个属性,那么在创建节点过程中,ZK会自动为给定接节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。
2.3.3、临时节点(EPHEMERAL)
和持久节点不同的是,临时节点的生命周期和客户端会话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉。注意,这一提到的是会话失效,而非连接断开。另外,咋临时节点下面不能创建子节点。
2.3.4、临时顺序节点(EPHEMERAL_SEQUENTIAL)
具有临时节点特点,额外的特性是,每个父节点会为他的第一级子节点维护一份时序。这点和刚才提到的持久顺序节点类似。
三、安装
3.1、linux系统安装
# 1.安装jdk并配置环境变量 & 下载 zk安装包
- https://dlcdn.apache.org/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz
# 2.下载安装包上传到linux中,并解压缩
- tar -zxvf zookeeper-3.6.3.tar.gz
# 3.重命名安装目录
- mv zookeeper-3.6.3 zk
# 4.配置zoo.cfg配置文件
- 1.修改zk的conf目录下的zoo_sample.cfg,修改完后,重命名为zoo.cfg
tickTime=2000
initLimit=10
syncLimit=4
dataDir=/usr/zookeeper/zkdata
clientPort=2181
# 5.启动zk
- 在zk的bin目录下,运行zkServer.sh
./bin/zkServer.sh start /usr/zookeepe/conf/zoo.cfg
# 6.使用jsp查看启动是否成功
# 7.启动客户端连接到zk
- ./bin/zkCli.sh -server 192.168.0.220:2181
注意:可以通过 ./bin/zkCli.sh help 查看客户端所有可以执行的命令
3.2、docker安装zookeeper
# 1.获取zk镜像
- docker pull zookeeper:3.4.14
# 2.启动zk服务
- docker run --name zk -p 2181:2181 -d zookeeper:3.4.14
3.3、配置文件详解
# The number of milliseconds of each tick 心跳停止的最长时间2s
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10 # 初始化集群时集群节点同步超时时间
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5 # 集群在运行过程中同步数据超时时间
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper # 默认数据存储位置
# the port at which the clients will connect
clientPort=2181 # 服务监听端口号
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60 # 线程池数量
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3 # 这个参数和下面的参数搭配使用,这个参数指定了需要保留的文件数目。默认是保留3个。
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1 # 3.4.0及之后版本,ZK提供了自动清理事务日志和快照文件的功能,这个参数指定了清理频率,单位是小时,需要配置一个1或更大的整数,默认是0,表示不开启自动清理功能。
四、客户端基本指令
# 1. ls path 查看特定节点下面的子节点
# 2. create path data 创建一个节点,并给节点绑定数据(默认是持久性节点)
- create path data 创建持久节点(默认是持久节点)
- create -s path data 创建持久顺序节点
- create -e path data 创建临时性节点(注意:临时节点不能含有任何子节点)
- create -e -s path data 创建临时顺序节点(注意:临时节点不能含有任何子节点)
# 3. stat path 查看节点状态
# 4. set path data 修改节点数据
# 5. ls2 path 查看节点下孩子和当前节点的状态
# 6. history 查看操作历史
# 7. get path 获得节点上绑定的数据信息
# 8. delete path 删除节点(注意:删除节点不能含有子节点)
# 9. rmr path 递归删除节点(注意:会将当前节点下所有节点删除)
# 10. quit 退出当前会话(会话失败)
五、节点监听机制 watch
客户端可以检测znode节3点的变化。Znode节点的变化触发相应的事件,然后清除对该节点的监测。当检测一个znode节点时候,Zookeeper会发送通知给监测节点。一个Watch事件是一个一次性的触发器,当被设置了Watch的数据和目录发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端以便通知他们。
# 1. ls /path true 监听节点目录的变化
# 2. get /path true 监听节点数据的变化
六、java 操作 ZK
引入依赖
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
常见API操作
public class TestZKClient {
private ZkClient zkClient;
@Before()
public void before() {
zkClient = new ZkClient("10.15.0.5:2181", 6000 * 30, 6000, new SerializableSerializer());
}
@Test
public void createNode() throws IOException {
// 1.创建节点
// 1. 持久性节点
zkClient.create("/node1", "zhangsan", CreateMode.PERSISTENT);
// 2. 持久顺序节点
zkClient.create("/node2", "lisi", CreateMode.PERSISTENT_SEQUENTIAL);
// 3. 临时性节点
zkClient.create("/node3", "wangwu", CreateMode.EPHEMERAL);
// 4. 临时顺序节点
zkClient.create("node4", "xiaochen", CreateMode.EPHEMERAL_SEQUENTIAL);
// 2.删除没有子节点的节点
boolean delete = zkClient.delete("/node1");
// 3.递归删除节点信息
boolean recursive = zkClient.deleteRecursive("/node1");
System.out.println(recursive);
// 4.查询当前节点下的所有子节点
List<String> children = zkClient.getChildren("/node1");
for (String child : children) {
System.out.println(child);
}
// 5.查看某个节点数据 注意:通过java客户端操作需要保证节点存储的数据和获取数据的序列化方式一致
Object readData = zkClient.readData("/node1");
System.out.println(readData);
// 6.查看节点状态信息
Stat stat = new Stat();
Object readData1 = zkClient.readData("/node1", stat);
System.out.println(readData1);
System.out.println(stat.getVersion());
System.out.println(stat.getCtime());
System.out.println(stat.getCzxid());
// 7.修改节点数据
User user = new User();
user.setId(1);
user.setName("xiaochen");
user.setAge(23);
user.setBir(new Date());
zkClient.writeData("/node1", user);
User o = zkClient.readData("/node1");
System.out.println(o.getId() + " " + o.getName() + " " + o.getAge() + " " + o.getBir() + " ");
// 8.监听节点数据变化
zkClient.subscribeDataChanges("/node1", new IZkDataListener() {
// 当前节点数据变化时触发对应这个方法
@Override
public void handleDataChange(String s, Object o) throws Exception {
System.out.println("当前节点路径:" + s);
System.out.println("当前节点变化后数据:" + o);
}
// 当前节点删除时触发这个方法
@Override
public void handleDataDeleted(String s) throws Exception {
System.out.println("当前节点路径:" + s);
}
});
System.in.read();
// 9.监听节点目录变化
zkClient.subscribeChildChanges("/node1", new IZkChildListener() {
// 当节点发生变化时,会自动调用这个方法
@Override
public void handleChildChange(String s, List<String> list) throws Exception {
System.out.println("父节点名称:" + s);
System.out.println("发生变更后字节孩子结点名称:");
for (String name : list) {
System.out.println(name);
}
}
});
System.in.read();
}
@After()
public void after() {
zkClient.close();
}
}
七、zk的集群
7.1、集群
# 1.集群
- 集合同一软件服务的多个结点同时提供服务
# 2.集群解决问题
- 单节点的并发访问的压力问题
- 单节点故障问题(如硬件老化,自然灾害等)
7.2、集群架构
7.3、集群搭建
# 1.创建三个dataDir
- mkdir zkData1 zkData2 zkData3
# 2.分别在三个dataDir目录下面创建myid文件
- touch zkData1/myid zkData2/myid zkData3/myid
# 3.在myid文件下分别写入 1|2|3
- echo "1" >> zkData1/myid
- echo "2" >> zkData2/myid
- echo "3" >> zkData3/myid
# 4.分别在/conf目录下创建zk配置文件zoo.cfg
- zoo1.cfg
tickTimetickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper/zkData1
clientPort=3001
server.1=192.168.10.3:3002:3003
server.2=192.168.10.3:4002:4003
server.3=192.168.10.3:5002:5003
- zoo2.cfg
tickTimetickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper/zkData2
clientPort=3002
server.1=192.168.10.3:3002:3003
server.2=192.168.10.3:4002:4003
server.3=192.168.10.3:5002:5003
- zoo3.cfg
tickTimetickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper/zkData3
clientPort=3003
server.1=192.168.10.3:3002:3003
server.2=192.168.10.3:4002:4003
server.3=192.168.10.3:5002:5003
解释:
1.server.x x为服务器的唯一标识
2.192.168.10.3 服务器所在的ip地址
3.3002 数据同步使用的端口号
4.3003 选举使用的端口号
# 4.分别启动各个zk服务器
- ./bin/zkServer.sh start /tmp/zookeeper/conf/zoo1.cfg
- ./bin/zkServer.sh start /tmp/zookeeper/conf/zoo2.cfg
- ./bin/zkServer.sh start /tmp/zookeeper/conf/zoo3.cfg
# 5.查看各个zk服务器的角色信息
- ./bin/zkServer.sh status /user/zookeeper/conf/zoo1.cfg
# 6.客户端连接任意zk服务器进行节点操作
- ./bin/zkCli.sh -server 192.168.0.220:3001
# 7.停止特定zk服务器
- ./bin/zkServer.sh stop /usr/zookeeper/conf/zoo1.cfg
7.4、操作zk集群
@Before()
public void before() {
zkClient = new ZkClient("10.15.0.5:3001,10.15.0.5:3002,10.15.0.5:3003", 6000 * 30, 6000, new SerializableSerializer());
}
相关文章
暂无评论...