Zookeeper从零入门笔记

Zookeeper从零入门笔记

  • 一、入门
    • 1. 概述
    • 2. 特点
    • 3. 数据结构
    • 4. 应用场景
  • 二、本地
    • 1.安装
    • 2. 参数解读
  • 三、集群操作
    • 3.1.1 集群安装
    • 3.2 选举机制
      • 1. 第一次启动
      • 2. 非第一次启动
    • 3.3 ZK集群启动停止脚本
    • 3.4 客户端命令行操作
      • 3.2.1 命令行语法
      • 3.2.2 节点类型(持久/短暂/有序号/无序号)
      • 3.2.4 监听器原理
      • 3.3 删除节点
    • 3.5 客户端API操作
    • 3.6 监听节点变化
    • 3.7 判断Znode是否存在
    • 3.8 写数据原理
  • 四、服务器动态上下线监听案例
  • 五、ZooKeeper分布式锁案例
    • 5.1、分布式锁-成熟框架curator
  • 六、企业面试真题

一、入门

1. 概述

在这里插入图片描述
在这里插入图片描述

2. 特点

在这里插入图片描述

3. 数据结构

在这里插入图片描述

4. 应用场景

统一命名服务:nginx也可以实现
统一配置管理:
统一集群管理:
服务器动态上下线:
软负载均衡:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、本地

1.安装

2. 参数解读

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、集群操作

3.1.1 集群安装

在这里插入图片描述
在这里插入图片描述

遇到问题:1防火墙未关闭,2配置错误
sudo systemctl stop firewalld
加到zok.conf中:

############cluster#################
server.2=192.168.88.130:2888:3888
server.3=192.168.88.131:2888:3888
server.4=192.168.88.132:2888:3888

3.2 选举机制

1. 第一次启动

在这里插入图片描述

2. 非第一次启动

在这里插入图片描述

3.3 ZK集群启动停止脚本

#!/bin/bash
case $1 in
"start"){for i in 192.168.88.130 192.168.88.131 192.168.88.132doecho -------- zookeeper $i 启动 ------------ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"done
}
;;
"stop"){for i in 192.168.88.130 192.168.88.131 192.168.88.132doecho -------- zookeeper $i 停止 ------------ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop"done
}
;;
"status"){for i in 192.168.88.130 192.168.88.131 192.168.88.132doecho -------- zookeeper $i 状态 ------------ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh status"done
}
;;
esac

3.4 客户端命令行操作

3.2.1 命令行语法

在这里插入图片描述

在这里插入图片描述

3.2.2 节点类型(持久/短暂/有序号/无序号)

在这里插入图片描述
临时节点:退出客户端以后删除
有序节点:可重复,key后自带序号

create /sanguo/shuguo/zhangfei #创建永久无序节点
create -s /sanguo/shuguo/guanyu #创建永久有序节点
create -s -e /sanguo/wuguo/zhouyu1 #创建临时有序节点
create -e /sanguo/wuguo/zhouyu2 #创建临时无序节点

3.2.4 监听器原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 删除节点

在这里插入图片描述

3.5 客户端API操作

在这里插入图片描述
在这里插入图片描述

3.6 监听节点变化

在这里插入图片描述

3.7 判断Znode是否存在

3.8 写数据原理

分为两种情况:
1、请求发送给Leader节点;

  1. Client发送write请求给Leader,Leader收到消息先写
  2. Leader将write请求转发给下一个Follower节点,Follow收到写入 完成后回一个ack给上一个节点(Leader)
  3. 大于半数的Leader节点完成写入(共3,完成2),Leader返回给Clinet一个ack表示完成
  4. Leader继续给其他Follower发送write请求,Follower接收到请求写入,完成后返回ack
    在这里插入图片描述

2、请求发送给Follower节点;

  1. Client发送write请求给Follower,Follower收到消息先转发给Leader
  2. Leader接收到write请求,先执行,然后转发给Follower
  3. Follower接收到write请求。执行,然后回复一个ack
  4. 大于半数节点已write,Leader返回一个ack给最先接触到Client的节点(Follower),Follower再返回一个ack给Client
  5. Leader给剩下的Follower发送write请求,Follower写完回复ack给Leader
    在这里插入图片描述

四、服务器动态上下线监听案例

在这里插入图片描述

