学习目标:

随堂视频 ;

最新zookeeper快速入门教程_哔哩哔哩_bilibili

  1. 什么是zookeeper
  2. 应用场景
  3. 基本的操作
    1. 安装部署
    2. shell客户端
    3. java端
  4. 基本原理
    1. 选举机制
    2. 数据一致性
    3. 数据的读写流程

1 zookeeper简介

zookeeper是一个底层的集群协调工具,(比如:NN和DN之间的状态感应;监控 通知)!

具备基本的功能有 ,记录用户的状态数据 (写), 返回用户的数据(读) ,监控和通知。zookeeper为了高可用和安全性是一个集群! 3台(每个节点的数据完全一致)!

2 应用场景

  • 写数据
  • 读取数据
  • 监控通知

2.1 服务状态感知

2.2 分布式锁

2.3 分布式配置同步

2.4 统一域名

分布式中统一CMD指令

分布式中服务器的状态感知

3 操作

3.1 安装

zookeeper在部署的时候选择奇数台!要求zk集群半数以上的机器在线才能正常工作!

上传解压 

配置

  1. 在zk安装目录下  创建文件夹 zkData  mkdir  zkData   /opt/apps/zookeeper-3.4.6/zkData
  2. 修改conf/下的配置模板配置文件名   mv zoo_sample.cfg zoo.cfg
  3. vi zoo.cfg   
    dataDir=/opt/apps/zookeeper-3.4.6/zkData# Set to "0" to disable auto purge feature
    #autopurge.purgeInterval=1
    server.1=linux01:2888:3888
    server.2=linux02:2888:3888
    server.3=linux03:2888:3888
  4. 在zkData文件夹下创建myid文件        echo 1 >  zkData/myid

同步安装包 

scp -r  zookeeper-3.4.6/  linux02:$PWD
scp -r  zookeeper-3.4.6/  linux03:$PWD

修改各个节点myid的值    linux02【2】  linux03【3】

启动集群 

在各个节点上启动ZK服务

/opt/apps/zookeeper-3.4.6/bin/zkServer.sh  start

查看进程  jps

[root@linux01 bin]# jps
1697 QuorumPeerMain
1720 Jps

查看集群状态  在每个节点执行

/opt/apps/zookeeper-3.4.6/bin/zkServer.sh  status-------------------------------------------------------
Mode: followerMode: leaderMode: follower

3.2 编写一键启动脚本

#!/bin/bash
# zk启停脚本
for hostname in linux01  linux02  linux03
do
echo "连接${hostname}... ...正在执行 $1"
ssh ${hostname} "source  /etc/profile ;/opt/apps/zookeeper-3.4.6/bin/zkServer.sh  $1 ;exit"
done 

3.3 shell操作

zookeeper中记录数据以Tree节点的形式存储数据的/类似于目录树!

目录叫znode  : 节点的组织数据是  K  V

基本操作指令

# 客户端连接
bin/zkCli.sh 连接到本地zk服务
bin/zkCli.sh -server  linux02:2181  连接到执行节点的服务
quit  退出客户端      ctrl+c
-------------------------------------------
help 帮助命令  查看系统支持的所有的命令
ZooKeeper -server host:port cmd argsstat path [watch]set path data [version]ls path [watch] * delquota [-n|-b] pathls2 path [watch]  * setAcl path aclsetquota -n|-b val pathhistory redo cmdnoprintwatches on|offdelete path [version]  * sync pathlistquota pathrmr path  * get path [watch]create [-s] [-e] path data acl  * addauth scheme authquit   * getAcl pathclose   * connect host:port-------------------------------------------------------------------
创建节点  节点必须以/开头  (路径必须是绝对路径)
--   create [-s] [-e] path data acl
create  /a  1
create  /b  2
create  /a/a1 11
create  /a/a2 22
create  /a/a3 33
[-s] 在节点后面添加一个自增的id  防止节点名重复而创建失败
[-e]  创建的节点是临时节点  , 只在当前连接中有效
------节点分类-----
--临时节点临时有序   -e临时无序   -e  -s
--永久节点永久有序    -s永久无序   默认
注意: 节点的创建不能层级创建
查看节点列表
ls    /a
ls2   /a  显示数据版本 , 事务id 创建时间等信息修改数据
set  /a  123
获取数据
get  /a
删除节点
delete   /a  只能删除空节点
rmr      /a  可以删除任意节点 

监听和通知

