Zookeeper

目录

  • Zookeeper 入门
    • 1、概述
    • 2、Zookeeper工作机制
    • 3、Zookeeper特点
    • 4、数据结构
    • 5、应用场景
      • ①统一命名服务
      • ②统一配置管理
      • ③统一集群管理
      • ④服务器动态上下线
      • ⑤软负载均衡
    • 6、下载地址
      • ①官网首页
      • ②下载截图
    • 7、Zookeeper 安装
      • ①创建工作路径/usr/zookeeper,下载相应软件,解压至工作路径。
      • ②解压zookeeper到相应路径
      • ③在zookeeper的目录中,创建配置中所需的zkdata和zkdatalog两个文件夹。(在master执行)
      • ④配置文件zoo.cfg
      • ⑤进入zkdata文件夹,创建文件myid,用于表示是几号服务器。master主机中,设置服务器id为1。(集群中设置master为1号服务器,slave1为2号服务器,slave2为3号服务器)
      • ⑥远程复制分发安装文件。
      • ⑦设置myid。在我们配置的dataDir指定的目录下面,创建一个myid文件,里面内容为一个数字,用来标识当前主机,conf/zoo.cfg文件中配置的server.X中X为什么数字,则myid文件中就输入这个数字。(在slave1和slave2中执行)
      • ⑧修改/etc/profile文件,配置zookeeper环境变量。(三台机器都执行)
      • ⑨生效环境变量
      • ⑩启动ZooKeeper集群。在ZooKeeper集群的每个结点上,执行启动ZooKeeper服务的脚本。注意在zookeeper目录下:(三台机器都执行)
    • 8、配置参数解读
      • ①tickTime = 2000
      • ②initLimit= 10
      • ③syncLimit=5
      • ④dataDir
      • ⑤clientPort= 2181
    • 9、Zookeeper选举机制(第一次启动)
  • 客户端命令行操作
    • ①启动客户端
    • ②命令行语法
    • ③查看当前znode中所包含的内容
    • ④查看当前节点详细数据
    • ⑤节点类型
      • 1、分别创建2个普通节点(永久节点+不带序号)
      • 2、创建普通节点带序号(关闭客户端,数据不会删除)
      • 3、创建临时节点(关闭客户端,数据删除)
      • 4、创建临时节点带序号
      • 5、修改节点数据值
    • ⑥监听器原理
      • 1、监听原理详解
      • 2、常见的监听
      • 3、实操
        • (1)节点数据监听
        • (2)节点的子节点数量监听
    • ⑦节点删除与查看
      • 删除节点
      • 递归删除节点
      • 查看节点状态
  • 客户端API操作
    • 1、API 环境搭建
      • ①打开IDEA,创建Maven工程
      • ②添加pom文件
      • ③拷贝log4j.properties文件到项目根目录
      • ④创建包名com.atguigu.zk
      • ⑤创建类名称zkClient
    • 2、创建Zookeeper客户端
    • 3、创建子节点
    • 4、获取子节点并监听节点变化
    • 5、判断Znode是否存在
    • 6、客户端向服务端写数据流程
      • ①分析需求
      • ②具体实现

Zookeeper 入门

1、概述

Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。

2、Zookeeper工作机制

Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper.上注册的那些观察者做出相应的反应。

3、Zookeeper特点

  1. Zookeeper: 一个领导者(Leader) ,多个跟随者(Follower) 组成的集群。
  2. 集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。所以Zookeeper适合安装奇数台服务器。
  3. 全局数据一致:每个Server保存 一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
  4. 更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行。
  5. 数据更新原子性,一次数据更新要么成功,要么失败。
  6. 实时性,在一定时间范围内,Client能读到最新数据。

4、数据结构

ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode。每一个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。
Zookeeper_第1张图片

5、应用场景

提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。

①统一命名服务

在分布式环境下,经常需要对应用/服务进行统一命名, 便于识别。例如: IP不容易记住,而域名容易记住。
Zookeeper_第2张图片

②统一配置管理

1、分布式环境下,配置文件同步非常常见。
(1)一般要求一个集群中,所有节点的配置信息是一致的,比如Kafka集群。
(2)对配置文件修改后,希望能够快速同步到各个节点上。
2、配置管理可交由ZooKeeper实现。
(1)可将配置信息写入ZooKeeper 上的一个Znode。
(2)各个客户端服务器监听这个Znode。
(3) 一旦Znode中的数据被修改,ZooKeeper将通知各个客户端服务器。
Zookeeper_第3张图片

③统一集群管理