package com.atguigu.case1;import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;import java.io.IOException;
import java.sql.Array;
import java.util.ArrayList;
import java.util.List;/*** 2023年11月24日* <p>* case1 服务器动态上下限* <p>* 1、获取zk连接* 2、监听节点* 3、业务代码(睡觉*/
public class DistributeClient {ZooKeeper zooKeeper;public static void main(String[] args) throws IOException, InterruptedException, KeeperException {DistributeClient zk = new DistributeClient();zk.connect();zk.watcherList();zk.business();}private void business() throws InterruptedException {Thread.sleep(Long.MAX_VALUE);}private void watcherList() throws InterruptedException, KeeperException {List<String> children = zooKeeper.getChildren("/servers", true, null);ArrayList<String> strings = new ArrayList<String>();for (String child : children) {byte[] data = zooKeeper.getData("/servers/" + child, false, null);strings.add(new String(data));}System.out.println(strings);}private void connect() throws IOException {String connectString = "192.168.88.130:2181,192.168.88.131:2181,192.168.88.132:2181";int sessionTimeout = 300000;zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {public void process(WatchedEvent watchedEvent) {try {watcherList();} catch (InterruptedException e) {throw new RuntimeException(e);} catch (KeeperException e) {throw new RuntimeException(e);}}});}
}
package com.atguigu.case1;import org.apache.zookeeper.*;import java.io.IOException;/*** case 1* 服务器动态上下线例子* <p>* 1. 创建zk连接* 2. 注册服务器到zk集群* 3. 业务代码(睡觉*/
public class DistributeServer {ZooKeeper zooKeeper;public static void main(String[] args) throws IOException, InterruptedException, KeeperException {DistributeServer zk = new DistributeServer();zk.connect();zk.register(args[0]);zk.business();}private void business() throws InterruptedException {Thread.sleep(Long.MAX_VALUE);}private void register(String hostName) throws InterruptedException, KeeperException {zooKeeper.create("/servers/"+hostName, hostName.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);System.out.println(hostName + "已注册上");}private void connect() throws IOException {String connectString = "192.168.88.130:2181,192.168.88.131:2181,192.168.88.132:2181";int sessionTimeout = 3000000;zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {public void process(WatchedEvent watchedEvent) {}});}}

五、ZooKeeper分布式锁案例

在这里插入图片描述

