zookeeper--知识点

一、zookeeper是分布式数据管理与协调框架,不适合存储大量数据,基础paxos算法 --主从选举

(原子消息广播协议),zookeeper一般都是集群存在,奇数个节点

1、顺序一致性

按照发起的顺序应用到zookeeper

客户端发送消息给zookeeper,消息遵循原子消息广播,消息都同步后才会返回客户端,会加锁,这个时候其他客户端不能操作这条消息,如果多个zookeeper节点间消息同步未成功,例如网络不通的时候,就会返回失败

2、原子性

3、单一视图

4、可靠性

zookeeper 将全量数据存储在内存中,针对非事务效率非常高

一半节点挂掉的时候就不对外提供服务了

zookeeper 是以简单的树形结构来进行相互协调,类似于一个标准的文件系统,

角色

leader

follower

observer

二、应用场景

配置管理     配置文件的动态变更

集群管理

发布与订阅

数据库切换

分布式锁,队列管理等

分布式日志收集

比如多个机器中的项目都有一份配置文件,修改一个配置文件,需要把修改的文件都同步到每个机器的每个项目中  ,就可以用zookeeper,项目中设置watcher,监听某个节点路径的信息

(数据量比较小,数据内容在运行时动态发生变化,集群中各个节点共享信息配置一致)

curator 框架  操作zookeeper 的框架

三、安装

解压到/usr/local/下

tar -zxvf zookeeper-3.4.5.tar.gz -C /usr/local/

zookeeper-3.4.5目录 移动到zookeeper

mv zookeeper-3.4.5/ zookeeper

也可以在后面这个地址下载  http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz

如果链接打不开,就先打开 http://mirror.bit.edu.cn/apache/zookeeper , 再选择版本。

更改zoo_sample.cfg  改成zoo.cfg

修改zoo.cfg

dataDir=/mnt/soft/zookeeper-3.4.5/data

/etc/profile

export ZOOKEEPER_HOME=/usr/local/zookeeper-3.4.13/

export PATH=$PATH:$ZOOKEEPER_HOME/bin

source /etc/profile

[root@localhost local]# cd /usr/local/zookeeper-3.4.13/bin
[root@localhost bin]# ./zkServer.sh start
./zkServer.sh status
默认端口2181
客户端
[root@localhost bin]# ./zkCli.sh

配置文件参数

数据结构

zookeeper命令

ls  /path   查找

create /path value      创建并赋值,不能重复创建,创建成功返回path,不允许递归创建节点,如果父节点不存在

create /path/path

get /path  获取

set /path  value  设值      value可以时 字符串  或文件,如果是文件的  存的是内容,或是二进制字节码

rmr /path  递归删除节点

delete /path/child   删除指定某个节点

四、java客户端调用

zookeeper客户端和服务器端会话的建立是一个异步的过程

一般用curator 调用客户端

节点类型

1、持久节点

2、持久顺序节点

3、临时节点       可以利用临时节点创建分布式锁   ,只在当前会话中有效,会话结束   path则消失

4、临时顺序节点

zookeeper 原始API

不允许递归创建节点

节点内容必须时字节数组,不支持序列化,如果需要序列化,可使用第三方框架   hessian,kryo

关闭防火墙

systemctl stop firewalld.service

<dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.6</version>
    </dependency>

添加log4j.properties

import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

public class ZkTest {

    /**
     * 集群地址
     */
    private static final String CONNECT_ADDRES = "192.168.233.100:2181";
    /**
     * 超时时间
     */
    private static final int SESSIONTIME = 2000;
    private static final CountDownLatch countDownLatch = new CountDownLatch(1);