1、分布式环境中,实时掌握每个节点的状态是必要的。
(1)可根据节点实时状态做出一-些调整。

2、ZooK eeper可以实现实时监控节点状态变化
(1) 可将节点信息写入ZooKeeper.上的一 个ZNode。
(2)监听这个ZNode可获取它的实时状态变化。
Zookeeper_第4张图片

④服务器动态上下线

客户端能实时洞察到服务器上下线的变化
Zookeeper_第5张图片

⑤软负载均衡

在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求。
Zookeeper_第6张图片

6、下载地址

①官网首页

https://zookeeper.apache.org/

②下载截图

Zookeeper_第7张图片

7、Zookeeper 安装

①创建工作路径/usr/zookeeper,下载相应软件,解压至工作路径。

mkdir -p /usr/zookeeper
cd /usr/zookeeper

②解压zookeeper到相应路径

tar -zxvf /usr/zookeeper/zookeeper-3.4.10.tar.gz -C /usr/zookeeper

③在zookeeper的目录中,创建配置中所需的zkdata和zkdatalog两个文件夹。(在master执行)

cd /usr/zookeeper/zookeeper-3.4.10
mkdir zkdata
mkdir zkdatalog

④配置文件zoo.cfg

进入zookeeper配置文件夹conf,将zoo_sample.cfg文件拷贝一份命名为zoo.cfg,Zookeeper 在启动时会找这个文件作为默认配置文件。

cd /usr/zookeeper/zookeeper-3.4.10/conf/
mv zoo_sample.cfg zoo.cfg
vim zoo.cfg

#对zoo.cfg文件配置如下:(在master执行)

tickTime=2000    
initLimit=10
syncLimit=5
dataDir=/usr/zookeeper/zookeeper-3.4.10/zkdata
clientPort=2181
dataLogDir=/usr/zookeeper/zookeeper-3.4.10/zkdatalog
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888

Zookeeper_第8张图片

⑤进入zkdata文件夹,创建文件myid,用于表示是几号服务器。master主机中,设置服务器id为1。(集群中设置master为1号服务器,slave1为2号服务器,slave2为3号服务器)

cd /usr/zookeeper/zookeeper-3.4.10/zkdata
vim myid

Zookeeper_第9张图片

⑥远程复制分发安装文件。

以上已经在主节点master上配置完成ZooKeeper,现在可以将该配置好的安装文件远程拷贝到集群中的各个结点对应的目录下:(在master执行)

scp -r /usr/zookeeper root@slave1:/usr/
scp -r /usr/zookeeper root@slave2:/usr/

⑦设置myid。在我们配置的dataDir指定的目录下面,创建一个myid文件,里面内容为一个数字,用来标识当前主机,conf/zoo.cfg文件中配置的server.X中X为什么数字,则myid文件中就输入这个数字。(在slave1和slave2中执行)

cd /usr/zookeeper/zookeeper-3.4.10/zkdata
vim myid

实验中设置slave1中为2:
Zookeeper_第10张图片
slave2中为3:
Zookeeper_第11张图片

⑧修改/etc/profile文件,配置zookeeper环境变量。(三台机器都执行)

vi /etc/profile

#set zookeeper environment    
export ZOOKEEPER_HOME=/usr/zookeeper/zookeeper-3.4.10 
PATH=$PATH:$ZOOKEEPER_HOME/bin 

Zookeeper_第12张图片

⑨生效环境变量

source /etc/profile

⑩启动ZooKeeper集群。在ZooKeeper集群的每个结点上,执行启动ZooKeeper服务的脚本。注意在zookeeper目录下:(三台机器都执行)

开启服务:bin/zkServer.sh start
查看状态:bin/zkServer.sh status

Zookeeper_第13张图片
通过上面状态查询结果可见,一个节点是Leader,其余的结点是Follower。至此,zookeeper安装成功。

8、配置参数解读

Zookeeper中的配置文件zoo.cfg中参数含义解读如下:

①tickTime = 2000

通信心跳时间,Zookeeper服务 器与客户端心跳时间,单位毫秒
Zookeeper_第14张图片

②initLimit= 10

LF初始通信时限
Leader和Follower初始连接时能容忍的最多心跳数(tickTime的数量)
Zookeeper_第15张图片

③syncLimit=5

LF同步通信时限
Leader和Follower之间通信时间如果超过syncLimit * tick Time,Leader认为Follwer死掉,从服务器列表中删除Follwer。

④dataDir

保存Zookeeper中 的数据
注意:默认的tmp目录,容易被Linux系统定期删除,所以一般不用默认的tmp目录。

