ZooKeeper介绍与安装配置

本文详细介绍了ZooKeeper的各个方面,包括其作为分布式协调服务的角色、节点类型、常用操作、应用场景和安装配置。此外,还讨论了ZooKeeper的Java API、ACL机制、集群搭建和一致性算法,如Paxos、Raft和ZAB。通过对ZooKeeper的学习,读者可以深入了解分布式系统中的配置管理、命名服务和分布式锁等关键概念。
摘要由CSDN通过智能技术生成

文章目录

一、概述

ZooKeeper是一个分布式应用所涉及的分布式的、开源的协调服务。

是Google的Chubby的开源实现

Zookeeper最早起源于雅虎的研究院的一个研究小组。在当时,研究人员发现,在雅虎内部很多大型的系统需要依赖一个类似的系统进行分布式协调,但是这些系统往往存在分布式单点问题。所以雅虎的开发人员就试图开发一个通用的无单点问题的分布式协调框架。在立项初期,考虑到很多项目都是用动物的名字来命名的(例如著名的Pig项目),雅虎的工程师希望给这个项目也取一个动物的名字。时任研究院的首席科学家Raghu Ramakrishnan开玩笑说:再这样下去,我们这儿就变成动物园了。此话一出,大家纷纷表示就叫动物园管理员吧——因为各个以动物命名的分布式组件放在一起,雅虎的整个分布式系统看上去就像一个大型的动物园了,而Zookeeper正好用来进行分布式环境的协调——于是,Zookeeper的名字由此诞生了。

分布式的引用可以建立在同步配置管理、选举、分布式锁、分组和命名等服务的更高级的实现的基础之上。ZooKeeper意欲设计一个易于编程的环境,它的文件系统使用我们所熟悉的目录树结构。ZooKeeper使用Java所编写,但是支持Java和C两种编程语言。

二、ZooKeeper节点

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

ZooKeeper的节点是通过像树一样的结构来进行维护,并且并且每一个节点通过路径标识以及访问。除此之外,每个节点还拥有自身的一些信息,包括:数据、数据长度、创建时间、修改时间等等。从这样一类既含有数据,又可以作为路径表示的节点特点中可以看出,ZooKeeper的节点既可以被看做是一个文件,又可以看做是一个目录,它同时具有二者的特点。
在这里插入图片描述

Znode还具有 原子性操作的特点:命名空间中。每一个Znode的数据将被原子地读写。读操作将读取与Znode相关的所有数据,写操作将替换掉所有的数据,除此之外,每一个节点都有一个访问控制列表,这个访问控制列表规定了用户操作的权限。

