ZooKeeper-base

一、概述

Apache ZooKeeper致力于开发和维护可实现高度可靠的分布式协调的开源服务器。

ZooKeeper是用于维护配置信息,命名,提供分布式同步和提供组服务的集中式服务。 所有这些类型的服务都以某种形式或由分布式应用程序使用。 每次实施它们时,都会进行很多工作来修复不可避免的错误和竞争条件。 由于难以实现这类服务,因此应用程序通常最初会在其上跳过,从而使它们在存在更改的情况下变得脆弱并且难以管理。 即使部署正确,这些服务的不同实现也会导致管理复杂。

是Google的Chuby的开源实现

雅虎的研究小组,开发出了一个类似与分布式协调系统的软件,由于当时的生态中普遍都是一动物进行命名,所以起名动物园管理员——Zookeeper

二、Zookeeper节点

Zookeeper提供的命名空间与标准的文件系统非常相似;一个名称是由斜线分割开来的路径名所组成的,Zookeeper中每一个节点都是通过路径来识别的。

Zookeeper通过向树一样的结构来维护的,每一个节点通过路径进行标示和访问;除此之外,路径自身会存储一些信息,包括:数据,长度,创建时间,修改时间,这样的一类即含有数据,又可以作为路径表示的节点中可以看出是文件也是路径;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DX3NH5Aj-1573987283260)(assets/1569293719656.png)]

在这里把Zookeeper的节点称之为Znode

Znode具有原子性操作的特点:在命名空间中,每一个Znode的数据将会别原子的读写,读操作是读取所有的数据,写操作是覆盖掉所有的数据,另外这里还存在ACL(权限控制)的特性,每一个Znode都有一个ACL,这些权限信息控制着Znode的访问权限。

Zookeeper的节点具有生命周期,这取决于节点的类型;主要分别两大类:临时节点(EPHEMERAL)|持久节点(PERSISTENT)

另外还有 顺序节点(SEQUENTIAL)

  • 持久节点

持久节点,是指节点创建后,就一直存储,直到删除操作将其删除,而不会因为客户端的会话消失而消失

  • 持久顺序节点

    与持久节点特性保持一致,在次基础上,每个父节点会为它的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。

  • 临时节点

    与持久节点不同的是,当前会话消失临时节点也会消失

  • 临时顺序节点b

    与临时节点特性保持一致,在次基础上,每个父节点会为它的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。

三、Zookeeper使用场景

3.1 配置中心(数据发布与订阅)

在分布式的应用实现对分布式节点的统一配置,通常将服务中的配置文件集中存储在配置服务。

3.2 命名服务|服务分组(Naming Service)

在分布式文件中使用命名服务,客户端能够根据名字来获取资源和服务的地址。

3.3 分布式锁(场景)

Redis 和ZK

  • zk 相对公平,有顺序节点
  • zk watcher 机制 客户端无需重复读取数据
  • Redis不稳定,客户端bug或者网络超时,导致锁表示永远无法释放,znode 客户端挂掉(会话消失)临时节点消失

四、ZK安装

zk的安装模式,单机、集群、伪集群

4.1 单机模式

需要有Java 运行环境

[root@HadoopNode00 ~]# mkdir /home/zk
[root@HadoopNode00 ~]# tar -zxvf zookeeper-3.4.6.tar.gz  -C /home/zk/
[root@HadoopNode00 ~]# cp /home/zk/zookeeper-3.4.6/conf/zoo_sample.cfg /home/zk/zookeeper-3.4.6/conf/zk.conf
[root@HadoopNode00 ~]# mkdir /home/zk/data  # 创建zk存储文件夹

zk.conf

tickTime=2000     # session 过期时间
initLimit=10
syncLimit=5
dataDir=/home/zk/data  # zk 数据文件
clientPort=2181  # 外部服务 端口号

4.2 启动

