zookeeper介绍

zookeeper是什么

        zookepper是hadoop的一个子项目,Apache软件基金会下的一个项目,用于分布式程序的协调服务。具体是什么呢?打个比方,我们可以把整个分布式应用程序想象成一个人,分布式应用程序由不同服务组成,就好比一个人由不同的器官组成,比如一个人有头,有手,有脚,眼睛,鼻子等。那么zookeeper在分布式系统中充当一个什么角色呢?我们可以把zookeeper想象成人体中的大脑,负责协调人体的不同器官。

zookeeper的应用场景

1.数据的发布与订阅          

        发布者将数据发布出来,订阅者通过一定的方式获取到这些数据ZooKeeper采用推模式和拉模式两种方式结合的方式。发布者将数据发布到zk集群节点上,订阅者通过一定的方法告诉服务器,我对哪个节点的数据感兴趣,那服务器在这些节点的数据发生变化时,就通知客户端,客户端得到通知后可以去服务器获取数据信息。

2.负载均衡

        举个例子,DB或者某个服务在启动的时候会在zookeeper上注册一个临时节点,zookeeper中有两种节点类型,一种是永久节点,另一种是临时节点,如果在启动的时候出现问题,那么该服务在zookeeper上注册的节点就会自动删除,这样在zookeeper中就会保留最新的并且可用的节点。

        客户端需要在数据库中读写数据时,首先需要在zookeeper中获取数据库的可用的连接信息,然后客户端会随机选择一个建立连接,当发现这个连接不可用时,客户读会再次到zookeeper中获取可用的连接信息,也可以在zookeeper中删除这个不可用的连接再建立一个新的连接。

3.分布式协调通知

        在zookeeper中判断某个服务是否可用,是通过判断这个服务在zookeeper中创建的一个临时节点是否存在,如果这个临时节点不存在说明这个服务不可用,相反可用。       

4.命名服务

        命名服务就是提供名称的服务,Zookeeper的命名服务有两个应用方面。一个是提供类似JNDI功能,另一个是制作分布式的序列号生成器

        JNDI功能,我们利用Zookeeper的分层结构,可以把系统中的各种服务的名称、地址、以及目录信息存放在Zookeeper中,需要的时候去Zookeeper中读取。
        另一个是利用Zookeeper循序节点的特性,制作分布式的序列号生成器,或者叫id生成器。 (分布式环境下使用作为数据库id,另外一种是UUID(缺点:没有规律)),Zookeeper可以生成有顺序的容易理解的同时支持分布式环境的编号。

zookeeper原始api的使用

package com.weibaoer;

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

public class ZookeeperNativeApi implements Watcher {

    private static final String PARENT_PATH="/parent";

    private static final String CHILD_PATH="/child";

    private static final String PARENT_DATA="parent";
    private static final String CHILD_DATA="child";

    private static final Integer SESSION_TIMEOUT=5000;

    private static final String CONNECT_URL="127.0.0.1:2181";

    private ZooKeeper zookeeper;

    private CountDownLatch countDownLatch=new CountDownLatch(1);

