ToB企服应用市场:ToB评测及商务社交产业平台

标题: ZooKeeper 入门教程 [打印本页]

作者: 用户国营    时间: 2024-10-23 08:38
标题: ZooKeeper 入门教程
0. 前言


文章已经收录到 GitHub 个人博客项目,接待 Star:
  1. https://github.com/chenyl8848/chenyl8848.github.io
复制代码
或者访问网站,进行在线浏览:
  1. https://chenyl8848.github.io/
复制代码
1. ZooKeeper 简介

ZooKeeper(动物园管理者)简称 ZK一个分布式的,开放源码的分布式应用步调和谐服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 Hbase 的紧张组件。ZooKeeper 使用 Java 所编写,但是支持 Java 和 C 两种编程语言。

应用场景
关注微信公众号:【Java陈序员】,获取开源项目分享、AI副业分享、超200本经典计算机电子册本等。
2. ZooKeeper 内存数据模型

2.1 模型结构


2.2 模型的特点

3. 节点的分类

3.1 持久节点(PERSISTENT)

指在节点创建后,就一直存在,直到有删除操作来主动删除这个节点 —— 不会因为创建该节点的客户端会话失效而消失
3.2 持久序次节点(PERSISTENT_SEQUENTIAL)

这类节点的根本特性和上面的节点类型是一致的。额外的特性是,在 ZooKeeper 中,每个父节点会为他的第一级子节点维护一份时序,会记载每个子节点创建的先后序次。基于这个特性,在创建子节点的时候,可以设置这个属性,那么在创建节点过程中,ZooKeeper 会自动为给定节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。
3.3 临时节点(EPHEMERAL)

和持久节点差别的是,临时节点的生命周期和客户端会话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被打扫掉。注意,这里提到的是会话失效,而非连接断开。另外,在临时节点下面不能创建子节点。
3.4 临时序次节点(EPHEMERAL_SEQUENTIAL)

具有临时节点特点,额外的特性是,每个父节点会为他的第一级子节点维护一份时序,这点和持久序次节点类似。
4. 安装

4.1 Linux 体系安装
  1. # 1.安装 JDK 并配置环境变量&下载 ZooKeeper 安装包
  2. -        https://mirrors.bfsu.edu.cn/apache/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
  3. # 2.下载安装包上传到 Linux 服务器中,并解压缩
  4. -        tar -zxvf zookeeper-3.4.12.tar.gz
  5. # 3.重命名安装目录
  6. -        mv zookeeper-3.4.12 zk
  7. # 4.配置 zoo.cfg 配置文件
  8. -        1.修改 ZooKeeper 的 conf 目录下的 zoo_simple.cfg,修改完后,重命名为zoo.cfg
  9.   tickTime=2000
  10.   initLimit=10
  11.   syncLimit=5
  12.   dataDir=/usr/zookeeper/zkdata
  13.   clientPort=2181
  14. # 5.启动 ZooKeeper
  15. -        在 ZooKeeper 的 bin 目录下,运行 zkServer.sh
  16.         ./bin/zkServer.sh start /usr/zookeeper/conf/zoo.cfg
  17.        
  18. # 6.使用 jps 查看启动是否成功
  19. # 7.启动客户端连接到 ZooKeeper
  20. - ./bin/zkCli.sh -server 192.168.0.220:2181
  21.         注意:可以通过  ./bin/zkCli.sh help 查看客户端所有可以执行的指令
复制代码
4.2 Docker 安装 ZooKeeper
  1. # 1.获取 ZooKeeper 的镜像
  2. - docker pull zookeeper:3.4.14
  3. # 2.启动 ZooKeeper 服务
  4. - docker run --name zk -p 2181:2181 -d zookeeper:3.4.14
复制代码
5. 客户端根本指令
  1. # 1.ls path                                                            查看特定节点下面的子节点
  2. # 2.create path data                           创建一个节点。并给节点绑定数据(默认是持久性节点)
  3.   - create path data                                                                  创建持久节点(默认是持久节点)
  4.   - create -s path data                                                   创建持久性顺序节点
  5.   -        create -e path data                                                   创建临时性节点(注意:临时节点不能含有任何子节点)
  6.   -        create -e -s path data            创建临时顺序节点(注意:临时节点不能含有任何子节点)
  7. # 3.stat path                查看节点状态
  8. # 4.set path data            修改节点数据
  9. # 5.ls2 path                 查看节点下孩子和当前节点的状态
  10. # 6.history                  查看操作历史
  11. # 7.get path                 获得节点上绑定的数据信息
  12. # 8.delete path              删除节点(注意:删除节点不能含有子节点)
  13. # 9.rmr  path                递归删除节点(注意:会将当前节点下所有节点删除)
  14. # 10.quit                    退出当前会话(会话失效)