ZooKeeper节点是有生命周期的,这取决于节点的类型。在ZooKeeper中,节点类型可以分为持久节点(PERSISTENT)、临时节点(EPHEMERAL),以及时序节点(SEQUENTIAL),具体在节点创建过程中。一般是组合使用,可以生成以下4中节点类型。

  • 持久节点(PERSISTENT

    持久节点,是指在节点创建后,就一直存在,直到有删除操作来主动清楚这个节点——不会因为创建该节点的客户端端会话失效而消失。

  • 持久顺序节点(PERSISTENT_SEQUENTIAL

    类节点的基本特性和持久节点类型是一致的。额外的特性是,在ZK中,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。

  • 临时节点(EPHEMERAL

    与持久节点不同的是,临时节点的生命周期和客户端会话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉。

  • 临时顺序节点(EPHEMERAL_SEQUENTIAL

    类节点的基本特性和临时子节点类型是一致的。额外的 特性是,在ZK中,每个父节点会为他的第一级

三、ZooKeeper使用场景

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

在分布式应用中为了实现对分布式节点的统一配置,通常将服务中的配置文件集中存储在一个配置服务中,例如 SpringCloud将配置信息存储在Git/SVN中,Solr Cloud 则将配置数据集中存储在Zookeeper中。这典型利用了Zookeeper节点的发布订阅特性。

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

命名服务也是分布式系统中比较常见的一类场景。在分布式系统 中通过使用命名服务,客户端应用能够根据指定名字来获取资源或者服务的地址,提供者等信息。被命名的实体可以是集群中的机器,提供的服务地址,远程对象等等——这些我们都可以统称他们为名字(Name)。其中较为常见的就是一些分布式服务框架中的服务地址列表。通过调用ZK提供的创建节点的API,能够很容易常见一个全局唯一的path,这个path就就可以作为一个名称。继而实现服务弹性部署。

3.3 分布式锁(场景)

Redis分布式锁 VS Zookeeper设计分布式锁的优势

  • ZK有Watcher机制,实现简单,客户端无需重复读取数据

  • Redis锁不稳定,客户端bug或者超时会导致锁失效,zk客户端挂掉znode直接销毁(临时节点)

  • zk相对公平,顺序节点

四、ZooKeeper安装

ZooKeeper的安装模式分为三种,分别为:单机模式(stand-alone)、集群模式和集群伪分布模式。ZooKeeper单机模式的安装相对比较简单,如果第一次接触ZooKeeper建议安装ZooKeeper单机模式或者伪集群模式。

下载地址:http://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/

4.1 单机模式

zoo.cfg (存在于ZK安装目录下的conf目录下)

tickTime=2000              //session 过期时间为两倍的 tickTime
dataDir=/var/zookeeper 		//zk数据文件
clientPort=2181             //外部服务端口

4.2 启动

[root@GuoJiafeng01 zookeeper-3.4.6]# ./bin/zkServer.sh  start ./conf/zk.conf
JMX enabled by default
Using config: ./conf/zk.conf
Starting zookeeper ... STARTED

进程名称:QuorumPeerMain

五、ZK基本使用

5.1 启动

Usage: zkServer.sh {
   start|start-foreground|stop|restart|status|upgrade|print-cmd}

5.2 连接

./bin/zkCli.sh -server 192.168.15.130:2181

5.3 其他指令

connect host:port
get path [watch]
ls path [watch]
set path data [version]
rmr path
quit 
printwatches on|off
create [-s] [-e] path data acl  默认持久节点  -s 顺序节点 -e 临时节点
stat path [watch]
close 
ls2 path [watch]
history 
setAcl path acl
getAcl path
addauth scheme auth
delete path [version]

5.4 close(关闭Session)

关闭当前连接 ,在命令行头部会显示CLOSED

5.6 connect (连接ZooKeeper)

connect localhost:2181

5.7 ls / ls2 (查看子节点)

[zk: localhost:2181(CONNECTED) 19] ls /
[dubbo, hadoop-ha, zookeeper, baizhi]
--------------------------------------
[zk: localhost:2181(CONNECTED) 20] ls2 /
[dubbo, hadoop-ha, zookeeper, baizhi]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x1001
cversion = 4
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 4

5.8 create(创建节点)

[zk: localhost:2181(CONNECTED) 15] create /baizhi '1'
Created /baizhi

5.9 delete(删除节点)

[zk: localhost:2181(CONNECTED) 21] delete /baizhi
[zk: localhost:2181(CONNECTED) 22] ls /
[dubbo, hadoop-ha, zookeeper]

5.10 rmr (递归删除节点)

[zk: localhost:2181(CONNECTED) 28] ls /baizhi
[gjf]
---------------------------------
[zk: localhost:2181(CONNECTED) 44] rmr /baizhi/gjf
[zk: localhost:2181(CONNECTED) 46]  ls /baizhi
[]

5.11 quit(退出ZookeeperSHell客户端)

quit

5.12 stat(查看节点状态)

[zk: localhost:2181(CONNECTED) 51] stat /baizhi
cZxid = 0x1004
ctime = Tue Mar 12 15:28:00 CST 2019
mZxid = 0x1004
mtime = Tue Mar 12 15:28:00 CST 2019
pZxid = 0x100f
cversion = 10
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 1
numChildren = 0

六、Java API操作

6.1 原生 API

1)Maven依赖

 <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
            <type>pom</type>
        </dependency>

2)相关操作

(1)获得客户端对象
 private  ZooKeeper zooKeeper;

    @Before
    public void getCline() throws Exception{
   

         zooKeeper = new ZooKeeper("192.168.134.99:2181",2000,null);

    }
(2)获取节点值
 @Test
    public void getData()throws Exception{
   

        /*获取节点值*/
        byte[] data = zooKeeper.getData("/baizhi/123", null, null);
        System.out.println(new String(data));
    }

(3)获取节点孩子
  @Test
    public void getChild() throws Exception{
   

        /*获取当前输入节点下的子节点*/
        List<String> children = zooKeeper.getChildren("/baizhi/gjf", null);
        children.forEach((a)->{
   
            System.out.println(a);
        });

    }
(4)创建节点
    @Test
    public void createNode() throws Exception{
   


        /*创建持久节点*/

        Object value = null;

        value = "12312312";


        byte[] bytes = ((String) value).getBytes();


        String s = zooKeeper.create("/baizhi/123", bytes, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(s);




    }

(5)更新节点值
 @Test
    public void setData() throws Exception{
   

        Stat stat = zooKeeper.setData("/baizhi/123", new String("123123").getBytes(), -1);

        System.out.println(stat);


    }
(6)判断节点是否存在
 @Test
    public void exist() throws Exception{
   

        Stat stat = zooKeeper.exists("/baizhi/13", false);

        if (stat==null) {
   
            System.out.println("该节点不存在!");
        }else {
   
            System.out.println("该节点存在!");
        }

    }

6.2 zkCline API

1)Mavne依赖

<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.8</version>
</dependency>

2)核心API

 ZkClient client=new ZkClient("ip:port");                         

3)相关操作

package test;

import org.I0Itec.zkclient.ZkClient;

import java.util.List;

/**
 * Create by GuoJF on 2019/3/12
 */
public class Main {
   
    public static void main(String[] args) {
   


        ZkClient zkClient = new ZkClient("192.168.134.5:2181");


        /*
        * 获取根目录下所有的node信息
        *
        * */
        List<String> children = zkClient.getChildren("/");

        children.forEach((a)->{
   
            System.out.println(a);
        });

    }
}

(1)创建节点

    @Test
    public void createNode() {
   

        String result = zkClient.create("/baizhi/001", "001", CreateMode.PERSISTENT);

        System.out.println(result);

    }

(2)获取节点

 @Test
    public void getData() {
   
        Object readData = zkClient.readData("/baizhi/001");

        System.out.println(readData.toString());

    }

(3)更新节点值

 @Test
    public void setData() {
   
        zkClient.writeData("/baizhi/001", "123123");
    }

(4)删除节点

 @Test
    public void delNode() {
   

        boolean delete = zkClient.delete("/baizhi/001");
        if (delete) {
   
            System.out.println("删除成功!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值