事件 : 触发了某种事件  通知

  • 节点数据的变化
  • 子节点个数的变化
  1. ls path [watch]     监控指定路径下数据的变化
  2. get  path [watch] 监控指定路径数据的变化

注意: 监控和通知只能1次

打开两个zk客户端
1) 一个监控   2) 一个修改数据 #  子节点个数变化
窗口01  :  ls  /   watch  ->(WatchedEvent state:SyncConnected type:NodeChildrenChangedpath:/)
窗口02  :  rmr  /a000000004
---------------------------------------------------------------------------
#  节点数据变化
窗口01  :   get  /b   watch  ->(WatchedEvent state:SyncConnected type:NodeDataChanged path:/b)
窗口02  :  set /b   321

3.4 java操作

  • 添加依赖
  • 获取zk客户端
  • 调用API
  • 释放资源

添加依赖

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

入门示例-[获取连接\创建节点]

package com.doitedu.zk.cli;import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import java.io.IOException;
/*** @Date 2022/2/23* @Created by HANGGE* @Description TODO*/
public class Demo01 {public static void main(String[] args) throws Exception {// 获取zk的客户端/*** 参数一 zk的地址  host:port,host2:port* 参数二 连接的超时时间  毫秒* 参数三 连接成功后的监听*/ZooKeeper zk = new ZooKeeper("linux01:2181,linux02:2181,linux03:2181", 3000, null);// 调用API//1  创建节点/*** 参数1   路径* 参数2   数据 值 字节数组* 参数3   权限* 参数4   节点类型  1 2 3 4*/zk.create("/doitedu" , "JINGYINGDOIT30_".getBytes() , ZooDefs.Ids.OPEN_ACL_UNSAFE , CreateMode.EPHEMERAL_SEQUENTIAL);//  System.out.println(zk);//释放资源Thread.sleep(8000);zk.close();}
}

zookeeper-Java-API使用

package com.doitedu.zk.cli;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import java.util.List;/*** @Date 2022/2/23* @Created by HANGGE* @Description* 创建节点* 删除节点* 获取值* 修改值* 遍历子节点列表*   判断节点是否存在*/
public class ClientApiDemo {public static void main(String[] args) throws Exception {// 获取客户端对象ZooKeeper zk = ZookeeperUtil.getZookeeper();// testGetData(zk);//修改数据//testSetData(zk);//获取子节点列表//testls(zk);// 只能删除空节点   递归// zk.delete("/b" , -1);// 递归删除节点ZookeeperUtil.rmr(zk,"/b") ;zk.close();}// 查看路径下的子节点列表public static void testls(ZooKeeper zk) throws KeeperException, InterruptedException {List<String> ls = zk.getChildren("/", null);if(ls!=null && ls.size()>0){for (String name : ls) {System.out.println("节点的名字是:" + name);byte[] data = zk.getData("/" + name, null, null);System.out.println(new String(data));}}}// 更新数据public static void testSetData(ZooKeeper zk) throws KeeperException, InterruptedException {Stat stat = zk.setData("/b", "liulan".getBytes(), -1);// 如果更新成功Stat 不为nullif(stat != null){testGetData(zk);}}// 获取数据public static void testGetData(ZooKeeper zk) throws KeeperException, InterruptedException {byte[] data = zk.getData("/b", null, null);String str = new String(data);System.out.println(str);}
}

封装工具类

package com.doitedu.zk.cli;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import java.io.IOException;
import java.util.List;
/*** @Date 2022/2/23* @Created by HANGGE* @Description TODO*/
public class ZookeeperUtil {/*** 获取指定zk集群的客户端对象*   linux01  02  03* @return* @throws IOException*/public  static ZooKeeper  getZookeeper() throws IOException {return  new ZooKeeper("linux01:2181,linux02:2181,linux03:2181", 3000, null);}/*** 删除任意节点* @param zk* @param path* @throws KeeperException* @throws InterruptedException*/public static void  rmr(ZooKeeper zk , String path) throws KeeperException, InterruptedException {// 遍历是否有子节点List<String> ls = zk.getChildren(path, null);// 有子节点if(ls!=null &&  ls.size() >0){// 删除子节点for (String name : ls) {//---递归rmr(zk , path+"/"+name);}}//没有子节点zk.delete(path , -1);}
}

监控和通知