复制代码
6. 节点监听机制 watch

客户端可以监测 znode 节点的变化。znode 节点的变化会触发相应的事件,然后打扫对该节点的监测。
当监测一个 znode 节点时候,Zookeeper 会发送关照给监测节点。一个 Watch 事件是一个一次性的触发器,当被设置了 Watch 的数据和目录发生了改变的时候,则服务器将这个改变发送给设置了 Watch 的客户端以便关照它们
  1. # 1.ls /path true             监听节点目录的变化
  2. # 2.get /path true                                                监听节点数据的变化
复制代码
7.Java 操作 ZooKeeper

7.1 创建项目引入依赖
  1. <dependency>
  2.     <groupId>com.101tec</groupId>
  3.     <artifactId>zkclient</artifactId>
  4.     <version>0.10</version>
  5. </dependency>
复制代码
7.2 获取 ZooKeeper 客户端对象
  1. private ZkClient zkClient;
  2. /**
  3. * 获取zk客户端连接
  4. */
  5. @Before
  6. public void Before() {
  7.     // 参数1:服务器的ip和端口
  8.     // 参数2:会话的超时时间
  9.     // 参数3:回话的连接时间
  10.     // 参数4:序列化方式
  11.     zkClient = new ZkClient("192.168.28.132:2181", 30000, 60000, new SerializableSerializer());
  12. }
  13. /**
  14. * 关闭资源
  15. */
  16. @After
  17. public void after(){
  18.     zkClient.close();
  19. }
复制代码
7.3 常用 API

  1. /**
  2. * 创建节点
  3. */
  4. @Test
  5. public void testCreateNode() {
  6.     //第一中创建方式  返回创建节点的名称
  7.     String nodeName = zkClient.create("/node5", "lisi", CreateMode.PERSISTENT);
  8.     zkClient.create("/node6", "zhangsan", CreateMode.PERSISTENT_SEQUENTIAL);
  9.     zkClient.create("/node7", "王五", CreateMode.EPHEMERAL);
  10.     zkClient.create("/node8", "xiaozhang", CreateMode.EPHEMERAL_SEQUENTIAL);
  11.     //第二种创建方式 不会返回创建节点的名称
  12.     zkClient.createPersistent("/node1", "持久数据");
  13.     zkClient.createPersistentSequential("/node1/aa", "持久数据顺序节点");
  14.     zkClient.createEphemeral("/node2", "临时节点");
  15.     zkClient.createEphemeralSequential("/node1/bb", "临时顺序节点");
  16. }
复制代码
  1. /**
  2. * 删除节点
  3. */
  4. @Test
  5. public void testDeleteNode() {
  6.     // 删除没有子节点的节点  返回值:是否删除成功
  7.     boolean delete = zkClient.delete("/node1");
  8.     // 递归删除节点信息 返回值:是否删除成功
  9.     boolean recursive = zkClient.deleteRecursive("/node1");
  10. }
复制代码
  1. /**
  2. * 查询节点
  3. */
  4. @Test
  5. public void testFindNodes() {
  6.     // 获取指定路径的节点信息  
  7.     // 返回值:为当前节点的子节点信息
  8.     List<String> children = zkClient.getChildren("/");
  9.     for (String child : children) {
  10.         System.out.println(child);
  11.     }
  12. }
复制代码
注意:如果出现:org.I0Itec.zkclient.exception.ZkMarshallingError: java.io.StreamCorruptedException: invalid stream header: 61616161. 非常的原因是:在 Shell 中的数据序列化方式和 Java 代码中使用的序列化方式不一致,因此要办理这个问题只必要保证序列化一致即可。
  1. /**
  2. * 获取节点的数据
  3. *
  4. */
  5. @Test
  6. public void testFindNodeData() {
  7.     Object readData = zkClient.readData("/node3");
  8.     System.out.println(readData);
  9. }
复制代码
  1. /**
  2. * 获取数据以及当前节点的状态信息
  3. */
  4. @Test
  5. public void testFindNodeDataAndStat() {
  6.     Stat stat = new Stat();
  7.     Object readData = zkClient.readData("/node60000000024", stat);
  8.     System.out.println(readData);
  9.     System.out.println(stat);
  10. }
复制代码
  1. /**
  2. * 修改节点数据
  3. */
  4. @Test
  5. public void testUpdateNodeData() {
  6.     zkClient.writeData("/node60000000024", new User("121", "name", "xxx"));
  7. }
