【博学谷学习记录】超强总结,用心分享|Zookeeper入门-part02

ZK的Znode节点特性

1、ZK的Znode节点是一个树形结构,最上边是根/节点

2、ZK的Znode节点既像文件(存数据),又像文件夹(可以有子节点)

3、ZK的Znode一般用来存储配置信息,数据量不会太大,每个Znode节点最多不超过1M数据

4、ZK的Znode节点必须使用绝对路径来访问,不能使用相对路径

ZK的Znode节点类型

PERSISTENT:永久节点

EPHEMERAL: 临时节点(临时节点会比永久节点更有用)(临时节点巧妙的地方在于宕机了断开链接watch机制能够监听的到)

PERSISTENT_SEQUENTIAL:永久节点、序列化(顺序)

EPHEMERAL_SEQUENTIAL: 临时节点、序列化(顺序)

ZK的Znode节点的属性

mZxid :Znode被修改的事务id,即每次对znode的修改都会更新mZxid。

ephemeralOwner:如果该节点为临时节点, ephemeralOwner值表示与该节点绑定的session id. 如果不是, ephemeralOwner值为0.

Zk的监听机制

监听(watch)节点(创建、修改、删除)。触发行为,在监听到节点发生变动的时候对应会做出什么行为。

Zk的操作代码

package pack01_zookeeper_api;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
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.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ZookeeperDemo1 {

    CuratorFramework client;

    // 初始化 会在@Test之前执行
    @Before
    public void init(){
        // 1:定制一个重试策略
        /*
         * 3000:如果没连接上zk集群,则每个3秒重试一次
         * 3:最多重试3次
         * 一般用多态的写法,左边是接口,右边是接口的实现类对象
         * */
        RetryPolicy retryPolicynew = new ExponentialBackoffRetry(3000, 3);

        // 2:获取zk的客户端对象
        String serverList = "192.168.88.101:2181,192.168.88.102:2181,192.168.88.103:2181";
        client = CuratorFrameworkFactory.newClient(serverList, retryPolicynew);

        // 3:开启客户端
        client.start();
    }

    // 会在@Test执行之后再执行 适合关闭代码
    @After
    public void close(){
        // 5:关闭客户端
        client.close();
    }

    // Zookeeper的监听机制
    @Test
    public void ZnodeWatch() throws Exception {
        // 1: 将要监听的节点树存入缓存中 把/app1这个节点的所有子节点都放入缓存中
        TreeCache treeCache = new TreeCache(client, "/app1");

        // 2: 自定义监听 获取开启列表?新增监听器(监控行为,触发行为干什么事情)
        // 匿名内部类 new接口的实现类对象
        treeCache.getListenable().addListener(new TreeCacheListener() {

            // childEvent 该方法自动执行,只要有事件被触发,就会自动执行该方法。
            // CuratorFramework 核心框架对象,一般不用。
            // TreeCacheEvent 树缓存事件
            public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
                // 不管是增加、删除、修改节点,都会执行该方法,具体是哪种行为需要使用treeCacheEvent对象判断
                switch (treeCacheEvent.getType()) {
                    case NODE_ADDED:
                        System.out.println("监控到增加节点事件,有客户端上线了。");
                        break;
                    case NODE_REMOVED:
                        System.out.println("监控到删除节点事件,有客户端下线了。");
                        break;
                    case NODE_UPDATED:
                        System.out.println("监控到修改节点数据事件。");
                        break;
                    case CONNECTION_SUSPENDED:
                        break;
                    case CONNECTION_LOST:
                        break;
                    case CONNECTION_RECONNECTED:
                        break;
                    case INITIALIZED:
                        break;
                }
            }
        });

        // 3: 开启监听
        treeCache.start();

        // 4: 程序挂起 为了测试监听
        Thread.sleep(100000000);

    }

    // 删除节点
    @Test
    public void deleteZnode() throws Exception {
        // 该方法不能删除有子节点的节点
        // client.delete().forPath("/app1");

        // 删除带有子节点的节点
        client.delete().deletingChildrenIfNeeded().forPath("/app2");
    }


    // 获取节点数据
    @Test
    public void getZnode() throws Exception {
        byte[] bytes = client.getData().forPath("/app1");
        String data = new String(bytes);
        System.out.println(data);
    }

    // 修改节点数据
    @Test
    public void changeZnode() throws Exception {
        client.setData().forPath("/app1", "node1".getBytes());
    }


    // 单元测试,Znode节点的创建
    @Test
    public void CreateZnode() throws Exception {

        // 4:进行zk节点创建 -> 节点类型、节点路径、节点携带的初始数据
        // 创建永久节点-单级
        // client.create().withMode(CreateMode.PERSISTENT).forPath("/app1", "mac_localhost".getBytes());
        // 创建永久节点-多级 creatingParentsIfNeeded递归创建
        // client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/app1", "mac_localhost".getBytes());
        // 也可以不携带初始数据创建节点
        client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/app1");

    }

}

ZK的选举机制

zookeeper默认的算法是FastLeaderElection,采用投票数大于半数则胜出的逻辑。

场景1:集群首次启动选举

node1首次启动会先投自己一票,然后寻找其他主机交流,判断票数是否过半;node2首次启动也会投自己一票,然后寻找其他主机交流,判断票数是否过半,如果过半,则比较两台主机的myid直谁大,谁大谁就是leader,顺理成章node2成为leader,node1成为follower;node3首次启动也会投自己一票,然后寻找其他主机交流,但发现已经有leader了,就会直接成为follower。

场景2:Leader宕机重新选举

如果在集群运行的过程中,leader宕机了,则内部会开始重新选择,首先会比较剩余存活follower的数据新旧程序(mzxid)数据越新mzxid的值越大那么谁就会成为leader。如果所有follower的mzxid值都相同,那么就会去比较myid,谁的myid大谁就是leader。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值