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.hqwc.cn/news/236395.html

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

相关文章

热部署怎么部署

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

Java系列-new Object的过程

从《深入理解Java虚拟机》里面的第七章看到了一些&#xff0c;先简单记录一下&#xff0c;好多不懂的。 类从被加载到虚拟机内存中开始&#xff0c;到卸载出内存为止&#xff0c;它的整个生命周期包括&#xff1a;加载、验证、准备、解析、初始化、使用和卸载7个阶段。其中验证…

Stream API练习题

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 考虑到Stream API在实际…

(蓝桥杯)1125 第 4 场算法双周赛题解+AC代码(c++/java)

题目一&#xff1a;验题人的生日【算法赛】 验题人的生日【算法赛】 - 蓝桥云课 (lanqiao.cn) 思路&#xff1a; 1.又是偶数&#xff0c;又是质数&#xff0c;那么只有2喽 AC_Code:C #include <iostream> using namespace std; int main() {cout<<2;return 0; …

java_springboot企业人事考勤请假管理信息系统rsglxx+jsp

&#xff08;1&#xff09;熟练掌握Java开发的原理和方法 &#xff08;2&#xff09;熟练学习掌握SSM框架 &#xff08;3&#xff09;熟悉软件开发的流程 &#xff08;4&#xff09;了解中内外互联网中所主流的技术 &#xff08;5&#xff09;深层次的了解计算机学科领域的知识…

【机器学习】线性模型之逻辑回归

文章目录 逻辑回归Sigmoid 函数概率输出结果预测值与真实标签之间的并不匹配交叉熵逻辑回归模型 梯度下降逻辑回归模型求解编程求解sklearn 实现&#xff0c;并查看拟合指标 逻辑回归 逻辑回归是一种广义线性模型&#xff0c;形式上引入了 S i g m o i d Sigmoid Sigmoid 函数…

Vue3Element-plus编写一个简版的字典服务

之前公司有维护过一个内部的字典平台,基本步骤和页面如下 添加字典属性弹窗 添加枚举值弹窗 基本业务代码如下 核心代码 import { defineStore } from pinia export const useDictionary defineStore(dictionary, {state: () > ({dict: [],dictObj: {},}),actions: {s…

贪心算法的介绍

贪心算法&#xff08;又称贪婪算法&#xff09;是指&#xff0c;在对问题求解时&#xff0c;总是做出在当前看来是最好的选择。也就是说&#xff0c;不从整体最优上加以考虑&#xff0c;他所做出的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解&#…

J签证、移民、绿卡都是怎么回事?

随着全球化的不断推进&#xff0c;越来越多的人开始关注国际间的移民与签证政策&#xff0c;其中包括J签证、移民以及绿卡的申请问题。本文将简要介绍J签证、移民绿卡的基本概念&#xff0c;并提供相关申请的一般步骤&#xff0c;以帮助读者更好地了解这些程序。 首先&#xff…

上海毅速丨新材料将推动3D打印在压铸行业的应用

压铸是一种应用广泛的制造工艺&#xff0c;它的制造原理是将液态或半液态金属&#xff0c;在高压作用下&#xff0c;以高速度填充压铸模具型腔&#xff0c;并在压力下快速凝固而获得铸件的一种方法。压铸模的设计和制造需要考虑到多方面的因素&#xff0c;如模具材料、结构、冷…

【MATLAB】EWT分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 EWTFFTHHT组合算法是一种广泛应用于信号处理领域的算法&#xff0c;它结合了经验小波变换&#xff08;Empirical Wavelet Transform&#xff0c;EWT&#xff09;、快速傅里叶变换&#x…

windows配置服务开机自启和保活

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、下载WinSW&#xff1f;二、使用步骤1.解压2.配置3.安装服务4.服务启停5.服务卸载6.开机自启7.保活 总结 前言 写了一个程序或者是exe&#xff0c;或者是ba…