【博学谷学习记录】超强总结,用心分享|狂野大数据课程【Zookeeper框架】的总结分析

Zookeeper框架

ZK的概述
1、ZK本身也是一个集群
2、ZK本身也可以存数据(配置数据),可以理解为一个数据库
3、ZK单独使用没有任何意义,ZK用来管理别的框架
4、ZK顶层是Java语言
5、ZK集群允许部分主机宕机,ZK集群中最坏情况下,只要有大于一半的主机在工作,集群就能维持运转(过半机制)

在这里插入图片描述

ZK的特点
1、全局一致性:在ZK的任何一台主机上对节点进行操作,其他主机都要跟着操作,保持完全同步
2、顺序性;在某一台主机上先后创建了A、B两个节点,则其他主机也必须遵循节点创建的先后顺序
3、原子性:对ZK的节点增加是一个原子操作(所有的主机都必须添加添加该节点,这个过程是不可再分的,只有所以的操作都完成,才算成功,否则就算失败)
4、实时性:对ZK的操作几乎是实时的,不会有太大的延迟
ZK集群角色

ZK集群角色

  • 描述

    ZK是一个主从架构,有主节点,也有从节点
    
  • 角色

    • Leader

      1、集群的管理者,管理整个集群
      2、既能完成非事务(查询,读取)操作,也能完成事务(增删改)操作
      
    • Follower

      1、只能完成非事务操作(查询,读取),如果收到客户端的事务请求,则会转发给Leader
      2、当Leader挂掉的时候,Follower投票选举新的Leader
      
    • Observer

      1、只能完成非事务操作(查询,读取),如果收到客户端的事务请求,则会转发给Leader
      2、当Leader挂掉的时候,Observer不能投票选举新的Leader(能干活,但是被剥夺政治权利)
      
ZK的集群搭建
  • 前提

    1、虚拟机上必须安装JDK
    2、虚拟机要求奇数台
       3台虚拟机  允许挂掉1台  剩下2台
       5台虚拟机  允许挂掉2台  剩下3台
       100台虚拟机  允许挂掉49台  剩下51台
    
  • 集群搭建方案

    服务器IP主机名myid的值 (ZK的编号)
    192.168.88.161node11
    192.168.88.162node22
    192.168.88.163node33
  • ZK的搭建

  • ZK的启动和状态查看

    zkServer.sh start #启动
    zkServer.sh stop #启动
    zkServer.sh status #启动
    
  • ZK的日志

    1、ZK的日志文件名是:Zookeeper.out
    2、日志文件会自动生成在启动命令所在的目录下
    
  • ZK的一键启动脚本

    • 版本1

      #!/bin/bash
      
      for i in 1 2 3
      do
          ssh  root@node$i "source /etc/profile;zkServer.sh $1"
      done
      
    • 版本2

      #!/bin/bash
      var=""
      echo "你要进行什么操作?"
      PS3="请输入你选择:"
      select var in "start" "stop" "status"
      do
        for i in 1 2 3
        do
             echo"---------------node$i------------------"
             ssh  root@node$i "source /etc/profile;zkServer.sh $var"
        done
       break;
      done
      
      echo "-----------Zookeer集群$var完毕!---------------"
      
