Zookeeper--实战(开发重点)
- 分布式安装部署
- 集群规划
- 在centos-master,centos-slave1,centos-slave2三个节点上部署zookeeper
- 解压安装
- 解压安装zookeeper安装包到 /opt/目录下 tar -zxvf zookeeper安装包
- 将解压的目录同步到centos-slave1和centos-slave2:scp -r zookeeper-3.4.10 slave1:/opt/ ,scp -r zookeeper-3.4.10 slave2:/opt/
- 配置服务器编号
- 在/opt/zookeeper-3.4.10/这个目录下创建zkData:mkdir -p zkData
- 在/opt/zookeeper-3.4.10/zkData目录下创建myid的文件 :touch myid
- 编辑myid文件:vim myid,在文件中添加与server对应的编号:1
- 拷贝配置好的zookeeper到其他机器上 :scp -r zkData slave1:/opt/zookeeper-3.4.10/
- 并分别修改centos-slave1和centos-slave2上的myid文件内容为2 和3
- 配置zoo.cfg文件
-
复制/opt/module/zookeeper-3.4.10/conf这个目录下的z00 sample.cfg 为zo0.cfgv
cp zoo_sample.cfg zoo.cfg. -
打开zoo.cfg 文件。
vim zoo.cfgv
修改数据存储路径配置
dataDir=/ opt/ module/ zookeeper-3.4.10/ zkDatar
增加如下配置:
#######################cluster##########################
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888 -
同步zoo.cfg配置文件。
scp -r zoo.cfg slave1:/opt/zookeeper-3.4.10/conf/ ,scp -r zoo.cfg slave2:/opt/zookeeper-3.4.10/conf/ -
配置参数解读
server .A=B:C:D. 4
A是一个数字,表示这个是第几号服务器;。
集群模式下配置一个文件myid,这个文件在dataDir.目录下,这个文件里面有一个数据
就是A的值,Zookeeper 启动时读取此文件,拿到里面的数据与zo0.cfg.里面的配置信息比较从而判断到底是哪个server。
B是这个服务器的ip地址;。
C是这个服务器与集群中的Leader服务器交换信息的端口;。
D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的
Leader,而这个端口就是用来执行选举时服务器相互通信的端口。 -
集群的操作
-
分别启动Zookeeper
-
bin/zkServer.sh start
-
bin/zkServer.sh start
-
bin/zkServer.sh start
-
-
查看状态
-
bin/zkServer.sh status
-
bin/zkServer.sh status
-
bin/zkServer.sh status
-
-
-
半数选举机制,如果有三台机器,第一台上线会先投自己一票,没有够半数上,则失败
-
等到第二台机器来的时候,第一台会投第二台一票(因为他投自己没成功,所以会投比自己序号大的),机器上线总是线投自己(自私的),第二台投自己一票,二票在半数以上,则成立,第二台机器时leader,后面来第三台,由于前面已将选出leader所有自动成为flower
-
-
- 集群规划
-
客户端的命令操作
-
启动客户端 : ./zkCli.sh
- 显示所有的操作命令
- 使用命令:help
- 使用命令:help
-
查看当前znode中所以的内容 :命令:ls /
-
查看当前节点的详细数据 :命令: ls2 /
- 分别创建两个普通的节点(创建的节点不能没有内容,否则创建节点不成共)
- 获取节点中的内容
- 获取的节点不能在最后面加 / 这样节点内容获取不到,必须是 get /节点名程)
-
创建短暂节点,客户端一但掉线重新连接,则短暂节点消失:命令:create -e /节点路径名/节点名 ‘节点内容’
- 创建带序号的节点
- 先创建一个根节点:create /sanguo/weiguo ‘caocoa’
- 在创建带序号的节点:create -s /snaguo/weiguo ‘caocao’
- 如果有节点中有节点,则会按需还递增,如没有其他节点,则序号从0开始递增
-
如果原来没有序号节点,序聘从0开始依次递增。如果原节点下已有2个节点,则再
排序时从2开始,以此类推 - 不能创建 create /没有的节点/没有的节点 必须一次创建一层的一个,不能透过第一层创建第二层的节点
-
修改节点的值:set /节点名称 ‘修改的值’
-
节点值的变化监听
-
在节点master 执行:get / 节点名 watch 只能对节点做一次监听,第二次改变就监听不到了
-
在节点slave1 修改上上节点的值,节点mater就会监听到,但只能监听一次
-
- 监听节点的子节点的变化(路径的变化)
- 在master设置节点的监听:ls /sanguo watch ,监听子节点的变化
- 在slave1中 /sanguo 的节点增加一个节点,看看master的变化
- 同样master设置了一次监听,当 /sanguo第二次变化时,就不能监听到了
-
删除节点 :delete /节点名
-
递归删除节点 rmr /节点名
-
查看节点的状态: stat /节点名
-
- API应用
- Idea环境搭建
-
<dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.10</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> </dependency> </dependencies>
-
- 创建Zookeeper客户端
-
@Test public void init() throws IOException { zkClient = new ZooKeeper(connectString,sessionTimeout, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { } }); System.out.println("这是一个测试类"+zkClient.toString()); }
-
- 创建子节点
-
package com.model.test; import org.apache.zookeeper.*; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.nio.charset.StandardCharsets; public class Zookeeper001 { private String connectString="master:2181,slave1:2181,slave2:2181"; private int sessionTimeout=20000; private ZooKeeper zkClient; @Before public void init() throws IOException { zkClient = new ZooKeeper(connectString,sessionTimeout, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { } }); System.out.println("这是一个测试类"+zkClient.toString()); } @Test public void createNode() throws KeeperException, InterruptedException { String path = zkClient.create("/jia", "zs".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); System.out.println(path); } }
-
-
- 获取子节点并监听上数据
-
package com.model.test; import org.apache.zookeeper.*; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.List; public class Zookeeper001 { private String connectString="master:2181,slave1:2181,slave2:2181"; private int sessionTimeout=20000; private ZooKeeper zkClient; @Before public void init() throws IOException { zkClient = new ZooKeeper(connectString,sessionTimeout, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { //实时的监控某节点下的节点数量变化,这里演示根目录下节点数量变化 System.out.println("*********start***********"); try { List<String> children = zkClient.getChildren("/", true); for (String child:children) { System.out.println(child); } System.out.println("********end*********"); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }); System.out.println("这是一个测试类"+zkClient.toString()); } //创建节点 @Test public void createNode() throws KeeperException, InterruptedException { String path = zkClient.create("/jia", "zs".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); System.out.println(path); } @Test public void getChildWatch(){ List<String> children = null; try { children = zkClient.getChildren("/", true); for (String child:children) { System.out.println(child); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } } }
-
-
- 判断Znode是否存在
-
- Idea环境搭建
- 监听服务器节点动态上下线案例
-
client代码
-
package com.model.DoTaiShangXiaXian; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class Client { public static void main(String[] args) throws IOException, KeeperException, InterruptedException { Client client=new Client(); // 1.连接zookeeper服务器 client.getConnect(); // 2.注册监听 client.getChildren(); // 3.业务逻辑处理 client.business(); } private void business() throws InterruptedException { Thread.sleep(Long.MAX_VALUE); } private void getChildren() throws KeeperException, InterruptedException { List<String> children = zkClient.getChildren("/servers", true); // 创建存储服务器节点主机名称的集合 ArrayList<String> hosts=new ArrayList<>(); for (String c:children){ byte[] data = zkClient.getData("/servers/"+c, false, null); hosts.add(new String(data)); } // 将所有的在线主机名称打印到控制台 System.out.println(hosts); } private final String connectString="master:2181,slave1:2181,slave2:2181"; private int sessionTimeout=30000; private ZooKeeper zkClient; private void getConnect() throws IOException { zkClient= new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { try { getChildren(); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }
-
-
server代码
-
package com.model.DoTaiShangXiaXian; import org.apache.zookeeper.*; import java.io.IOException; public class Server { //实现服务器动态上下线 //服务器端 public static void main(String[] args) throws IOException, KeeperException, InterruptedException { Server service=new Server(); // 1.连接zookeeper服务器集群 service.getConnect(); // 2.在zookeeper上注册节点 service.register(args[0]); // 3.业务逻辑处理 service.business(); } private void business() throws InterruptedException { Thread.sleep(Long.MAX_VALUE); } private void register(String hostname) throws KeeperException, InterruptedException { String path = zkClient.create("/servers/server", hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); System.out.println(hostname+"is online"); } private final String connectString="master:2181,slave1:2181,slave2:2181"; private int sessionTimeout=30000; private ZooKeeper zkClient; public void getConnect() throws IOException { zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { } }); } }
-
-
只运行client代码,在zookeeper集群操作节点变化,观察控制台
-
-
同时运行server和client类观察控制台变化
-
-
-