tar -zxf /opt/zookeeper-3.4.14.tar.gz -C ./
vim /etc/profile
export ZK_HOME=/opt/zookeeper-3.4.14
export PATH=$ZK_HOME/bin:
(1)拷贝示例文件配置文件
cp zoo_sample.cfg zoo.cfg
(2)修改配置文件:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/hadoop/zoodata
clientPort=2181
# IP:和leader通信的端口号:和从节点通信的端口号
server.0=master:2888:3888
server.1=slave1:2888:3888
server.2=slave2:2888:3888
cd /home/hadoop/zoodata
在master执行:echo 0 > myid
在slave1执行:echo 1 > myid
在slave2执行:echo 2 > myid
scp -r /opt/zookeeper-3.4.14 slave1:/opt/
scp -r /opt/zookeeper-3.4.14 slave2:/opt/
zookeeper服务器端指令:
zkServer.sh start 启动
zkServer.sh stop 停止
zkServer.sh restart 重启
zkServer.sh status 查看状态
zkServer启动成功之后,通过JPS查看进程:
QuorumPeerMain
zookeeper客户端指令:
zkCli.sh 连接本地zk服务器
zkClie.sh -server host:port 客户端连接远程服务器
进入客户端之后:
ls path [watch] 查看指定节点的子节点信息(添加监听)
create path data 创建指定节点及对应的数据
get path [watch] 查看指定节点下的数据(添加监听)
set path data 修改指定节点下的数据
rmr path 删除指定节点(会连通子节点一块删除)
节点类型:
持久节点、临时节点、顺序节点、不顺序节点
create -s path data 创建持久顺序节点(默认不顺序节点)
create -e ptah data 创建临时不顺序节点(当创建该节点的客户端下线,该节点自动删除)
zookeeper Java API:
public class Demo2 {
ZooKeeper zk = null;
public void init() throws Exception {
String connStr = "192.168.56.101:2181";
// 参数: 连接zk服务器的IP:port, 超时时间, 监听
zk = new ZooKeeper(connStr, 2000000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if(event.getState() == KeeperState.SyncConnected // 判断监听是否同步
&&
event.getType() == EventType.NodeChildrenChanged) { // 判断监听类型:子节点改变
System.out.println("子节点发生变化");
// 再次监听
try {
getChildren();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if(event.getState() == KeeperState.SyncConnected
&&
event.getType() == EventType.NodeDataChanged) { // 监听类型:节点数据改变
System.out.println("节点数据发生变化");
// 再次监听
try {
getData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
/**
* 创建节点
* @throws Exception
*/
public void createNode() throws Exception {
// 参数: 节点路径, 节点存储的数据,权限, 节点类型
zk.create("/aa", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
/**
* 获取指定节点的数据
* @throws Exception
*/
public void getData() throws Exception {
// 参数: 节点路径, 是否添加监听, 数据版本
byte[] data = zk.getData("/aa", true, null);
System.out.println(new String(data));
}
/**
* 获取指定节点的子节点
* @throws Exception
*/
public void getChildren() throws Exception {
// 参数: 节点路径, 是否添加监听
List children = zk.getChildren("/aa", true);
for(String str : children) {
// 返回的节点名称中不带 /
System.out.println(str);
}
}
public static void main(String[] args) throws Exception {
Demo2 demo2 = new Demo2();
demo2.init();
demo2.getChildren();
demo2.getData();
Thread.sleep(Integer.MAX_VALUE);
}
}
zookeeper应用场景:服务器上下线动态感知
服务器端:
public class QueryTimeServer {
ZooKeeper zk = null;
public void init() throws IOException {
String connStr = "192.168.56.101:2181";
zk = new ZooKeeper(connStr, 2000000, null);
}
// 注册IP、port
public void registSever(String ip, String port) throws Exception {
// 判定 /Servers 节点是否存储
Stat exists = zk.exists("/Servers", false);
if(exists == null) {
// 如果 /Servers 节点不存在,需要创建 : 持久不顺序节点
zk.create("/Servers",
null,
Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
}
// 注册 IP、PORT到 /Servers/server00000X节点
// 该节点为临时顺序节点
zk.create("/Servers/server",
(ip+":"+port).getBytes(),
Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(ip+":"+port+"服务器向zk注册成功!");
}
// TODO 业务处理 -- 响应时间请求
public static void main(String[] args) throws Exception {
QueryTimeServer server = new QueryTimeServer();
server.init();
server.registSever(args[0], args[1]);
// TODO 业务处理 -- 响应时间请求
Thread.sleep(Integer.MAX_VALUE);
}
}
客户端:
public class Client {
ZooKeeper zk = null;
// 服务器在线列表
List online = new ArrayList();
public void init() throws IOException {
String connStr = "192.168.56.101:2181";
zk = new ZooKeeper(connStr, 2000000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if(event.getState() == KeeperState.SyncConnected
&&
event.getType() == EventType.NodeChildrenChanged) {
// 获取最新的在线列表
try {
getOnline();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
// 获取服务器列表
public void getOnline() throws Exception {
List servers = new ArrayList();
// 获取 /Servers 节点下的子节点
List children = zk.getChildren("/Servers", true);
for(String str : children) {
byte[] data = zk.getData("/Servers/"+str, false, null);
String msg = new String(data);
servers.add(msg);
}
online = servers;
System.out.println("当前在线服务器:"+Arrays.toString(online.toArray()));
}
// TODO 业务处理 -- 时间查询
public static void main(String[] args) throws Exception {
Client client = new Client();
client.init();
client.getOnline();
// TODO 业务处理 -- 时间查询
Thread.sleep(Integer.MAX_VALUE);
}
}
在HBase中使用安装的zookeeper集群:
1、在master上修改hbase-env.sh文件, 修改如下内容:
vim /opt/hbase-1.2.6/conf/hbase-env.sh
export HBASE_MANAGES_ZK=false
2、将hbase-env.sh拷贝到 slave1、slave2 虚拟机上
scp /opt/hbase-1.2.6/conf/hbase-env.sh slave1:/opt/hbase-1.2.6/conf/
scp /opt/hbase-1.2.6/conf/hbase-env.sh slave2:/opt/hbase-1.2.6/conf/
3、启动顺序:HDFS、ZooKeeper、Hbase
start-dfs.sh (在master上启动)
zkServer.sh start (在三台虚拟机上分别启动)
start-hbase.sh (在master上启动)