    public void createConnect(){
        try {
            zookeeper=new ZooKeeper(CONNECT_URL,SESSION_TIMEOUT,this);
            countDownLatch.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void close(){
        if(zookeeper!=null){
            try {
                zookeeper.close();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public void create(String path,String data,Boolean needWatch){
        try {
            zookeeper.exists(path,needWatch);
            String root = zookeeper.create(path, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println(root);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void delete(String path,Boolean needWatch){
        try {
            zookeeper.exists(path,needWatch);
            zookeeper.delete(path,-1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }

    public void setData(String path,Boolean needWatch){
        try {
            zookeeper.exists(path,needWatch);
            zookeeper.setData(path,"hello".getBytes(),-1);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void process(WatchedEvent watchedEvent) {
        try {
            countDownLatch.countDown();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(watchedEvent==null){
            return;
        }
        String path = watchedEvent.getPath();
        Event.KeeperState state = watchedEvent.getState();
        Event.EventType type = watchedEvent.getType();
        if(state==Event.KeeperState.SyncConnected){
            if(type==Event.EventType.None){
                System.out.println("连接成功!");
            }else if(type==Event.EventType.NodeCreated){
                System.out.println("创建节点:"+path);
            }else if(type==Event.EventType.NodeDataChanged){
                System.out.println("更新节点:"+path);
            }else if(type==Event.EventType.NodeChildrenChanged){
                System.out.println("孩子节点变化:"+path);
            }
        }else{
            System.out.println("连接失败!");
        }

    }

    public static void main(String[] args) {

        ZookeeperNativeApi zookeeperWatch=new ZookeeperNativeApi();
        zookeeperWatch.createConnect();

        zookeeperWatch.create(PARENT_PATH,PARENT_DATA,false);

        zookeeperWatch.close();

    }
}

curator使用

package com.weibaoer;

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.apache.zookeeper.data.Stat;

import java.util.List;

public class ZookeeperCuratorApi {

    //zookeeper的连接地址
    private static final String CONNECT_STRING="127.0.0.1:2181";

    //zookeeper的session过期时间
    private static final Integer SESSION_TIMEOUT=5000;

    //重试策略:初试时间为1s 重试10次
    private static final RetryPolicy retryPolicy=new ExponentialBackoffRetry(1000,10);


    private CuratorFramework curatorFramework;

    //创建一个连接
    public void createConnect(){
        //链式编程创建一个curatorFramework对象
        curatorFramework=CuratorFrameworkFactory.builder()
                .connectString(CONNECT_STRING)
                .sessionTimeoutMs(SESSION_TIMEOUT)
                .retryPolicy(retryPolicy)
                .build();
        //开启一个连接
        curatorFramework.start();
//        System.out.println(ZooKeeper.States.CONNECTED);
        //获取链接状态
        System.out.println(curatorFramework.getState());
    }

    //释放连接
    public void releaseConnect(){
        if(curatorFramework!=null){
            curatorFramework.close();
        }
    }

    //通过curatorFramework对象创建一个节点
    public void createNode(String path,String data){

        //4 建立节点 指定节点类型(不加withMode默认为持久类型节点)、路径、数据内容
        try {
            curatorFramework.create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.PERSISTENT)
                    .forPath(path,data.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //删除节点
    public void delete(String path){
        try {
            curatorFramework.delete()
                    .guaranteed()
                    .deletingChildrenIfNeeded()
                    .forPath(path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取节点数据
    public void getData(String path){
        try {
            byte[] datas = curatorFramework.getData().forPath(path);
            System.out.println(new String(datas,"UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //更新节点数据
    public void setData(String path,String data){
        try {
            curatorFramework.setData().forPath(path, data.getBytes("UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取某个节点的子节点
    public void getChildren(String path){
        try {
            List<String> childNodes = curatorFramework.getChildren().forPath(path);
            for (String node:childNodes) {
                System.out.println(node);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //判断某个节点是否存在
    public void checkNodeExists(String path){
        try {
            Stat stat = curatorFramework.checkExists().forPath(path);
            System.out.println(stat);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //删除子节点
    public void deleteChilds(String path){
        try {
            curatorFramework.delete()
                    .guaranteed()
                    .deletingChildrenIfNeeded()
                    .forPath(path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static void main(String[] args) {
        ZookeeperCuratorApi zookeeperCuratorApi=new ZookeeperCuratorApi();
        zookeeperCuratorApi.createConnect();

        zookeeperCuratorApi.createNode("/super/c1","111111");
        zookeeperCuratorApi.createNode("/super/c2","222222");
        zookeeperCuratorApi.checkNodeExists("/super");
        zookeeperCuratorApi.getData("/super/c1");
        zookeeperCuratorApi.setData("/super/c1","333333");
        zookeeperCuratorApi.getData("/super/c1");
//        zookeeperCuratorApi.deleteChilds("/super");
        zookeeperCuratorApi.delete("/super");

        zookeeperCuratorApi.releaseConnect();
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值