复制代码
  1. /**
  2. * 监听节点数据的变化
  3. */
  4. @Test
  5. public void testOnNodeDataChange() throws IOException {
  6.     zkClient.subscribeDataChanges("/node60000000024", new IZkDataListener() {
  7.         // 当节点的值在修改时,会自动调用这个方法  将当前修改节点的名字,和节点变化之后的数据传递给方法
  8.         public void handleDataChange(String nodeName, Object result) throws Exception {
  9.             System.out.println(nodeName);
  10.             System.out.println(result);
  11.         }
  12.         // 当节点的值被删除的时候,会自动调用这个方法,会将节点的名字已参数形式传递给方法
  13.         public void handleDataDeleted(String nodename) throws Exception {
  14.             System.out.println("节点的名字:" + nodename);
  15.         }
  16.     });
  17.     //阻塞客户端
  18.     System.in.read();
  19. }
复制代码
  1. /**
  2. * 监听节点的变化
  3. */
  4. @Test
  5. public void testOnNodesChange() throws IOException {
  6.     zkClient.subscribeChildChanges("/node60000000024", new IZkChildListener() {
  7.         // 当节点的发生变化时,会自动调用这个方法
  8.         // 参数1:父节点名称
  9.         // 参数2:父节点中的所有子节点名称
  10.         public void handleChildChange(String nodeName, List<String> list) throws Exception {
  11.             System.out.println("父节点名称:" + nodeName);
  12.             System.out.println("发生变更后字节孩子节点名称:");
  13.             for (String name : list) {
  14.                 System.out.println(name);
  15.             }
  16.         }
  17.     });
  18.     // 阻塞客户端
  19.     System.in.read();
  20. }
复制代码
8. ZooKeeper 的集群

8.1 集群(Cluster)
  1. # 1.集群(Cluster)
  2. - 集合同一种软件服务的多个节点同时提供服务
  3. # 2.集群解决问题
  4. -  单节点的并发访问的压力问题
  5. -  单节点故障问题(如硬件老化、自然灾害等)
复制代码
8.2 集群架构


8.3 集群搭建
  1. # 1.创建三个 dataDir
  2. - mkdir zkdata1 zkdata2 zkdata3
  3. # 2.分别在三个dataDir目录下面myid文件
  4. - touch ./zkdata1/myid
  5.     myid 的内容是 服务器的  表示  1|2|3
  6. # 3.在 /conf 目录下创建三个 ZooKeeper 配置文件,分别为 zoo1.cfg、zoo2.cfg、zoo3.cfg       
  7. -        zoo1.cfg
  8.     tickTime=2000
  9.     initLimit=10
  10.     syncLimit=5
  11.     dataDir=/root/zkdata1
  12.     clientPort=3001
  13.     server.1=10.15.0.5:3002:3003
  14.     server.2=10.15.0.5:4002:4003
  15.     server.3=10.15.0.5:5002:5003
  16. - zoo2.cfg
  17.     tickTime=2000
  18.     initLimit=10
  19.     syncLimit=5
  20.     dataDir=/root/zkdata2
  21.     clientPort=4001
  22.     server.1=10.15.0.5:3002:3003
  23.     server.2=10.15.0.5:4002:4003
  24.     server.3=10.15.0.5:5002:5003
  25. - zoo3.cfg
  26.     tickTime=2000
  27.     initLimit=10
  28.     syncLimit=5
  29.     dataDir=/root/zkdata3
  30.     clientPort=5001
  31.     server.1=10.15.0.5:3002:3003
  32.     server.2=10.15.0.5:4002:4003
  33.     server.3=10.15.0.5:5002:5003
  34. 解释:
  35.     1.server.X: x为服务器的唯一标识。
  36.     2.192.168.0.220: 服务器所在的ip地址
  37.     3.3002: 数据同步使用的端口号
  38.     4.3003: 选举使用的端口号
  39. # 4.分别启动各个 ZooKeeper 服务器
  40. - ./bin/zkServer.sh start /usr/zookeeper/conf/zoo1.cfg 
  41. - ./bin/zkServer.sh start /usr/zookeeper/conf/zoo2.cfg 
  42. - ./bin/zkServer.sh start /usr/zookeeper/conf/zoo3.cfg
  43. # 5.查看各个 ZooKeeper 服务器的角色信息
  44. - ./bin/zkServer.sh status /usr/zookeeper/conf/zoo1.cfg
  45. # 6.客户端连接任意 ZooKeeper 服务器进行节点操作
  46. - ./bin/zkCli.sh -server 192.168.0.220:3001
  47. # 7.停止特定 ZooKeeper 服务器
  48. - ./bin/zkServer.sh stop /usr/zookeeper/conf/zoo1.cfg 
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4