首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zookeeper入门

zookeeper入门

作者头像
LiosWong
发布2019-05-13 16:18:57
6460
发布2019-05-13 16:18:57
举报
文章被收录于专栏:后端沉思录后端沉思录

Apache ZooKeeper是Apache软件基金会的一个软件项目,他为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。ZooKeeper曾经是Hadoop的一个子项目,但现在是一个独立的顶级项目。 ZooKeeper的架构通过冗余服务实现高可用性。因此,如果第一次无应答,客户端就可以询问另一台ZooKeeper主机。ZooKeeper节点将它们的数据存储于一个分层的命名空间,非常类似于一个文件系统或一个前缀树结构。客户端可以在节点读写,从而以这种方式拥有一个共享的配置服务。更新是全序的。--维基百科

搭建
  • 单机配置
    • 去官网上下载https://archive.apache.org/dist/zookeeper/,然后解压
    • copy conf/zoo_sample.cfg文件重命名为zoo.cfg,并配置修改
    • /bin/zkServer.sh start 启动服务 zoo.cfg配置文件如下:
        # The number of milliseconds of each tick        tickTime=2000        # The number of ticks that the initial        # synchronization phase can take        initLimit=10        # The number of ticks that can pass between        # sending a request and getting an acknowledgement        syncLimit=5        # the directory where the snapshot is stored.        dataDir=/Users/wenchao.wang/dev/zookeeper/data        dataLogDir=/Users/wenchao.wang/dev/zookeeper/logs
        # the port at which the clients will connect        clientPort=2181
  • 集群配置 一般zookeeper集群由三台及以上机器组成,只要集群中存在超过一半的机器能够正常工作,那么整个集群就能够正常对外服务.下面将安装三个节点的zookeeper集群,即一个leader、两个follower.
    • 下载安装包、解压(同上)
    • 把解压包copy三份,分别命名为zookeeper-node-1、zookeeper-node-2、zookeeper-node-3
    • 分别copy三个节点下conf/zoo_sample.cfg文件重命名为zoo.cfg,并修改配置
    • 然后在zookeeper-node-1、zookeeper-node-2、zookeeper-node-3同级目录下创建目录zookeeper-data/8001/data、zookeeper-data/8002/data、zookeeper-data/8003/data、zookeeper-data/8001/logs、zookeeper-data/8002/logs、zookeeper-data/8003/logs
    • 在zookeeper-data/8001/data、zookeeper-data/8002/data、zookeeper-data/8003/data目录下分别创建文件myid,分别在myid中写入1,2,3
    • /bin/zkServer.sh start 分别启动三台服务 zoo.cfg配置如下:
        # The number of milliseconds of each tick        # The number of milliseconds of each tick        tickTime=2000        # The number of ticks that the initial        # synchronization phase can take        initLimit=10        # The number of ticks that can pass between        # sending a request and getting an acknowledgement        syncLimit=5        # the directory where the snapshot is stored.        dataDir=/Users/wenchao.wang/dev/zookeeper-cluster/zookeeper-data/8002/data        # dataDir=/Users/wenchao.wang/dev/zookeeper-cluster/zookeeper-data/8001/data        # dataDir=/Users/wenchao.wang/dev/zookeeper-cluster/zookeeper-data/8003/data        dataLogDir=/Users/wenchao.wang/dev/zookeeper-cluster/zookeeper-data/8002/logs        # dataLogDir=/Users/wenchao.wang/dev/zookeeper-cluster/zookeeper-data/8001/logs        # dataLogDir=/Users/wenchao.wang/dev/zookeeper-cluster/zookeeper-data/8003/logs
        # the port at which the clients will connect        clientPort=2182        # clientPort=2181        # clientPort=2183
        # server.number (number是1、2、3)分别对应myid中的内容,        # zookeeper也是通过server后面的数字以及dataDir下的myid内容来判断zookeeper集群的关系的(哪个server对应哪个地址),然后后面两个端        # 口号,一个是跟服务器发送链接的端口,另一个是接受服务器链接的端口        server.1=127.0.0.1:8001:9001        server.2=127.0.0.1:8002:9002        server.3=127.0.0.1:8003:9003

下面是在本地机器上配置的zookeeper集群三级目录树状图:

        /Users/wenchao.wang/dev/zookeeper-cluster        ├── zookeeper-data        │   ├── 8001        │   │   ├── data        │   │   └── logs        │   ├── 8002        │   │   ├── data        │   │   └── logs        │   └── 8003        │       ├── data        │       └── logs        ├── zookeeper-node-1        │   ├── bin        │   ├── conf        │   ├── contrib        │   │   ├── ZooInspector        │   │   ├── bookkeeper        │   │   ├── fatjar        │   │   ├── rest        │   │   ├── zkfuse        │   │   ├── zkperl        │   │   ├── zkpython        │   │   └── zktreeutil        │   ├── data        │   ├── dist-maven        │   ├── docs        │   │   ├── api        │   │   ├── images        │   │   ├── jdiff        │   │   └── skin        │   ├── lib        │   │   ├── cobertura        │   │   └── jdiff        │   ├── recipes        │   │   ├── lock        │   │   └── queue        │   └── src        │       ├── c        │       ├── contrib        │       ├── docs        │       ├── java        │       └── recipes        ├── zookeeper-node-2        │   ├── bin        │   ├── conf        │   ├── contrib        │   │   ├── ZooInspector        │   │   ├── bookkeeper        │   │   ├── fatjar        │   │   ├── rest        │   │   ├── zkfuse        │   │   ├── zkperl        │   │   ├── zkpython        │   │   └── zktreeutil        │   ├── data        │   ├── dist-maven        │   ├── docs        │   │   ├── api        │   │   ├── images        │   │   ├── jdiff        │   │   └── skin        │   ├── lib        │   │   ├── cobertura        │   │   └── jdiff        │   ├── recipes        │   │   ├── lock        │   │   └── queue        │   └── src        │       ├── c        │       ├── contrib        │       ├── docs        │       ├── java        │       └── recipes        └── zookeeper-node-3            ├── bin            ├── conf            ├── contrib            │   ├── ZooInspector            │   ├── bookkeeper            │   ├── fatjar            │   ├── rest            │   ├── zkfuse            │   ├── zkperl            │   ├── zkpython            │   └── zktreeutil            ├── data            ├── dist-maven            ├── docs            │   ├── api            │   ├── images            │   ├── jdiff            │   └── skin            ├── lib            │   ├── cobertura            │   └── jdiff            ├── recipes            │   ├── lock            │   └── queue            └── src                ├── c                ├── contrib                ├── docs                ├── java                └── recipes