⑤clientPort= 2181

客户端连接端口,通常不做修改。

9、Zookeeper选举机制(第一次启动)

Zookeeper_第16张图片

客户端命令行操作

①启动客户端

[root@master bin]# sh zkCli.sh -server master:2181

②命令行语法

命令基本语法 功能描述
help 显示所有操作命令
ls path 使用 ls 命令来查看znode的子节点【可监听】 -w 监听子节点变化 -s 附加次级信息
create 普通创建子节点 -s 含有序列 -e 临时(重启或者超时小时)
get path 获得节点的值【可监听】-w 监听节点内容变化 -e附加次级信息
set 设置节点的具体值
stat 查看节点信息
delete 删除节点
deleteall 递归删除节点

③查看当前znode中所包含的内容

ls /

④查看当前节点详细数据

ls -s /

Zookeeper_第17张图片

(1) czxid: 创建节点的事务zxid

每次修改ZooKeeper状态都会产生一个ZooKeeper事务ID。事务ID是ZooKeeper中所有修改总的次序。每次修改都有唯一的zxid,如果zxid小于zxid2,那么zxid在zxid2之前发生。
(2) ctime
znode 被创建的毫秒数(从1970年开始)
(3) mzxid
znode最后更新的事务zxid
(4) mtime
znode 最后修改的毫秒数(从1970年开始)
(5) pZxid
znode最后更新的子节点zxid
(6)cversion
znode 子节点变化号,znode, 子节点修改次数
(7) dataversion
znode 数据变化号
(8) aclVersion
znode 访问控制列表的变化号
(9) ephemeralOwner
如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0。
(10) dataI ength
znode的数据长度
(11)numChildren
znode 子节点数量

⑤节点类型

持久(Persistent):客户端和服务器端断开连接后,创建的节点不删除
短暂(Ephemeral):客户端和服务器端断开连接后,创建的节点自己删除
Zookeeper_第18张图片

1、分别创建2个普通节点(永久节点+不带序号)

[zk: master:2181(CONNECTED) 15] create /sanguo "yu zai"

 create /sanguo/shuguo "dian dian" 

获取节点中内容的值

get /sanguo
get /sanguo/shuguo

2、创建普通节点带序号(关闭客户端,数据不会删除)

create -s /sanguo/weiguo/ "zhang liao"

在这里插入图片描述
退出客户端

quit

连接客户端

 sh zkCli.sh -server master:2181

查看节点数据

ls /sanguo/weiguo 

数据并未删除

3、创建临时节点(关闭客户端,数据删除)

create -e /sanguo/wuguo "zouiyu"

4、创建临时节点带序号

 create -e -s /sanguo/wuguo "zouiyu3"

在这里插入图片描述

退出客户端

quit

连接客户端

 sh zkCli.sh -server master:2181

查看临时节点数据

ls /sanguo

在这里插入图片描述

数据消失。

5、修改节点数据值

set /sanguo/weiguo "simayi"

原节点内容
Zookeeper_第19张图片
修改后
Zookeeper_第20张图片

⑥监听器原理

客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目录节点增加删除)时,ZooKeeper. 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序。

1、监听原理详解

(1)首先要有一个main()线程
(2)在main线程中创建Zookeeper客户端 ,这时就会创建两个线程,一个负责网络连接通信(connet) ,-个负责监听(listener) 。
(3)通过connect线程将注册的监听事件发送给Zookeeper。
(4)在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。
(5)Zookeeper监 听到有数据或路径变化,就会将这个消息发送给listener线程。
(6)listener线程内部调用了process()方法。

2、常见的监听

(1)监听节点数据的变化
get path [watch]
(2)监听子节点增减的变化
ls path [watch]

Zookeeper_第21张图片

3、实操

(1)节点数据监听

① 启动三个节点的客户端

 sh zkCli.sh -server master:2181

 sh zkCli.sh -server slave1:2181

 sh zkCli.sh -server slave2:2181

②在slave2节点上监控sanguo的数据值

查看数据值

 get /sanguo

Zookeeper_第22张图片

监控三国

 get /sanguo -w

③在slave1节点上修改sanguo的数据
修改数据

 set /sanguo "xisi"

slave2节点会监测的数据异常
在这里插入图片描述
④再次在slave1节点上修改sanguo的数据
修改数据

set /sanguo "yangfeiyan"

此时数据已经改变,但slave2的不会监测提醒
Zookeeper_第23张图片
注意:在slave1再多次修改/sanguo的值,slave2上不会再收到监听。因为注册一次,只能监听一次。想再次监听,需要再次注册。