package com.atguigu.case2;import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;/*** 分布式锁*/
public class DistributedLock {public ZooKeeper zooKeeper;public CountDownLatch connectLatch = new CountDownLatch(1);public CountDownLatch waitLatch = new CountDownLatch(1);private String waitPath;private String currentNode;DistributedLock() throws IOException, InterruptedException, KeeperException {//连接zkString connectString = "192.168.88.130:2181,192.168.88.131:2181,192.168.88.132:2181";int sessionTimeout = 3000;zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {public void process(WatchedEvent watchedEvent) {//连接完成后释放connectLatchif (watchedEvent.getState() == Event.KeeperState.SyncConnected) {connectLatch.countDown();}//当前锁节点为最小锁时,释放waitLatchif (watchedEvent.getType() == Event.EventType.NodeDeleted && watchedEvent.getPath().equals(waitPath)) {waitLatch.countDown();}}});//连接完成后继续执行connectLatch.await();}public void lock() throws InterruptedException, KeeperException {// 检测locks节点是否存在,不存在就建一个Stat exists = zooKeeper.exists("/locks", false);if (exists == null){zooKeeper.create("/locks",null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);}//创建锁节点currentNode = zooKeeper.create("/locks/res-",null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);// 判断是否是头一个,是的话给锁List<String> locks = zooKeeper.getChildren("/locks", false);Collections.sort(locks);//若数组内无值,说明就是第一位可以直接给锁if (locks.size() == 0){}else {//算出创建锁的位置,判断是否是最小的,是的话就给锁,否则对上一个锁进行监听int location = locks.indexOf(currentNode.substring("/locks/".length()));if (location == 0){//最小给锁}else if (location == -1){//错误System.out.println("错误");}else {waitPath = locks.get(location - 1);zooKeeper.getData(waitPath,true,null);//等待监听waitLatch.await();}}}public void unlock() throws InterruptedException, KeeperException {zooKeeper.delete(currentNode,-1);}
}
package com.atguigu.case2;import org.apache.zookeeper.KeeperException;import java.io.IOException;public class Client {public static void main(String[] args) throws IOException, InterruptedException, KeeperException {new Thread(new Runnable() {public void run() {try {DistributedLock distributedLock = new DistributedLock();distributedLock.lock();System.out.println("线程1启动,获取锁");Thread.sleep(5 * 1000);distributedLock.unlock();System.out.println("线程1释放锁");} catch (InterruptedException e) {throw new RuntimeException(e);} catch (KeeperException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}}).start();new Thread(new Runnable() {public void run() {try {DistributedLock distributedLock = new DistributedLock();distributedLock.lock();System.out.println("线程2启动,获取锁");Thread.sleep(5 * 1000);distributedLock.unlock();System.out.println("线程2释放锁");} catch (InterruptedException e) {throw new RuntimeException(e);} catch (KeeperException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}}).start();}
}

5.1、分布式锁-成熟框架curator

在这里插入图片描述

六、企业面试真题

EPOCH:leader任期
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/187473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

六:Day01_Spring Boot01

一、Spring Boot简介 1. 概念简介 Spring Boot是Spring公司的一个顶级项目&#xff0c;和Spring Framework是一个级别的。 Spring Boot实际上是利用Spring Framework 4 自动配置特性完成。编写项目时不需要编写xml文件。 2. 启动器介绍 Spring Boot的启动器实际上就是一个依赖…

热部署怎么部署

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言操作流程&#xff1a;在这里插入图片描述 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a832d83c091742eda9d9325931a89df4.png) 这里的跟上面的…

WPF实战项目十九(客户端):修改RestSharp的引用

修改HttpRestClient&#xff0c;更新RestSharp到110.2.0&#xff0c;因为106版本和110版本的代码不一样&#xff0c;所以需要修改下代码 using Newtonsoft.Json; using RestSharp; using System; using System.Threading.Tasks; using WPFProjectShared;namespace WPFProject.S…

算法通关村第十八关青铜挑战——透析回溯的模板

大家好&#xff0c;我是怒码少年小码。 回溯是最重要的算法思想之一&#xff0c;主要解决一些暴力枚举也搞不定的问题&#xff08;组合、子集、分割、排列、棋盘等等&#xff09;。性能并不高&#xff0c;但是哪些暴力枚举都无法ko的问题能解出来就可以了&#x1f923;。 这一…

BUUCTF [GXYCTF2019]BabySQli 1 详解!(MD5与SQL之间的碰撞)

题目环境burp抓包 随便输入值 repeater放包 在注释那里发现某种编码 MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5 看着像是base编码格式 通过测试发现是套加密&#xff08;二次加密&#xff09; 首先使用base32对此编码…

项目11:豆瓣首页-页脚 完结撒花!

这次我们就来制作豆瓣首页的最后一部分页脚。 同样&#xff0c;页脚也在container中&#xff0c;页脚分为左区域和右区域&#xff0c;左区域里是多个p元素与a元素结合完成的&#xff0c;还要插入一些图片&#xff0c;右区域里里有几个横向菜单&#xff0c;以及一张图片。 左右…

近期知识点

aop (1) 要求利用AOP记录用户操作日志。内容包含以下信息&#xff1a;ip地址、用户名、请求的地址&#xff0c;请求的时间 &#xff08; 4 分&#xff09; &#xff08;2&#xff09;要求利用AOP记录用户操作日志&#xff0c;日志记录到文本文件。内容包含以下信息&#xff…

在Spring Boot中使用JavaMailSender发送邮件

用了这么久的Spring Boot&#xff0c;我们对Spring Boot的了解应该也逐步进入正轨了&#xff0c;这篇文章讲的案例也在我们的实际开发中算是比较实用的了&#xff0c;毕竟我们完成注册功能和对用户群发消息&#xff0c;都可以采用到邮箱发送功能&#xff0c;往下看&#xff0c;…

寿险公司通过开源治理保障数字创新,安全打通高质量服务新通道

某寿险公司致力于为消费者提供人性化的产品和服务&#xff0c;在中国保险市场中始终保持前列。该寿险公司以挖掘和满足客户需求为出发点&#xff0c;从产品开发、渠道销售、运营流程和售后服务等各环节&#xff0c;借助数字化工具&#xff0c;不断地努力探索并提升服务品质。 精…

C++ :运算符重载

运算符重载&#xff1a; 运算符重载概念&#xff1a;对已有的运算符重新进行定义&#xff0c;赋予其另一种功能&#xff0c;以适应不同的数据类型 运算符的重载实际是一种特殊的函数重载&#xff0c;必须定义一个函数&#xff0c;并告诉C编译器&#xff0c;当遇到该重载的运算符…

IDEA中的Postman!

Postman是大家最常用的API调试工具&#xff0c;那么有没有一种方法可以不用手动写入接口到Postman&#xff0c;即可进行接口调试操作&#xff1f;今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;写完代码就可以调试接口并一键生成接口文档&#xff01;而且还…

SAP 如何检查已安装的SAP UI5 版本

第一个方法是直接从FLP中查看 但是部分高版本的FLP中没有这个about&#xff0c; 那么在当前界面可以使用&#xff1a;CTRL ALT SHIFT S 查看当前版本 根据此版本&#xff0c;去进行你的UI5的开发吧

观察者模式

1.观察者模式是什么呢&#xff1f; 观察者模式&#xff08;有时又被称为发布-订阅Subscribe>模式、模型-视图View>模式、源-收听者Listener>模式或从属者模式&#xff09;是软件设计模式的一种。在此种模式中&#xff0c;一个目标物件管理所有相依于它的观察者物件&am…

2分图匹配算法

定义 节点u直接无边&#xff0c;v之间无边&#xff0c;边只存在uv之间。判断方法&#xff1a;BFS染色法&#xff0c;全部染色后&#xff0c;相邻边不同色 无权二部图中的最大匹配 最大匹配即每一个都匹配上min&#xff08;u&#xff0c; v&#xff09;。贪心算法可能导致&…

【Unity】Blender场景导入

素材 下载场景&#xff1a;https://www.aplaybox.com/details/model/keDSIks72Qh3 blender文件导出为.fbx文件&#xff0c;路径选择复制&#xff08;做的过程太乱了不知道有没有影响&#xff09;&#xff0c;物理类型选择网格&#xff0c;勾选应用变换 blender下的物体长度是u…

SS8813T 打印机驱动芯片

SS8813为打印机和其它电机一体化应用提供一种双通道集成电机驱动方案。SS8813有两路H桥驱动&#xff0c;每个H桥可提供最大峰值电流2.5A和均方根电流1.75A(在24V和Ta 25C适当散热条件下)&#xff0c;可驱动两个刷式直流电机&#xff0c;或者一个双极步进电机&#xff0c;或者螺…

Xilinx FPGA——ISE的UCF时序约束

时序约束是我们对FPGA设计的要求和期望&#xff0c;例如&#xff0c;我们希望FPGA设计可以工作在多快的时钟频率下等等。 设计是要求系统中的每一个时钟都进行时序约束。 一、分组约束语法&#xff08;NET、PIN、INST&#xff09; TNM是最基本的分组约束语法&#xff0c;其语法…

【小布_ORACLE笔记】Part11-5 RMAN Backups

【小布_ORACLE笔记】Part11-5 RMAN Backups 文章目录 【小布_ORACLE笔记】Part11-5 RMAN Backups1. 增量备份&#xff08;Incremental Backups)1.1差异增量备份&#xff08;Differential Incremental Backup&#xff09;1.2累积增量备份&#xff08;Cumulative Incremental Bac…

C#WPF本地化语言实例

本文演示C#WPF中使用.resx资源文件本地化语言实例 一、更改默认Resources.resx 文件 在解决方案资源管理器中,您将在“属性”文件夹下看到 Resources.resx 文件。将访问修饰符从内部更改为公共,以便可以在 XAML 文件中访问它。 二、创建新资源文件 默认情况下,程序使用默…

uniapp如何与原生应用进行混合开发?

目录 前言 1.集成Uniapp 2.与原生应用进行通信 3.实现原生功能 4.使用原生UI组件 结论: 前言 随着移动应用市场的不断发展&#xff0c;使用原生开发的应用已经不能满足用户的需求&#xff0c;而混合开发成为了越来越流行的选择。其中&#xff0c;Uniapp作为一种跨平台的开…