客户端命令

在bin/目录下执行 ./zkCli.sh,登录客户端,输入任意字符回车,会看见命令提示,下面简单的介绍一些常用的命令:

查看节点状态,例: stat/lios/server
Java客户端

下面通过Java代码简单说明,服务端往zookeeper中添加节点信息,客户端订阅该节点,当节点发生变化时,刷新节点数据,首先添加依赖包:

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

ZookeeperServer:

/** * @author LiosWong * @description * @date 2019/4/18 下午4:39 */public class ZookeeperServer extends AbstractZoo {
    // 创建链接    @Override    protected ZooKeeper connect() {        try {            zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {                @Override                public void process(WatchedEvent event) {                    // 当连接状态时,处理逻辑.关于状态参考org.apache.zookeeper.Watcher.Event.KeeperState                    if (Event.KeeperState.SyncConnected.equals(event.getState())) {                        System.out.println("====>" + event.getPath() + ";" + event.getType());                    }                }            });        } catch (IOException e) {            e.printStackTrace();        }        return zooKeeper;    }
    // 创建节点    public ZooKeeper serverRegister(Integer type, String data) {        try {            Stat stat = connect().exists(CREATE_SERVER_NODE, true);            switch (type) {                case 1:                    // 同步创建节点                    if (Objects.isNull(stat)) {                        zooKeeper.create(CREATE_SERVER_NODE, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);//                        zooKeeper.create(CREATE_SERVER_NODE, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);  顺序节点                    }                    break;                case 2:                    // 异步创建节点                    zooKeeper.create(CREATE_SERVER_NODE, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new CallBack(), "异步创建节点");//                    zooKeeper.create(CREATE_SERVER_NODE, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL, new CallBack(), "异步创建节点");  顺序节点                    break;                default:                    break;            }        } catch (KeeperException e) {            e.printStackTrace();        } catch (InterruptedException e) {            e.printStackTrace();        }        return zooKeeper;    }

    public static void main(String[] args) throws InterruptedException {        ZookeeperServer zoo = new ZookeeperServer();        zoo.serverRegister(2, "d,");        Thread.sleep(999999);    }
    private static class CallBack implements AsyncCallback.StringCallback {
        @Override        public void processResult(int rc, String path, Object ctx, String name) {            System.out.println("rc=" + rc + ";" + "path=" + path + ";" + "ctx=" + ctx + ";" + "name=" + name);        }    }}
public abstract class AbstractZoo {    protected static final String connectString = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183";    protected static final int sessionTimeout = 10000;    protected static final String CREATE_SERVER_NODE = "/lios/server/g";    protected static final String GET_SERVER_NODE = "/lios/server";    protected static ZooKeeper zooKeeper = null;
    // 创建链接    protected abstract ZooKeeper connect();
    // 获取节点    protected void getNodeData() {
    }}

ZookeeperClient:

public class ZookeeperClient extends AbstractZoo {    @Override    protected ZooKeeper connect() {        try {            zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {                @Override                public void process(WatchedEvent event) {                    if (Event.KeeperState.SyncConnected.equals(event.getState())) {                        // 刷新节点                        getNodeData();                    }                }            });        } catch (IOException e) {            e.printStackTrace();        }        return zooKeeper;    }
    @Override    protected void getNodeData() {        try {            List<String> childList = zooKeeper.getChildren(GET_SERVER_NODE, true);            for (String addr : childList) {                byte[] data = zooKeeper.getData(GET_SERVER_NODE + "/" + addr, false, null);                System.out.println("=======>节点addr:" + addr + ";" + "data:" + new String(data));            }            System.out.println("==================>刷新完成");        } catch (KeeperException e) {            e.printStackTrace();        } catch (InterruptedException e) {            e.printStackTrace();        }    }
    public static void main(String[] args) {        AbstractZoo client = new ZookeeperClient();        client.connect();        client.getNodeData();        try {            Thread.sleep(99999999);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

发现ZookeeperServer中只要在 /lios/server下新增或删除,ZookeeperClient中都会刷新该节点下的列表,实际中可通过 ./zkCli.sh在命令下操作节点,观察ZookeeperClient下刷新状态.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端沉思录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 搭建
  • 客户端命令
  • Java客户端
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档