(2)节点的子节点数量监听

在slave2注册监听

 ls /sanguo -w

在这里插入图片描述
在slave1上的sanguo创建子节点

create /sanguo/jinguo "simayi"

在这里插入图片描述
slave2监听到异常
在这里插入图片描述
注意:节点的路径变化,也是注册一次,生效一次。想多次生效,就需要多次注册。

⑦节点删除与查看

删除节点

(适用于删除子节点)

delete /sanguo/jinguo

递归删除节点

(其节点与子节点都会删除)

deleteall /sanguo/shuguo

查看节点状态

stat /sanguo

客户端API操作

1、API 环境搭建

前提:保证hadoop102、hadoop103、 hadoop104 服务器上Zookeeper集群服务端启动。

①打开IDEA,创建Maven工程

Zookeeper_第24张图片
Zookeeper_第25张图片

②添加pom文件

<dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>RELEASE</version>
  </dependency>
 <dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.8.2</version>
 </dependency>
 <dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.5.7</version>
 </dependency>
</dependencies>

Zookeeper_第26张图片

③拷贝log4j.properties文件到项目根目录

需要在项目的src/main/resources目录下,新建一个文件,命名为“log4j.properties”,在文件中填入。
Zookeeper_第27张图片

log4j.rootLogger=INFO,stdout
1og4j.appender.stdout=org.apache.log4j.ConsoleAppender
1og4i.appender.stdout.layout=org.apache.1og4j.PatternLayout
loq4j.appender.stdout.layout.ConversionPattern=%d%p[%c]-%m%n
1og4i.appender.logfile=org.apache.1og4j.FileAppender
log4j.appender.logfile.File=target/spring.log
1og4i.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d%p[%c]-%m%n

Zookeeper_第28张图片

④创建包名com.atguigu.zk

Zookeeper_第29张图片

⑤创建类名称zkClient

Zookeeper_第30张图片

2、创建Zookeeper客户端

package yuzai.zk;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Test;

import javax.imageio.IIOException;
import java.io.IOException;

public class zkClient {
    //:"master:2181,slave1:2181,slave2:2181"的逗号左右不能有空格。
    private String connectString = "master:2181,slave1:2181,slave2:2181";
    private int sessionTimeout = 2000 ;

    @Test
    public void init() throws IOException {

         ZooKeeper zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {

            }
        });
    }
}

3、创建子节点

package yuzai.zk;

import org.apache.zookeeper.*;
import org.junit.Before;
import org.junit.Test;

import javax.imageio.IIOException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class zkClient {
    //:"master:2181,slave1:2181,slave2:2181"的逗号左右不能有空格。
    private String connectString = "192.168.187.198:2181,192.168.187.197:2181,192.168.187.196:2181";
    private int sessionTimeout = 2000 ;
    private static ZooKeeper zkClient ;

    @Before
    public void init() throws IOException {

         zkClient  = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {

            }
        });
    }

    @Test
    public void creata() {
        try {
            String nodeCreated = zkClient.create("/adian", "xiaozahng".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

4、获取子节点并监听节点变化

Zookeeper_第31张图片

5、判断Znode是否存在

Zookeeper_第32张图片

6、客户端向服务端写数据流程

①分析需求

Zookeeper_第33张图片

②具体实现

(1)先在集群上创建/servers节点

[zk: localhost:2181 (CONNECTED) 10]create /servers "servers " 

(2)在Idea中创建包名: com.atguigu.zkcase1

(3)服务器端向Zookeeper注册代码

package yuzai.zk1;

import org.apache.zookeeper.*;

import java.io.IOException;

public class DistributeServer {

    private String connectString = "192.168.187.198:2181,192.168.187.197:2181,192.168.187.196:2181";
    private int sessionTimeout = 2000 ;


    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        DistributeServer server = new DistributeServer();
        //1.获取zk连接
        server.getConnect();
        //2.注册服务器到zk集群
        server.regist(args[0]);

        //3.启动业务逻辑(睡觉觉)
        server.business();
    }

    private void business() throws InterruptedException {
        Thread.sleep(Long.MAX_VALUE);
    }

    private void regist(String hostname) throws InterruptedException, KeeperException {
        String create = zk.create("/servers", hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

        System.out.println(hostname+"is online");
    }

    ZooKeeper zk;

    // 获取zk连接.方法
    private void getConnect() throws IOException {

         zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {

            }
        });
    }
}

你可能感兴趣的:(大数据生态圈,java-zookeeper,zookeeper,服务器)