    public static void main(String[] args) throws Exception, InterruptedException, KeeperException {
        ZooKeeper zk = new ZooKeeper(CONNECT_ADDRES, SESSIONTIME, new Watcher() {

            public void process(WatchedEvent event) {
                // 获取时间的状态
                KeeperState keeperState = event.getState();
                EventType tventType = event.getType();
                // 如果是建立连接
                if (KeeperState.SyncConnected == keeperState) {
                    if (EventType.None == tventType) {
                        // 如果建立连接成功,则发送信号量,让后阻塞程序向下执行
                        countDownLatch.countDown();
                        System.out.println("zk 建立连接");
                    }
                }else {
                    System.out.println("zk 建立失败");
                }
            }

        });
        // 进行阻塞
        countDownLatch.await();
        // 创建父节点
        // String result = zk.create("/testRott", "12245465".getBytes(),
        // Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        // System.out.println("result:" + result);
        // 创建子节点
        String result = zk.create("/testRott/children", "children 12245465".getBytes(), Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT);
        System.out.println("result:" + result);
        zk.close();
    }

}

五、zookeeper 事件监听

客户端发送请求到 某一个节点zookeeper,该节点就会建立一个watcher,这个watcher的动作事件叫watch,watch 是一次性的 ,boolean    true   代表该watcher时候还监听

Watcher 可以监听某一个路径,对某一个路径设置监听
package com.itman;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

public class ZkWatcher implements Watcher {

    /**
     * 集群地址
     */
    private static final String CONNECT_ADDRES = "169.254.197.135:2181";
    private static ZooKeeper zooKeeper;
    /**
     * 超时时间
     */
    private static final int SESSIONTIME = 2000;

    public ZkWatcher() {
        createConnection(CONNECT_ADDRES, SESSIONTIME);
    }

    // zk节点、发生变更、删除、修改 、 新增 事件通知
    public void process(WatchedEvent event) {
        KeeperState keeperState = event.getState();
        // 事件类型
        EventType eventType = event.getType();
        // 节点名称
        String path = event.getPath();
        System.out.println(
                "#####process()####调用####keeperState:" + keeperState + ",eventType:" + eventType + ",path:" + path);
        if (KeeperState.SyncConnected == keeperState) {
            // 连接类型
            if (EventType.None == eventType) {
                // 建立zk连接
                System.out.println("建立zk连接成功!");
            }
            // 创建类型
            if (EventType.NodeCreated == eventType) {
                System.out.println("####事件通知,当前创建一个新的节点####路径:" + path);
            }
            // 修改类型
            if (EventType.NodeDataChanged == eventType) {
                System.out.println("####事件通知,当前创建一个修改节点####路径:" + path);
            }
            // 删除类型
            if (EventType.NodeDeleted == eventType) {
                System.out.println("####事件通知,当前创建一个删除节点####路径:" + path);
            }
        }
        System.out.println("####################################################");
        System.out.println();
    }

    // 创建zk连接
    private void createConnection(String connectAddres, int sessiontime) {
        try {
            zooKeeper = new ZooKeeper(connectAddres, sessiontime, this);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    // 创建节点
    public void createNode(String path, String data) {
        try {
            String result = zooKeeper.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("创建节点成功....result:" + result);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 修改节点
    public void updateNode(String path, String data) {
        try {
            zooKeeper.setData(path, data.getBytes(), -1);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    // 删除节点
    public void deleNode(String path) {
        try {
            zooKeeper.delete(path, -1);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public void close() {
        try {
            if (zooKeeper != null)
                zooKeeper.close();
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public static void main(String[] args) throws KeeperException, InterruptedException {
        ZkWatcher zkWatcher = new ZkWatcher();
        // zkWatcher.createNode("/parent1", "6452852");
        String path = "/parent1";
        zooKeeper.exists(path, true);
        // zkWatcher.updateNode(path, "88888");
        zkWatcher.deleNode(path);
        zkWatcher.close();
    }
}

六、zookeeper 安装认证

acl认证

七、zookeeper 第三方实现

zkclient

subscribeChildChanges("/super","")

只监听当前节点和当前节点下的新增和删除

subscribeDataChanges("/super","")

对父节点添加监听子节点变化

curator

 
 
原文地址:https://www.cnblogs.com/jentary/p/12291115.html