ZK的数据模型和客户端操作
  • 数据模型
    数据模型
    在这里插入图片描述

    1、ZK内部有一个树形的结构的`目录树
    2、访问目录树的节点必须使用绝对路径 
    3、ZK的节点称为Znode
    4、Znode既具有文件特点(存数据),又具有文件夹特点(有子节点)
    5、ZK中主要存储配置信息,数量量不大,一般是以K为单位,最多不超过1M
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6bJgl5e9-1662300077368)(Zookeeper框架.assets/image-20220901221103097.png)]

  • 客户端连接ZK集群

    #方式1-默认连接本主机的ZK
    zkClient.sh   #quit退出
    
    #方式2-连接指定主机
    zkClient -server node1/node2/node3
    
  • shell命令操作ZK的节点

    1:创建普通永久节点
    
     #永久节点永远存在,除非手动删除
     create /app1 hello    
    
    2: 创建永久顺序节点
    
    #永久顺序节点永远存在,除非手动删除,会自动在节点名字后边加一串数字,该数字表示创建节点的先后顺序
    #永久顺序节点的创建命令可以多次执行,因为后边会自动加编号
      
    create -s /app2 world   
    
    3:创建临时节点
    
    #临时节点依赖当前的会话(客户端和服务器构建的连接),会话消失,则节点自动消失
    create -e /tempnode world
    
    4:创建临时顺序节点
    
    #临时顺序节点依赖当前的会话(客户端和服务器构建的连接),会话消失,则节点自动消失
    #临时顺序节点的创建命令可以多次执行,因为后边会自动加编号
    create -s -e /tempnode2 aaa
    
    5:创建子节点
       create /app1/app1_1 null      #永久节点的子节点
       create -s /app1/app1_2 null   #永久顺序节点的子节点
       
       #注意:临时节点,不能创建子节点
    
    6:获取节点数据
       get  /app1
       get /app1/app1_1
    
    7:修改节点数据
       set /app1  hadoop
    
    8:删除节点
    
      delete  /app1 删除的节点不能有子节点
    
      rmr    /app1 递归删除
    
ZK节点的属性
1、查看ZK节点属性

get /app1

2、分析节点属性
nulll                                    #节点数据
cZxid = 0x900000009                      #节点创建事务ID,和创建的时机有关,该值不变
ctime = Sat Sep 03 13:51:44 CST 2022     #节点创建时间
mZxid = 0x900000009					     #节点的修改事务ID,每次都节点进行修改,该值加1
mtime = Sat Sep 03 13:51:44 CST 2022     #节点修改时间
pZxid = 0x900000009					     #子节点的事务ID,子节点发生变化,则会增加
cversion = 0                             #子节点的版本号
dataVersion = 0							 #节点数据版本,对字节数据修改,则值加1
aclVersion = 0							 #节点的权限
ephemeralOwner = 0x0	                 #永久节点:0x0 	临时节点(会话id): 0x182f95799320001
dataLength = 5						     #节点数据的长度
numChildren = 0							 #子节点的数量
ZK的Watch机制
  • 概念
wath机制就是监控一个节点的变化
  数据修改
  添加操作
  删除操作
  ....
一旦监控到节点发生变化,则会自动触发某个行为(自定义):通知备用节点让他去进行节点创建

ZK的watch机制在命令行终端是一次性的,如果想重复的监听,则必须使用Java代码来完成
KeeperStateEventType触发条件说明
None连接成功
SyncConnectedNodeCreatedZnode被创建此时处于连接状态
SyncConnectedNodeDeletedZnode被删除此时处于连接状态
SyncConnectedNodeDataChangedZnode数据被改变此时处于连接状态
SyncConnectedNodeChildChangedZnode的子Znode数据被改变此时处于连接状态
  • 操作

    1、在第一个ZK的客户端执行命令
    get /app1 watch  #回车之后,ZK会自动的监控/app1节点
    
    2、在第二个ZK的客户端执行命令
    set /app1 xxx
    
    
ZK的Java操作
  • 介绍

    在这里我们要通过java将之前的shell命令操作全部实现,也就是通过java对Zookeeper节点进行增删改查
    
  • Java代码

    • pom.xml

          <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>
      
    • 代码

    package pack01_zookeeper;
    
    import org.apache.curator.RetryPolicy;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.api.GetDataBuilder;
    import org.apache.curator.framework.imps.CuratorFrameworkState;
    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.apache.zookeeper.data.Stat;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    public class Demo1Zookeeper {
    
        private  CuratorFramework client;
    
        @Before
        public void init(){
            //1:定制一个重试策略
            /*
               3000 : 间隔3秒重试去连接ZK服务器
               3    : 最多连接次
            */
            RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 3);
    
            //2:获取一个客户端对象
            client =  CuratorFrameworkFactory.newClient("node1:2181,node2:2181,node3:2181",
                    retryPolicy);
    
            //3:开启客户端
            client.start();
        }
    
    
        @After
        public void close(){
            //5:关闭客户端
            client.close();
        }
    
        //6:watch机制
        @Test
        public void watchDemo() throws Exception {
            //4:将要监听的节点树存入缓存中
            TreeCache treeCache = new TreeCache(client, "/master");
    
            //5:自定义监听
            treeCache.getListenable().addListener(new TreeCacheListener() {
                //childEvent方法是自动调用,只要你的/app1节点有状态变化,则就会自动执行该方法
                public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
                    //因为不管是:增加/删除/修改节点,都会执行该方法,但是具体是因为哪一种才执行该方法,则需要进一步确认
                    switch (treeCacheEvent.getType()) {
                        case NODE_ADDED:
                            System.out.println("监控到增加节点事件!");
                            System.out.println("有客户端上线了!");
                            break;
                        case NODE_REMOVED:
                            System.out.println("监控到节点移除事件!");
                            System.out.println("主节点挂掉了!");
                            System.out.println("让备用节点称为新的主节点!");
                            break;
                        case NODE_UPDATED:
                            System.out.println("监控到节点修改事件!");
                            //重新读取配置文件
                            break;
                        case CONNECTION_SUSPENDED:
                            break;
                        case CONNECTION_RECONNECTED:
                            break;
                        case CONNECTION_LOST:
                            break;
                        case INITIALIZED:
                            break;
                    }
    
                }
            });
            //开启监听
            treeCache.start();
    
            //让程序挂起
            while (true);
            //Thread.sleep(100000000);
        }
        
    
        //5、删除节点数据- rmr /app1
        @Test
        public void deleteZnode() throws Exception {
            //client.delete().forPath("/app1"); //该方法不能删除有子节点的znode
            client.delete().deletingChildrenIfNeeded().forPath("/app1"); //该方法可以删除所有节点
        }
    
        //4、查询节点属性 - get /app1
        //@Test
        //public void getZnodeAttr() throws Exception {
        //    CuratorFrameworkState state = client.getState();
        //    state.
        //
        //}
    
        //3、查询节点数据 - get /app1
        @Test
        public void getZnodeData() throws Exception {
            byte[] bytes = client.getData().forPath("/app1");
    
            String str = new String(bytes);
            System.out.println(str);
    
        }
    
        //2、修改节点数据 - set /app1 xxx
        @Test
        public void setZnode() throws Exception {
            //4:修改节点数据
            client.setData().forPath("/app1", "xxx".getBytes());
        }
    
        //1、创建节点- create /app1 hello
        @Test
        public void createZnode() throws Exception {
    
            //4:创建节点
            //client.create().forPath("/app1");   //情况1:没有数据,没有节点类型-默认创建的是永久节点
            //client.create().creatingParentsIfNeeded().forPath("/app1/app1_1");  //情况2:创建多级节点
    
             //client.create().creatingParentsIfNeeded().forPath("/app1/app1_2","hello".getBytes()); //情况3:创建多级节点并携带数据
    
            /*
             PERSISTENT                          -- 永久节点
             PERSISTENT_SEQUENTIAL               -- 永久顺序节点
             EPHEMERAL                           -- 临时节点
             EPHEMERAL_SEQUENTIAL(3, true, true); --临时顺序节点
             */
            client.create().creatingParentsIfNeeded().   //情况3:创建指定类型节点携带数据
                    withMode(CreateMode.EPHEMERAL).forPath("/app3","hello".getBytes());
            Thread.sleep(10000000L);
    
        }
    }
    
ZK的应用场景
1、主机状态监控
  通过创建临时节点和会话关系,来判断主机的健康状态
2、发布和订阅
3、分布式锁
4、注册中心
  服务提供者  服务消费者
5、分布式数据共享

ZK的选举机制
  • 概述

    1、场景1: 启动ZK,需要选举Leader
    
    node1启动 投自己1票  和其他主机交换投票信息,系统判断投票数是否过半,否
    node2启动 投自己1票  和其他主机交换投票信息,系统判断投票数是否过半,是,谁的myid最大,就是Leader   node3启动 投自己1票  和其他主机交换投票信息,发现已经有Leader了,直接成为Follower
    
    启动顺序: node3  ndoe2  node1    ----》node3就是leader
    
    2、场景2:ZK运行的过程中,Leader挂掉,需要选举Leader
      2.1 当Leader挂掉之后,系统会判断剩余的主机是否过半,是,则开始选举新Leader,否,则直接终止整个集群
      2.2 如果剩余的主机过半,则开始选举新Leader
         a:比较哪台主机的数据最新,如果某台主机的数据最新,则直接当选Leader
         b:如果所有主机的数据都是一样新的,则谁的myid最大,谁就是Leader
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值