  • 连接成功 监听通知
  • 数据变化
  • 节点变化

例子

package com.doitedu.zk.cli;import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;import java.io.IOException;/*** @Date 2022/2/23* @Created by HANGGE* @Description 连接对象获取成功 事件通知*/
public class TestWatcher01 {public static void main(String[] args) throws Exception {/*** 参数三  事件通知  监听器*  在获取对象的时候使用  当连接成功以后会  回调一次process方法*/ZooKeeper zk = new ZooKeeper("linux11:2181", 2000, new Watcher() {public void process(WatchedEvent event) {System.out.println("获取连接成功......");}});System.out.println(zk);zk.close();}}----------------------------------------------------------------------
package com.doitedu.zk.cli;import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;/*** @Date 2022/2/23* @Created by HANGGE* @Description* 监听节点数据的变化*   当监听的节点的数据发生变化    通知客户端  回调process*/
public class TestWatcher02 {public static void main(String[] args) throws Exception {/*** 参数三  事件通知  监听器*  在获取对象的时候使用  当连接成功以后会  回调一次process方法*/final ZooKeeper zk = new ZooKeeper("linux01:2181", 2000, null);// 获取指定节点数据的时候  绑定监听器  监听此节点数据的变化byte[] data = zk.getData("/b", new Watcher() {// /b节点数据变化就会执行这个方法   1次public void process(WatchedEvent event) {try {System.out.println("/b的数据发生了变化....");System.out.println(event.getType());// 改变后的数据是byte[] data1 = zk.getData("/b", this, null);System.out.println("变化后的的数据是: "+new String(data1));} catch (Exception e) {e.printStackTrace();}}}, null);System.out.println("变化以前的数据是: "+new String(data));Thread.sleep(Integer.MAX_VALUE);zk.close();}}
-----------------------------------------------------------------------
package com.doitedu.zk.cli;import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;import java.util.List;/*** @Date 2022/2/23* @Created by HANGGE* @Description* 监听节点数据的变化*   当监听的节点的数据发生变化    通知客户端  回调process*/
public class TestWatcher03 {public static void main(String[] args) throws Exception {/*** 参数三  事件通知  监听器*  在获取对象的时候使用  当连接成功以后会  回调一次process方法*/final ZooKeeper zk = new ZooKeeper("linux01:2181", 2000, null);List<String> ls = zk.getChildren("/", new Watcher() {// 当 / 节点的子节点 被删除  添加 执行这个方法public void process(WatchedEvent event) {try {System.out.println(event.getType());List<String> ls2 = zk.getChildren("/", this);System.out.println("变化后的节点有:"+ls2);} catch (Exception e) {e.printStackTrace();}}});System.out.println("当前的节点有: "+ls);Thread.sleep(Integer.MAX_VALUE);zk.close();}}

4 原理基础

4.1 选举机制

在ZK中有三种状态 ;

Leader: 优先负责写数据

follower  存储数据  参与选举

observe 观察者 不参与选举  存储数据

每个服务器都有一个唯一的myid标记

初始启动选举

  1. ZK服务启动[linux01(myid=1)] , 发现集群中没有Leader .进入到选举状态 ; 投自己一票
  2. myid=1的机器获取1票 , 票数没有过半, 不能当选leader
  3. linux01, 广播投票结果
  4. linux02(myid=2)启动 ,发现集群中没有leader , 进入到选举状态
  5. 收到linux01的1票信息 , 发现linux02的myid > linux01的myid ;投自己一票 ,广播
  6. linux01收到广播 ,发现自己的myid小 ; 改投lnux02 1票 , 广播
  7. linux02 收到linux01的广播  ,自己的票数为2 , 过半 ,切换leader状态
  8. linux01 切换follower状态
  9. linux03启动 ,发现集群中有leader ;切换follower状态

运行过程中选举

注意: 要求整个集群中的数据是一致的! 有事务的保证! zxid事务id

1 先比较zxid的大小 , zxid大的优先当选

2 如果事务id一致 , 再比较myid

整个集群中有机器宕机 ,属于不正常的状态! 修复.........

数据一致性

zk中存储数据以KV的形式  ; K是以节点的组织的 以/开头

整个集群中所有的节点存储一样的数据

记录的数据一般为状态数据  ,配置数据 ,命令....数据量不大

zookeeper随堂笔记相关推荐

  1. ZooKeeper私人学习笔记

    俗话说"好记性不如烂笔头",编程的海洋如此的浩大,养成做笔记的习惯是成功的一步! 此笔记主要是ZooKeeper3.4.9版本的笔记,并且笔记都是博主自己一字一字编写和记录,有错误 ...

  2. 92030302随堂笔记 c# 1614675886

    92030302随堂笔记 c# 1614675886 控件 Nodes添加节点 默认事件 被选中的节点 文本内容,Text 深度,level 控件的Nodes属性 获取所有的节点对象数组的长度 尝试用 ...

  3. 图床云存储项目课程随堂笔记

    这个项目属实重量级,第一遍学习的过程比较懵,只是记录一下随堂笔记.后面理解了项目后端代码流程,再细写几篇博客归纳. 基本单机环境配置 大的项目你可能连配置都配不清楚. 新手必须要心细,因为你错了一步, ...

  4. 【笔记】嵌入式C语言随堂笔记

    喏,你们要的嵌入式C语言随堂笔记,丰富度应该要比老师自己记录的高一些.但是机酱的废话一样很多哦! 这个笔记是自己一个字一个字手打的,话说打个原创图个慰藉没问题的吧=.= 而且那时候很菜,知道就好不许说 ...

  5. 《Advice on how to read papers》---吴恩达CS230随堂笔记

    How to read papers? Reading research papers Reading a paper Questions to ask yourself after reading ...

  6. JAVA历险记--java基础知识--随堂笔记

    JAVA基础知识随堂笔记 简介 学习视频 题1 题2 答疑 简介 由于本人从事Delphi(很古董的语言了)和c#开发,所以一些基础的知识还是比较了解的,需要熟悉的是IDE的简单操作,以及JAVA的相 ...

  7. 汤家凤高等数学基础阶段课程的随堂笔记并标记重点

    本文内容为汤家凤高数基础阶段课程的随堂笔记并标记重点,我主页中的思维导图中内容大多从我的笔记中整理而来,相应技巧可在笔记中查找原题,有兴趣的可以去 我的主页 了解更多计算机学科的精品思维导图整理 本文 ...

  8. winsever服务系统基础教程(随堂笔记)

    本文草稿链接https://www.yuque.com/docs/share/000c4611-fa69-4881-90f4-d35ace0f9d26?# <winsever服务系统基础教程(随 ...

  9. linux加权_「学员笔记」LINUX随堂笔记(十一):LVS负载均衡群集

    第12章 LVS负载均衡群集 一.群集概述 1.1 群集的类型 无论是哪种群集,都至少包括两台节点服务器,而对外表现为一个整体,只提供一个访问入口(域名或IP地址),相当于一台大型计算机,根据群集所提 ...

最新文章

  1. golang中的plugin包
  2. 线段树 区间更新模板
  3. linux下hg无法运行_在 Windows 里也可以访问 Linux 子系统文件了
  4. R 学习 - 箱线图
  5. linux php源码安装mysql_linux源码安装mysql5.7
  6. Python培训班怎么选?
  7. 打docker镜像_分分钟搞定阿里云私有Docke镜像仓库的搭建
  8. 2021-06-28
  9. 图解通信原理与案例分析-18:低功耗、远距离物联网无线通信技术LoRa概述与扩频通信的基本原理
  10. 程序员常用英语单词1700
  11. php网站后台密码忘记,phpweb忘记后台密码
  12. pg_auto_failover 之三 automated failover
  13. R语言ETL系列:创建字段(mutate)
  14. User-Agent反爬虫的原理和绕过方法
  15. 解决在iOS9上安装的软件显示未受信任的企业级开发者
  16. 天文基础浏览-盖亚计划
  17. 回顾知识点:操作系统篇(二)
  18. java book打印机_java如何调用本地打印机进行图片打印
  19. 阿里云网站备案申请被驳回的问题解答汇总
  20. 深度神经网络TensorFlow基础学习(3)——卷积神经网络的参数个数和张量大小

热门文章

  1. Win7 64位系统下思维导图XMind的Java环境配置
  2. MySQL安装--无法初始化
  3. 4PAM的误码率仿真
  4. mysql trim()_MySQL trim()函数
  5. ker矩阵是什么意思_用初等变换求逆矩阵的小小解释
  6. webdav服务器文件大小限制,WebDAV服务器
  7. (GPU) Intel 服务器独立GPU SG1 - H3C XG310试用
  8. OptiView® XG 网络分析平板电脑特性(上)
  9. 主动降噪在服务器中的应用,AirPods Pro主动降噪功能有多大用处?主动降噪耳机适用范围详解!...
  10. 基于单片机的秒表计时器系统设计(#0400)