zookeeper学习

目录

一、Zookeeper概念

二、Zookeeper下载与安装

三、Zookeeper的操作

1. 命令操作

1.1 Zookeeper的数据模型

1.2 Zookeeper服务端常用命令

1.3 zookeeper客户端常用命令

2. API操作

2.1 Curator的介绍

2.2 Curator API的常用操作

2.3 分布式锁

2.4 模拟12306售票

3. 集群

3.1 zookeeper集群搭建

3.2 zookeeper集群角色


一、Zookeeper概念

配置中心的作用:注意在这里,如果我们没有使用配置中心,当我们需要获取数据库资源的时候,A\B\C需要分别获取,这样的话一旦数据库发生改变,我们就需要分别给A\B\C进行修改,如果我们当前的服务器更多的话,要修改的岂不是更多!

分布式锁的使用:当我们当前有个服务A获取到了资源,这个时候多个线程访问服务A的时候,我们怎么保证数据的正确性?----加锁。但是如果当前除了服务A还有服务B也获得了资源,那么加锁就没用了,因为当前的资源可以在服务A上也可以在服务B上被修改,那么这个时候就需要加分布式锁了,当服务A需要访问的时候,就先找分布式锁要,如果当前空闲,就可以分配给A,不空闲A就只可以等待!

二、Zookeeper下载与安装

zookeeper下载与安装详解【linux单机】一定会安装_young_man2的博客-CSDN博客

三、Zookeeper的操作

1. 命令操作

1.1 Zookeeper的数据模型

1.2 Zookeeper服务端常用命令

1.3 zookeeper客户端常用命令

./zkCli.sh localhost:2181   #连接本地
quit  #退出

ls /  #进入客户端之后使用此命令查看下面的子包

create /app1 +数据 #创建子节点app1

get /app1  #获取子节点

set /app1 +数据  #设置数据

delete /app1  #删除子节点,只可以删除空节点

deleteall /app1  #删除所有节点,可以不为空

help  #帮助命令


create -e /app1  #创建一个临时节点app1 当前退出之后,临时节点被关闭

create -s /app1  #创建一个顺序节点app1,有编号的

create -es /app1 #创建一个临时的顺序节点

ls -s /app1  #查看节点app1的详细信息

2. API操作

2.1 Curator的介绍

●Curator 是Apache ZooKeeper的Java客户端库.
●常见的ZooKeeper Java API :
        原生Java API
        ZkClient
        Curator
●Curator项目的目标是简化ooKeeper客户端的使用。
●Curator最初是Netfix研发的,后来捐献了Apache基金会,目前是Apache的顶级项目。

2.2 Curator API的常用操作

1. 建立连接

package com.wxy.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.junit.Test;

public class CuratorTest {

    /*
    * 建立连接
    * */
    @Test
    public void testConnect(){
        /*
        * 这里我们需要将curator和zk进行连接,我们就需要要使用CuratorFramework,但是他是接口,所以我们只能使用
        * 它的工厂方法CuratorFrameworkFactory
        * */

        //第一种方式
        /*
        * 四个参数
        * 1. 连接字符串 zk server地址和端口
        * 2. 会话超时时间 单位是毫秒
        * 3. 连接超时时间
        * 4. 超市策略
        * */
        RetryPolicy retryPolicy=new ExponentialBackoffRetry(3000,10);
        CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.122.1", 60 * 1000, 15 * 1000, retryPolicy);

        //开启链接
        client.start();

        //第二种方式
        //CuratorFrameworkFactory.builder()
       /* CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder().connectString("192.168.122.1").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy);
        CuratorFramework build = builder.build();
        build.start();*/
        CuratorFramework client1 = CuratorFrameworkFactory.builder().connectString("192.168.122.1").
                sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy).namespace("wxy").build();
        //这里添加namespace就会默认下次创建会在这个目录(节点)下进行创建,可以简化代码
        client1.start();

    }

}

连接成功后如下显示

2. 添加节点

