Zookeeper
Zookeeper概念
Zookeeper 是 Apache Hadoop 项目下的一个子项目,是一个树形目录服务。
Zookeeper 翻译过来就是 动物园管理员,他是用来管 Hadoop(大象)、Hive(蜜蜂)、Pig(小 猪)的管理员。简称zk
Zookeeper 是一个分布式的、开源的分布式应用程序的协调服务。
Zookeeper 提供的主要功能包括:
配置管理:对项目的公共配置文件进行统一管理
分布式锁:一个数据库可以被多个对象使用加锁,对象的其他属性不能使用这个数据库
集群管理:可以管理多个对象
ZooKeeper 安装与配置
下载安装
环境准备
ZooKeeper服务器是用Java创建的,它运行在JVM之上。需要安装JDK 7或更高版本。
上传
将下载的ZooKeeper放到/opt/ZooKeeper目录下
xml
#上传zookeeper alt+p
put f:/setup/apache-zookeeper-3.5.6-bin.tar.gz
#打开 opt目录
cd /opt
#创建zooKeeper目录
mkdir zooKeeper
#将zookeeper安装包移动到 /opt/zooKeeper
mv apache-zookeeper-3.8.6-bin.tar.gz /opt/zookeeper/
解压
将tar包解压到/opt/zookeeper目录下
xml
tar -zxvf apache-ZooKeeper-3.8.6-bin.tar.gz
配置启动
配置zoo.cfg
进入到conf目录拷贝一个zoo_sample.cfg并完成配置
xml
#进入到conf目录
cd /opt/zooKeeper/apache-zooKeeper-3.8.6-bin/conf/
#拷贝
cp zoo_sample.cfg zoo.cfg
修改zoo.cfg
xml
#打开目录
cd /opt/zooKeeper/
#创建zooKeeper存储目录
mkdir zkdata
#修改zoo.cfg
vim /opt/zooKeeper/apache-zooKeeper-3.5.6-bin/conf/zoo.cfg
修改存储目录:dataDir=/opt/zookeeper/zkdata
port在后面会用到
启动ZooKeeper
xml
cd /opt/zooKeeper/apache-zooKeeper-3.8.6-bin/bin/
#启动
./zkServer.sh start
STARTED代表成功
查看ZooKeeper状态
./zkServer.sh status
zookeeper启动成功。standalone代表zk没有搭建集群,现在是单节点
如果zookeeper没有启动
ZooKeeper 命令操作
数据模型
ZooKeeper 是一个树形目录服务,其数据模型和Unix的文件系统目录树很类似,拥有一个层次化结构。
这里面的每一个节点都被称为: ZNode,每个节点上都会保存自己的数据和节点信息。
节点可以拥有子节点,同时也允许少量(1MB)数据存储在该节点之下。
节点可以分为四大类:
PERSISTENT 持久化节点
EPHEMERAL 临时节点 :-e
PERSISTENT_SEQUENTIAL 持久化顺序节点 :-s
EPHEMERAL_SEQUENTIAL 临时顺序节点 :-es
服务端命令
•启动 ZooKeeper 服务: ./zkServer.sh start
•查看 ZooKeeper 服务状态: ./zkServer.sh status
•停止 ZooKeeper 服务: ./zkServer.sh stop
•重启 ZooKeeper 服务: ./zkServer.sh restart
Zookeeper客户端常用命令
•连接ZooKeeper服务端
./zkCli.sh --server ip:port
•断开连接
quit
•查看命令帮助
help
•显示指定目录下节点
ls 目录
•创建节点
create /节点path value
•获取节点值
get /节点path
•设置节点值
set /节点path value
•删除单个节点
delete /节点path
•删除带有子节点的节点
deleteall /节点path
创建临时有序节点
•创建临时节点
create -e /节点path value
•创建顺序节点
create -s /节点path value
•查询节点详细信息
ls --s /节点path
•czxid:节点被创建的事务ID
•ctime: 创建时间
•mzxid: 最后一次被更新的事务ID
•mtime: 修改时间
•pzxid:子节点列表最后一次被更新的事务ID
•cversion:子节点的版本号
•dataversion:数据版本号
•aclversion:权限版本号
•ephemeralOwner:用于临时节点,代表临时节点的事务ID,如果为持久节点则为0
•dataLength:节点存储的数据的长度
•numChildren:当前节点的子节点个数
ZooKeeper JavaAPI 操作
Curator介绍
•Curator 是 Apache ZooKeeper 的Java客户端库。
•常见的ZooKeeper Java API :
•原生Java API
•ZkClient
•Curator
•Curator 项目的目标是简化 ZooKeeper 客户端的使用。
•Curator 最初是 Netfix 研发的,后来捐献了 Apache 基金会,目前是 Apache 的顶级项目。
•官网:http://curator.apache.org/
JavaAPI操作建立连接
1,搭建项目
创建项目curator-zk
引入pom和日志文件
资料文件夹下pom.xml和log4j.properties
2、创建测试类,使用curator连接zookeeper
java
@Before
public void testConnect() {
//重试策略
RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
//2.第二种方式
//CuratorFrameworkFactory.builder();
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("127.0.0.1:2181")
.sessionTimeoutMs(60 * 1000)
.connectionTimeoutMs(15 * 1000)
.retryPolicy(retryPolicy)
.namespace("bukaedu")
.build();
//开启连接
client.start();
}
创建节点
java
/**
* 创建节点:create 持久 临时 顺序 数据
* 1. 基本创建 :create().forPath("")
* 2. 创建节点 带有数据:create().forPath("",data)
* 3. 设置节点的类型:create().withMode().forPath("",data)
* 4. 创建多级节点 /app1/p1 :create().creatingParentsIfNeeded().forPath("",data)
*/
@Test
public void testCreate() throws Exception {
//2. 创建节点 带有数据
//如果创建节点,没有指定数据,则默认将当前客户端的ip作为数据存储
String path = client.create().forPath("/app2", "hehe".getBytes());
System.out.println(path);
}@Test
public void testCreate2() throws Exception {
//1. 基本创建
//如果创建节点,没有指定数据,则默认将当前客户端的ip作为数据存储
String path = client.create().forPath("/app1");
System.out.println(path);
}
@Test
public void testCreate3() throws Exception {
//3. 设置节点的类型
//默认类型:持久化
String path = client.create().withMode(CreateMode.EPHEMERAL).forPath("/app3");
System.out.println(path);
}
@Test
public void testCreate4() throws Exception {
//4. 创建多级节点 /app1/p1
//creatingParentsIfNeeded():如果父节点不存在,则创建父节点
String path = client.create().creatingParentsIfNeeded().forPath("/app4/p1");
System.out.println(path);
}
查询节点
java
/**
* 查询节点:
* 1. 查询数据:get: getData().forPath()
* 2. 查询子节点: ls: getChildren().forPath()
* 3. 查询节点状态信息:ls -s:getData().storingStatIn(状态对象).forPath()
*/
@Test
public void testGet1() throws Exception {
//1. 查询数据:get
byte[] data = client.getData().forPath("/app1");
System.out.println(new String(data));
}
@Test
public void testGet2() throws Exception {
// 2. 查询子节点: ls
List<String> path = client.getChildren().forPath("/");
System.out.println(path);
}
@Test
public void testGet3() throws Exception {
Stat status = new Stat();
System.out.println(status);
//3. 查询节点状态信息:ls -s
client.getData().storingStatIn(status).forPath("/app1");
System.out.println(status);
}
修改节点
java
/**
* 修改数据
* 1. 基本修改数据:setData().forPath()
* 2. 根据版本修改: setData().withVersion().forPath()
* * version 是通过查询出来的。目的就是为了让其他客户端或者线程不干扰我。
*
* @throws Exception
*/
@Test
public void testSet() throws Exception {
client.setData().forPath("/app1", "buka".getBytes());
}
@Test
public void testSetForVersion() throws Exception {
Stat status = new Stat();
//3. 查询节点状态信息:ls -s
client.getData().storingStatIn(status).forPath("/app1");
int version = status.getVersion();//查询出来的 3
System.out.println(version);
client.setData().withVersion(version).forPath("/app1", "hehe".getBytes());
}