[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh  start ./conf/zk.conf
JMX enabled by default
Using config: ./conf/zk.conf
Starting zookeeper ... STARTED
[root@HadoopNode00 zookeeper-3.4.6]# jps
2501 ResourceManager
2598 NodeManager
53142 Jps
16871 SecondaryNameNode
16712 DataNode
16587 NameNode
53117 QuorumPeerMain
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh  status ./conf/zk.conf
JMX enabled by。、 default
Using config: ./conf/zk.conf
Mode: standalone

五、Zk基本使用

5.1 连接

[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkCli.sh   # m默认连接本地的2182端口
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkCli.sh -server hadoopnode00:2181

5.2 指令

ZooKeeper -server host:port cmd args
        stat path [watch]
        set path data [version]
        ls path [watch]
        delquota [-n|-b] path
        ls2 path [watch]
        setAcl path acl
        setquota -n|-b val path
        history
        redo cmdno
        printwatches on|off
        delete path [version]
        sync path
        listquota path
        rmr path
        get path [watch]
        create [-s] [-e] path data acl
        addauth scheme auth
        quit
        getAcl path
        close
        connect host:port

close 关闭Session

[zk: hadoopnode00:2181(CONNECTED) 1] close
2019-09-22 03:58:59,198 [myid:] - INFO  [main:ZooKeeper@684] - Session: 0x16d55606c160008 closed
[zk: hadoopnode00:2181(CLOSED) 2] 2019-09-22 03:58:59,208 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@512] - EventThread shut down

ls/ls2 查看节点

[zk: hadoopnode00:2181(CONNECTED) 6] ls /
[zookeeper]
[zk: hadoopnode00:2181(CONNECTED) 7] ls /
[zookeeper]
[zk: hadoopnode00:2181(CONNECTED) 8] ls /zookeeper
[quota]
[zk: hadoopnode00:2181(CONNECTED) 9] ls /zookeeper/quota

[zk: hadoopnode00:2181(CONNECTED) 10] ls2 /
[zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1

create 创建节点

[zk: hadoopnode00:2181(CONNECTED) 14] create /baizhi "baizhijiaoyu"
Created /baizhi
[zk: hadoopnode00:2181(CONNECTED) 15] ls /
[baizhi, zookeeper]
[zk: hadoopnode00:2181(CONNECTED) 16] ls2 /baizhi
[]
cZxid = 0x14
ctime = Sun Sep 22 04:01:35 CST 2019
mZxid = 0x14
mtime = Sun Sep 22 04:01:35 CST 2019
pZxid = 0x14
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 14
numChildren = 0

delete 删除节点

[zk: hadoopnode00:2181(CONNECTED) 19] delete /baizhi
[zk: hadoopnode00:2181(CONNECTED) 20] ls /
[zookeeper]

get 获取数据

[zk: hadoopnode00:2181(CONNECTED) 18] get /baizhi
"baizhijiaoyu"
cZxid = 0x14
ctime = Sun Sep 22 04:01:35 CST 2019
mZxid = 0x14
mtime = Sun Sep 22 04:01:35 CST 2019
pZxid = 0x14
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 14
numChildren = 0

rmr 递归删除

[zk: localhost:2181(CONNECTED) 10] delete  /baizhi
Node not empty: /baizhi
[zk: localhost:2181(CONNECTED) 11] rmr /baizhi
[zk: localhost:2181(CONNECTED) 12] ls /
[zookeeper]

六 、Java API

6.1 依赖

 <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.7.1</version>
        </dependency>

6.2 相关操作

(1)获取客户端对象

private CuratorFramework client;

    @Before
    public void getClient() {


        ExponentialBackoffRetry retry = new ExponentialBackoffRetry(1000, 1000);

        client = CuratorFrameworkFactory.newClient("hadoopnode00:2181", retry);


        client.start();
    }

(2)创建节点

 @Test
    public void createNode() throws Exception{
        String s = client.create().withMode(CreateMode.PERSISTENT).forPath("/baizhi", "1123".getBytes());
        System.out.println(s);

    }

(3)获取节点

 @Test
    public void getNode() throws Exception {

        byte[] bytes = client.getData().forPath("/baizhi");


        System.out.println(new String(bytes));

    }

(4)更新节点值

@Test
    public void setNode() throws Exception{
        client.setData().forPath("/baizhi", "456".getBytes());

    }

(5)获取孩子节点

 @Test
    public void getChild() throws Exception {

        client.getChildren().forPath("/baizhi").forEach((name) -> {
            System.out.println(name);
        });

    }

(6)删除节点


    @Test
    public void delNode() throws Exception{

        client.delete().deletingChildrenIfNeeded().forPath("/baizhi");

    }

6.3 Watcher接口

   <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.7.1</version>
        </dependency>

(1)监听节点的变化 NodeChange


    @Test
    public void testNodeChange() throws Exception {

        ExecutorService pool = Executors.newFixedThreadPool(2);

        NodeCache nodeCache = new NodeCache(client, "/baizhi", false);

        nodeCache.start();


        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {


                System.out.println(new String(nodeCache.getCurrentData().getData()));

            }
        }, pool);

        Thread.sleep(Long.MAX_VALUE);
    }

(2 )监听子节点的变化