package com.wxy.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
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 CuratorTest {
    private CuratorFramework client;

    /*
    * 建立连接
    * */
    @Before
    public void testConnect(){
        /*
        * 这里我们需要将curator和zk进行连接,我们就需要要使用CuratorFramework,但是他是接口,所以我们只能使用
        * 它的工厂方法CuratorFrameworkFactory
        * */

        //第一种方式
        /*
        * 四个参数
        * 1. 连接字符串 zk server地址和端口
        * 2. 会话超时时间 单位是毫秒
        * 3. 连接超时时间
        * 4. 超市策略
        * */
        RetryPolicy retryPolicy=new ExponentialBackoffRetry(3000,10);
         client = CuratorFrameworkFactory.newClient("192.168.122.1", 60 * 1000, 15 * 1000, retryPolicy);

        //开启链接
        client.start();

        //第二种方式
        //CuratorFrameworkFactory.builder()
       /* CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder().connectString("192.168.122.1").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy);
        CuratorFramework build = builder.build();
        build.start();*/
        CuratorFramework client1 = CuratorFrameworkFactory.builder().connectString("192.168.122.1").
                sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy).namespace("wxy").build();
        //这里添加namespace就会默认下次创建会在这个目录(节点)下进行创建,可以简化代码
        client1.start();

    }

    @Test
    public void testCreate1() throws Exception {
        //1. 创建节点,带有数据

        String path = client.create().forPath("app2","hello".getBytes());
        System.out.println(path);

    }
    @Test
    public void testCreate2() throws Exception {
        //2. 基本创建
        //如果创建节点的时候没有传输数据,默认将ip数据传输进来
        String path = client.create().forPath("/app1");
        System.out.println(path);

    }
    @Test
    public void testCreate3() throws Exception {
        //3. 设置节点的类型

        String path = client.create().withMode(CreateMode.EPHEMERAL).forPath("app2","hello".getBytes());
        System.out.println(path);

    }

    @Test
    public void testCreate4() throws Exception {
        //4. 设置多级节点
        //平常是不允许直接创建多级节点的,因为此时app3不存在,需要使用creatingParentsIfNeeded()
        String path = client.create().creatingParentsIfNeeded().forPath("/app3/s1");
        System.out.println(path);
    }

    @After
    public void close(){  //释放资源
        if(client!=null){
            client.close();
        }
    }

}

3. 删除节点

/*******************************delete****************************************/
    /*
    * 删除节点  delete   deleteall
    *1. 删除单个节点
    *2. 删除带有子节点的节点
    *3. 必须成功的删除
    *4. 回调
    * */
    @Test
    public void testDelete1() throws Exception {
        //1. 删除单个节点
        client.delete().forPath("/app1");
    }
    @Test
    public void testDelete2() throws Exception {
        //2. 删除带有子节点的节点
        client.delete().deletingChildrenIfNeeded().forPath("/app1");
    }
    public void testDelete3() throws Exception {
        //3. 必须成功的删除
        client.delete().guaranteed().forPath("/app1");
    }
    public void testDelete4() throws Exception {
        //4. 回调
        client.delete().guaranteed().inBackground(new BackgroundCallback() {
            @Override
            public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
                
            }
        }).forPath("/app1");
    }

4. 修改节点

@Test
    public void testSet() throws Exception {
        //修改数据
        client.setData().forPath("/app1","hahha".getBytes());
    }
    @Test
    public void testSetForVersion() throws Exception {
        //根据版本修改
        Stat stat=new Stat();
        client.getData().storingStatIn(stat).forPath("/app1");
        int version=stat.getVersion();
        client.setData().withVersion(version).forPath("/app1","hahha".getBytes());
    }

5. 查找节点

 /**************************************Get****************************************************/
    /*
    * 查询节点
    * 1. 查询子节点
    * 2. 查询数据
    * 3. 查询节点状态信息    *
    * */
    @Test
    public void testGet1() throws Exception {
        //1. 查询数据
        byte[] bytes = client.getData().forPath("/app1");
    }

    @Test
    public void testGet2() throws Exception {
        //2. 查询子节点
        List<String> strings = client.getChildren().forPath("/app4");
        System.out.println(strings);
    }
    @Test
    public void testGet3() throws Exception {
        //2. 查询节点状态信息
        Stat stat=new Stat();
        client.getData().storingStatIn(stat).forPath("/app1");
    }

6. watch事件监听

6.1 NodeCache监听某一个特定的节点

package com.wxy.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
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;

import java.util.List;

public class CuratorTest {
    private CuratorFramework client;

    /*
    * 建立连接
    * */
    @Before
    public void testConnect() {
        /*
         * 这里我们需要将curator和zk进行连接,我们就需要要使用CuratorFramework,但是他是接口,所以我们只能使用
         * 它的工厂方法CuratorFrameworkFactory
         * */

        //第一种方式
        /*
         * 四个参数
         * 1. 连接字符串 zk server地址和端口
         * 2. 会话超时时间 单位是毫秒
         * 3. 连接超时时间
         * 4. 超市策略
         * */
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
        client = CuratorFrameworkFactory.newClient("192.168.122.1", 60 * 1000, 15 * 1000, retryPolicy);

        //开启链接
        client.start();

        //第二种方式
        //CuratorFrameworkFactory.builder()
       /* CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder().connectString("192.168.122.1").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy);
        CuratorFramework build = builder.build();
        build.start();*/
        CuratorFramework client1 = CuratorFrameworkFactory.builder().connectString("192.168.122.1").
                sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy).namespace("wxy").build();
        //这里添加namespace就会默认下次创建会在这个目录(节点)下进行创建,可以简化代码
        client1.start();
    }

    @After
    public void close(){  //释放资源
        if(client!=null){
            client.close();
        }
    }

    @Test
    public void testCacheNode() throws Exception {
        //创建NodeCache对象
        NodeCache nodeCache=new NodeCache(client,"/app1");
        //注册监听
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                System.out.println("节点变化了");
            }
        });
        //开启监听,如果设置为true则开启监听时加载缓存数据
        nodeCache.start(true);

    }

}

