1 Zookeeper 的概述
Zookeeper 是一个开源的分布式协调服务框架 ,主要用来解决分布式集群中应用系统的
一致性问题和数据管理问题
2:Zookeeper的特点
Zookeeper 本质上是一个分布式文件系统, 适合存放小文件,也可以理解为一个数据库
Zookeeper 中存储的其实是一个又一个 Znode, Znode 是 Zookeeper 中的节点
Znode 是有路径的, 例如 /data/host1 , /data/host2 , 这个路径也可以理解为是Znode 的 Name
Znode 也可以携带数据, 例如说某个 Znode 的路径是 /data/host1 , 其值是一个字符串 "192.168.0.1"
正因为 Znode 的特性, 所以 Zookeeper 可以对外提供出一个类似于文件系统的试图, 可以通过操作文件系统的方式操作 Zookeeper
使用路径获取 Znode
获取 Znode 携带的数据
修改 Znode 携带的数据
删除 Znode
添加 Znode
3.Zookeeper安装
服务器IP
|
主机名 |
myid的值
|
192.168.100.100 |
node01
|
1 |
192.168.100.110 |
node02
|
2 |
192.168.100.120 |
node03
|
3 |
第一步:下载zookeeeper的压缩包,下载网址如下(3.4.9版本)
http://archive.apache.org/dist/zookeeper/
下载完成之后,上传到我们的linux的/export/soxwares路径下准备进行安装
第二步:解压
解压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
第五步:安装包分发并修改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
第三台机器上修改myid的值为3
第六步:三台机器启动zookeeper服务
三台机器启动zookeeper服务
这个命令三台机器都要执行
/export/servers/zookeeper-3.4.9/bin/zkServer.sh start
查看启动状态
/export/servers/zookeeper-3.4.9/bin/zkServer.sh status
4.zookeeper的JavaAPI操作
这里操作Zookeeper的JavaAPI使用的是一套zookeeper客户端框架 Curator ,解决了很多Zookeeper客户端非常底层的细节开发工作 。
Curator包含了几个包:
curator-framework:对zookeeper的底层api的一些封装
curator-recipes:封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式计数器等
Maven依赖(使用curator的版本:2.12.0,对应Zookeeper的版本为:3.4.x,如果跨版本会有兼容性问题,很有可能导致节点操作失败)
<dependencies> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.12.0</version> </dependency> <dependency> <groupId>com.google.collections</groupId> <artifactId>google-collections</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> </dependency> </dependencies> <build> <plugins> <!-- java编译插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
package com.ytkj.zookeeper; import org.apache.curator.RetryPolicy; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.cache.ChildData; import org.apache.curator.framework.recipes.cache.TreeCache; import org.apache.curator.framework.recipes.cache.TreeCacheEvent; import org.apache.curator.framework.recipes.cache.TreeCacheListener; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.zookeeper.CreateMode; import org.junit.Test; public class ZookeeperApiTest { /** * PERSISTENT:永久节点 * EPHEMERAL:临时节点 * PERSISTENT_SEQUENTIAL:永久节点、序列化 * EPHEMERAL_SEQUENTIAL:临时节点、序列化 */ /** * 创建永久节点 * * @throws Exception */ @Test public void createZnode() throws Exception { //定制重试策略 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 1); //获取客户端对象 String connectString = "192.168.100.100:2181,192.168.100.110:2181,192.168.100.120:2181"; CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, 8000, 8000, retryPolicy); //开启客户端 client.start(); //创建节点 client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/hello1", "world".getBytes()); //关闭客户端 client.close(); } /* 创建临时节点 */ @Test public void createTmpZnode() throws Exception { //1:定制一个重试策略 /* param1: 重试的间隔时间 param2:重试的最大次数 */ RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 1); //2:获取一个客户端对象 /* param1:要连接的Zookeeper服务器列表 param2:会话的超时时间 param3:链接超时时间 param4:重试策略 */ String connectionStr = "192.168.100.100:2181,192.168.100.110:2181,192.168.100.120:2181"; CuratorFramework client = CuratorFrameworkFactory.newClient(connectionStr, 8000, 8000, retryPolicy); //3:开启客户端 client.start(); //4:创建节点 client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/hello2", "world".getBytes()); //临时节点 会话结束就临时节点就消失 Thread.sleep(5000); //5:关闭客户端 client.close(); } /* 设置节点数据 */ @Test public void setZnodeData() throws Exception { //1:定制一个重试策略 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 1); //2:获取客户端 String conectionStr = "192.168.100.100:2181,192.168.100.110:2181,192.168.100.120:2181"; CuratorFramework client = CuratorFrameworkFactory.newClient(conectionStr, 8000, 8000, retryPolicy); //3:启动客户端 client.start(); //4:修改节点数据 client.setData().forPath("/hello", "zookeeper".getBytes()); //5:关闭客户端 client.close(); } /* 获取节点数据 */ @Test public void getZnodeData() throws Exception { //1:定制一个重试策略 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 1); //2:获取客户端 String conectionStr = "192.168.100.100:2181,192.168.100.110:2181,192.168.100.120:2181"; CuratorFramework client = CuratorFrameworkFactory.newClient(conectionStr, 8000, 8000, retryPolicy); //3:启动客户端 client.start(); //4:获取节点数据 byte[] bytes = client.getData().forPath("/hello"); System.out.println(new String(bytes)); //5:关闭客户端 client.close(); } /* 节点的watch机制 */ @Test public void watchZnode() throws Exception { //1:定制一个重试策略 RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 1); //2:获取客户端 String conectionStr = "node01:2181,node02:2181,node03:2181"; CuratorFramework client = CuratorFrameworkFactory.newClient(conectionStr, 8000, 8000, retryPolicy); //3:启动客户端 client.start(); //4:创建一个TreeCache对象,指定要监控的节点路径 TreeCache treeCache = new TreeCache(client, "/hello3"); //5:自定义一个监听器 treeCache.getListenable().addListener(new TreeCacheListener() { @Override public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception { ChildData data = treeCacheEvent.getData(); if (data != null) { switch (treeCacheEvent.getType()) { case NODE_ADDED: System.out.println("监控到有新增节点!"); break; case NODE_REMOVED: System.out.println("监控到有节点被移除!"); break; case NODE_UPDATED: System.out.println("监控到节点被更新!"); break; default: break; } } } }); //开始监听 treeCache.start(); Thread.sleep(1000000); } }
登录Zookeeper客户端查看
bin/zkCli.sh -server node01:2181