@Test
    public void testChildChange() throws Exception {


        PathChildrenCache childrenCache = new PathChildrenCache(client, "/baizhi", true);

        childrenCache.start();


        childrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {

                switch (event.getType()) {

                    case CHILD_ADDED:
                        System.out.println("节点被增加" + event.getData().getPath() + "  它的值是" + new String(event.getData().getData()));
                        break;
                    case CHILD_REMOVED:
                        System.out.println("节点被删除" + event.getData().getPath());
                        break;
                    case CHILD_UPDATED:
                        System.out.println("节点被更新" + event.getData().getPath() + "  它的值是" + new String(event.getData().getData()));
                        break;

                }

            }
        });

        Thread.sleep(Integer.MAX_VALUE);

    }

七、ZK 集群

7.1 基础 环境

删除mac地址

更改IP

更加主机名

更加HOSTS

在各个节点中必须安装Java 和 ZK

7.2 集群配置

(1)添加启动配置文件

tickTime=2000     # session 过期时间
initLimit=10
syncLimit=5
dataDir=/home/zk/data  # zk 数据文件
clientPort=2181  # 外部服务 端口号
server.1=zk01:2887:3887
server.2=zk02:2887:3887
server.3=zk03:2887:3887

server.id = host:port:port

指出了不同的zk的服务器不同的标示,作为集群中的一部分需要识别自己是哪部分,别人的节点信息又是什么。

在data目录中需要新建一个叫做myid文件,在这个文件中值需要给出id的数字即可(1,2,3)

第一个port是保持和主机通信,第二个是做选举用的。

(2)新建myid文件

将myid文件放在data目录中
1
2
3

(3)启动

./bin/zkServer.sh  start ./conf/zk.conf

7.3 伪集群

[root@HadoopNode00 ~]# mkdir /home/zk/data01
[root@HadoopNode00 ~]# mkdir /home/zk/data02
[root@HadoopNode00 ~]# mkdir /home/zk/data03

[root@HadoopNode00 ~]# echo "1" >>  /home/zk/data01/myid
[root@HadoopNode00 ~]# echo "2" >>  /home/zk/data02/myid
[root@HadoopNode00 ~]# echo "3" >>  /home/zk/data03/myid

[root@HadoopNode00 ~]# vi /home/zk/zookeeper-3.4.6/conf/zk01.conf
tickTime=2000    
initLimit=10
syncLimit=5
dataDir=/home/zk/data01  
clientPort=2181 
server.1=hadoopnode00:2887:3887
server.2=hadoopnode00:2888:3888
server.3=hadoopnode00:2889:3889
[root@HadoopNode00 ~]# vi /home/zk/zookeeper-3.4.6/conf/zk02.conf
tickTime=2000    
initLimit=10
syncLimit=5
dataDir=/home/zk/data02
clientPort=2182  
server.1=hadoopnode00:2887:3887
server.2=hadoopnode00:2888:3888
server.3=hadoopnode00:2889:3889
[root@HadoopNode00 ~]# vi /home/zk/zookeeper-3.4.6/conf/zk03.conf
tickTime=2000    
initLimit=10
syncLimit=5
dataDir=/home/zk/data03 
clientPort=2183  
server.1=hadoopnode00:2887:3887
server.2=hadoopnode00:2888:3888
server.3=hadoopnode00:2889:3889

[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh start ./conf/zk01.conf
JMX enabled by default
Using config: ./conf/zk01.conf
Starting zookeeper ... STARTED
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh start ./conf/zk02.conf
JMX enabled by default
Using config: ./conf/zk02.conf
Starting zookeeper ... STARTED
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh start ./conf/zk03.conf
JMX enabled by default
Using config: ./conf/zk03.conf
Starting zookeeper ... STARTED
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh status ./conf/zk03.conf
JMX enabled by default
Using config: ./conf/zk03.conf
Mode: follower
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh status ./conf/zk02.conf
JMX enabled by default
Using config: ./conf/zk02.conf
Mode: leader
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh status ./conf/zk01.conf
JMX enabled by default
Using config: ./conf/zk01.conf
Mode: follower

fault
Using config: ./conf/zk03.conf
Starting zookeeper … STARTED
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh status ./conf/zk03.conf
JMX enabled by default
Using config: ./conf/zk03.conf
Mode: follower
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh status ./conf/zk02.conf
JMX enabled by default
Using config: ./conf/zk02.conf
Mode: leader
[root@HadoopNode00 zookeeper-3.4.6]# ./bin/zkServer.sh status ./conf/zk01.conf
JMX enabled by default
Using config: ./conf/zk01.conf
Mode: follower


















































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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值