6.2 PathChildrenCache 监控一个ZNode的子节点

package com.wxy.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.framework.recipes.cache.*;
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;

import java.util.List;

public class CuratorTest {
    private CuratorFramework client;

    /*
    * 建立连接
    * */
    @Before
    public void testConnect() {
        /*
         * 这里我们需要将curator和zk进行连接,我们就需要要使用CuratorFramework,但是他是接口,所以我们只能使用
         * 它的工厂方法CuratorFrameworkFactory
         * */

        //第一种方式
        /*
         * 四个参数
         * 1. 连接字符串 zk server地址和端口
         * 2. 会话超时时间 单位是毫秒
         * 3. 连接超时时间
         * 4. 超市策略
         * */
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
        client = CuratorFrameworkFactory.newClient("192.168.122.1", 60 * 1000, 15 * 1000, retryPolicy);

        //开启链接
        client.start();

        //第二种方式
        //CuratorFrameworkFactory.builder()
       /* CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder().connectString("192.168.122.1").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy);
        CuratorFramework build = builder.build();
        build.start();*/
        CuratorFramework client1 = CuratorFrameworkFactory.builder().connectString("192.168.122.1").
                sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy).namespace("wxy").build();
        //这里添加namespace就会默认下次创建会在这个目录(节点)下进行创建,可以简化代码
        client1.start();
    }

    @After
    public void close(){  //释放资源
        if(client!=null){
            client.close();
        }
    }

    @Test
    public void testPathChildrenNode() throws Exception {
        //1. 创建监听对象
        PathChildrenCache pathChildrenCache=new PathChildrenCache(client,"/app2",true);

        //2. 绑定监听器
        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
                System.out.println("子节点变化了");

                //1. 获取类型
                PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();
                //2. 判断类型是不是update
                if(type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
                    byte[] data = pathChildrenCacheEvent.getData().getData();  //这里才是我们真正的数据
                    System.out.println(new String(data));

                }
            }
        });
         //3. 开启监听
        pathChildrenCache.start();

    }

}

3. TreeCache(可以监听整个树上的所有节点)

package com.wxy.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.framework.recipes.cache.*;
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;

import java.util.List;

public class CuratorTest {
    private CuratorFramework client;

    /*
    * 建立连接
    * */
    @Before
    public void testConnect() {
        /*
         * 这里我们需要将curator和zk进行连接,我们就需要要使用CuratorFramework,但是他是接口,所以我们只能使用
         * 它的工厂方法CuratorFrameworkFactory
         * */

        //第一种方式
        /*
         * 四个参数
         * 1. 连接字符串 zk server地址和端口
         * 2. 会话超时时间 单位是毫秒
         * 3. 连接超时时间
         * 4. 超市策略
         * */
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
        client = CuratorFrameworkFactory.newClient("192.168.122.1", 60 * 1000, 15 * 1000, retryPolicy);

        //开启链接
        client.start();

        //第二种方式
        //CuratorFrameworkFactory.builder()
       /* CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder().connectString("192.168.122.1").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy);
        CuratorFramework build = builder.build();
        build.start();*/
        CuratorFramework client1 = CuratorFrameworkFactory.builder().connectString("192.168.122.1").
                sessionTimeoutMs(60 * 1000).connectionTimeoutMs(60 * 1000).retryPolicy(retryPolicy).namespace("wxy").build();
        //这里添加namespace就会默认下次创建会在这个目录(节点)下进行创建,可以简化代码
        client1.start();
    }

    @After
    public void close(){  //释放资源
        if(client!=null){
            client.close();
        }
    }

    @Test
    public void testTreeCache() throws Exception {
       TreeCache treeCache=new TreeCache(client,"/app1");
       treeCache.getListenable().addListener(new TreeCacheListener() {
           @Override
           public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
               System.out.println("节点变化了");
               System.out.println(treeCacheEvent);
           }
       });

    }

}

2.3 分布式锁

为什么创建临时的?

因为如果是持久的,一旦发生宕机,节点就无法删除,锁就不能释放,但是是临时的就可以自己释放

为什么要是顺序的? 

因为要找最小的节点

2.4 模拟12306售票

3. 集群

3.1 zookeeper集群搭建

集群搭建请看下面的链接

链接:https://pan.baidu.com/s/12oOu5HOQdwB1Lnc_9lhRvA 
提取码:dzdz

3.2 zookeeper集群角色

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值