Zookeeper基础知识:成功分布式系统的关键

文章目录

      • 一、引言
      • 二、Zookeeper介绍
      • 三、Zookeeper安装
      • 四、Zookeeper架构【`重点`】
        • 4.1 Zookeeper树形结构
        • 4.2 znode类型
        • 4.3 Zookeeper的监听通知机制
      • 五、Zookeeper常用操作
        • 5.1 zk常用命令
        • 5.2 Java连接Zookeeper
        • 5.3 Java操作Znode节点
        • 5.4 监听通知机制
      • 六、Zookeeper集群【`重点`】
        • 6.1 Zookeeper集群架构图
        • 6.2 Zookeeper集群中节点的角色
        • 6.3 Zookeeper数据同步
        • 6.4 Zookeeper选举
        • 6.5 搭建Zookeeper集群
        • 6.6 Zookeeper过半数存活原则
        • 6.7 为什么Zookeeper需要设计一个过半数存活机制?
      • 七、Java连接Zookeeper集群
      • 八,Zookeeper应用场景
        • 8.1 配置文件管理
        • 8.2 集群管理
        • 8.3 分布式锁
        • 8.4 命名服务(Dubbo监控中心原理)
        • 8.5 发现服务

一、引言

在这里插入图片描述


在分布式环境下,如果舍弃SpringCloud,使用其他的分布式框架,那么注册心中,配置集中管理,集群管理,分布式锁,分布式任务,队列的管理想单独实现怎么办。

分布式系统面临的问题

  1. 分布式系统如何实现对同一资源的访问,保证数据的强一致性?
  2. 集群中的Master挂了,传统做法是什么?zookeeper又是如何做的?
    在这里插入图片描述

二、Zookeeper介绍


ZooKeeper是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。

简单来说zookeeper=文件系统+监听通知机制

ZooKeeper最为主要的使用场景,是作为分布式系统的分布式协同服务。在学习zookeeper之前,先要对分布式系统的概念有所了解。

ZooKeeper
在这里插入图片描述

三、Zookeeper安装


docker-compose.yml

version: "3.1"
services:zk:image: daocloud.io/daocloud/zookeeper:latestrestart: alwayscontainer_name: zkports:- 2181:2181

四、Zookeeper架构【重点


4.1 Zookeeper树形结构

每个子目录项如 NameService 都被称作为 znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。

Zookeeper的架构图
在这里插入图片描述
4.2 znode类型
  • PERSISTENT-持久化目录节点

    ​ 客户端与zookeeper断开连接后,该节点依旧存在

  • PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
    ​ 客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

  • EPHEMERAL-临时目录节点

    ​ 客户端与zookeeper断开连接后,该节点被删除

  • EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点

    ​ 客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

4.3 Zookeeper的监听通知机制

zookeeper提供了节点watch的功能,zookeeper的client监控zookeeper上的节点,当节点变动的时候,client会收到变动事件和变动后的内容,基于zookeeper的这个特性,我们可以给服务器集群中的所有机器都注册watch事件,监控特定znode,节点中存储部署代码的配置信息,需要更新代码的时候,修改znode中的值,服务器集群中的每一台server都会收到代码更新事件,然后触发调用,更新目标代码。也可以很容易的横向扩展,可以随意的增删机器,机器启动的时候注册监控节点事件即可。

监听通知机制
在这里插入图片描述

五、Zookeeper常用操作

5.1 zk常用命令

Zookeeper针对增删改查的常用命令

在这里插入图片描述

5.2 Java连接Zookeeper

创建Maven工程

导入依赖

<dependencies><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.6.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>2.12.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
</dependencies>

编写连接Zookeeper集群的工具类

public class ZkUtil {public static CuratorFramework cf(){// 超时时间是3s,重试2次RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,2);CuratorFramework cf = CuratorFrameworkFactory.builder().connectString("192.168.193.88:2181").retryPolicy(retryPolicy).build();cf.start();return cf;}}
5.3 Java操作Znode节点

查询

public class Demo2 {CuratorFramework cf = ZkUtil.cf();// 获取子节点@Testpublic void getChildren() throws Exception {List<String> strings = cf.getChildren().forPath("/");for (String string : strings) {System.out.println(string);}}// 获取节点数据@Testpublic void getData() throws Exception {byte[] bytes = cf.getData().forPath("/qf");System.out.println(new String(bytes,"UTF-8"));}}

添加

@Test
public void create() throws Exception {cf.create().withMode(CreateMode.PERSISTENT).forPath("/qf2","uuuu".getBytes());
}

修改

@Test
public void update() throws Exception {cf.setData().forPath("/qf2","oooo".getBytes());
}

删除

@Test
public void delete() throws Exception {cf.delete().deletingChildrenIfNeeded().forPath("/qf2");
}

查看znode的状态

@Test
public void stat() throws Exception {Stat stat = cf.checkExists().forPath("/qf");System.out.println(stat);
}
5.4 监听通知机制
public class Demo3 {CuratorFramework cf = ZkUtil.cf();@Testpublic void tesetListener() throws Exception{CuratorFramework cf = ZkClinet.cf();TreeCache nodeCache = new TreeCache(cf,"/demo");nodeCache.getListenable().addListener(new TreeCacheListener() {@Overridepublic void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {ChildData eventData = event.getData();switch (event.getType()) {case NODE_ADDED:System.out.println("/demo" + "节点添加" + eventData.getPath() + "\t添加数据为:" + new String(eventData.getData()));break;case NODE_UPDATED:System.out.println(eventData.getPath() + "节点数据更新\t更新数据为:" + new String(eventData.getData()) + "\t版本为:" + eventData.getStat().getVersion());break;case NODE_REMOVED:System.out.println(eventData.getPath() + "节点被删除");break;default:break;}}});nodeCache.start();System.out.println("监听开始。。。");System.in.read();}
}

六、Zookeeper集群【重点


6.1 Zookeeper集群架构图
集群架构图
在这里插入图片描述
6.2 Zookeeper集群中节点的角色
  • Leader(Master):事务请求的唯一处理者,也可以处理读请求。
  • Follower(Slave):可以直接处理客户端的读请求,并向客户端响应;但其不会处理事务请求,其只会将客户端事务请求转发给Leader来处理,同步 Leader 中的事务处理结果;Leader 选举过程的参与者,具有选举权与被选举权。(就好像正式工)
  • Observer(Slave):可以理解为不参与 Leader 选举的 Follower,在 Leader 选举过程中没有选举权与被选举权;同时,对于 Leader 的提案没有表决权。用于协助 Follower 处理更多的客户端读请求。Observer 的增加,会提高集群读请求处理的吞吐量,但不会增加事务请求的通过压力,不会增加 Leader 选举的压力。(就好像临时工)
6.3 Zookeeper数据同步

​ ZooKeeper 集群的所有机器通过一个 Leader来完成写服务(也可以完成读)。Follower只提供读服务,不能提供写服务。

  1. 如果有机器要对节点做更新,这个机器先告诉Leader。

  2. Leader收到后请求后广播给所有的节点进行写操作,每个角色都在自己的机器中写。

  3. 每个机器写完后都给Leader汇报是否写入成功

  4. 如果有一半的机器写成功了Leader就下发第二个指令

  5. 提交事务,以广播的形式发出。

6.4 Zookeeper选举
  • 每一个Zookeeper服务都会被分配一个全局唯一的myid,··是一个数字。
  • Zookeeper在执行写数据时,每一个节点都有一个自己的FIFO的队列。保证写每一个数据的时候,顺序是不会乱的,Zookeeper还会给每一个数据分配一个全局唯一的zxid,数据越新zxid就越大。
  • 选举Leader:
    • 选举出zxid最大的节点作为Leader。
    • 在zxid相同的节点中,选举出一个myid最大的节点,作为Leader。
6.5 搭建Zookeeper集群

1、2181:对cline端提供服务

2、3888:选举leader使用

3、2888:集群内机器通讯使用(Leader监听此端口)

version: "3.1"
services:zk1:image: zookeeperrestart: alwayscontainer_name: zk1ports:- 2181:2181environment:ZOO_MY_ID: 1ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=zk3:2888:3888;2181zk2:image: zookeeperrestart: alwayscontainer_name: zk2ports:- 2182:2181environment:ZOO_MY_ID: 2ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=zk3:2888:3888;2181zk3:image: zookeeperrestart: alwayscontainer_name: zk3ports:- 2183:2181environment:ZOO_MY_ID: 3ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=zk3:2888:3888;2181

查看节点状态 zkServer.sh status

6.6 Zookeeper过半数存活原则

​ 在zookeeper集群中,当存活的机器数量超过总机器的一半的时候,整个集群才能正常工作,否则拒绝访问。基于过半数存活原则,zookeeper的集群机器数量一定是奇数台,因为2N+1和2N+2的容灾能力是一样的,基于成本考虑2N+1台的选择方案更优。

6.7 为什么Zookeeper需要设计一个过半数存活机制?

*脑裂问题*

集群中的节点监听不到leader节点的心跳, 就会认为leader节点出了问题, 此时集群将分裂为不同的小集群, 这些小集群会各自选举出自己的leader节点, 导致原有的集群中出现多个leader节点。

为了防止网络脑裂,保证数据的强一致性,因为整个集群中,有可能因为网络问题"脑裂",导致整个集群分为2个甚至多个集群,如果没有过半数存活机制,那么整个zookeeper会变成多个集群,那么zookeeper提供的数据无法再保证数据一致性;

在这里插入图片描述

七、Java连接Zookeeper集群

编写连接Zookeeper集群的工具类

public class ZkUtil {public static CuratorFramework cf(){RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,2);CuratorFramework cf = CuratorFrameworkFactory.builder().connectString("192.168.199.109:2181,192.168.199.109:2182,192.168.199.109:2183").retryPolicy(retryPolicy).build();cf.start();return cf;}
}

测试类

测试
在这里插入图片描述

八,Zookeeper应用场景

8.1 配置文件管理

在这里插入图片描述

将需要统一管理的配置全部放到zookeeper上去,保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中。

8.2 集群管理

所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除。新机器加入也是类似,

我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。

8.3 分布式锁

我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁

8.4 命名服务(Dubbo监控中心原理)

在日常开发中,我们会遇到这样的场景:服务A需要访问服务B,但是服务B还在开发过程中(未完成),那么服务A(此时已完成)就不知道如何获取服务B的访问路径了,使用zookeeper的服务就可以简单解决:服务B部署成功后,可以先到zookeeper注册服务(即在zookeeper添加节点/service/B和节点数据)。服务A开发结束后,部署到服务器,然后服务A监控zookeeper服务节点/service/B,如果发现节点有数据了,那么服务A就可以访问服务B了。

8.5 发现服务

在这里插入图片描述

注册一个持久节点/service/business/what,他下面的每个子节点都是一个可用服务,保存了服务的地址端口等信息,服务调用者通过zookeeper获取/service/business/what所有子节点信息来得到可用的服务。下面的节点都是临时节点,服务器启动的时候会过来注册一个临时节点,服务器挂掉之后或主动关闭之后,临时节点会自动移除,这样就可以保证使用者获取的what服务都是可用的,而且可以动态的扩容缩容。

后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹

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

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

相关文章

Tablesgenerator 使用

1.在线工具网站 Create LaTeX tables online – TablesGenerator.com 2.按住 shift 选择边框 3.选择标题和双栏布局 4.保存和加载表格 5.默认风格与三线表 Default table style使用 \hline 而 Booktabs 使用 \toprule、\midrule和\bottomrule。 \toprule、\midrule和 \botto…

MVO-CNN-BiLSTM多输入时序预测|多元宇宙优化算法-卷积-双向长短期神经网络时序预测(Matlab)

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…

Paddle上手实战——NLP经典cls任务“推特文本情感13分类”

Paddle上手实战——NLP经典cls任务“推特文本情感13分类” 实战背景介绍 数据地址:https://www.heywhale.com/home/activity/detail/611cbe90ba12a0001753d1e9/content Twitter推文具备多重特性,首要之处在于其与Facebook的显著区别——其完全基于文本形式,通过Twitter接…

1分钟做的AI利润表分析报告,效果怎样?

各位数据的朋友&#xff0c;大家好&#xff0c;我是老周道数据&#xff0c;和你一起&#xff0c;用常人思维数据分析&#xff0c;通过数据讲故事&#xff01; 自从去年年初ChatGPT3.5推出以来&#xff0c;AI大模型的话题就一直非常热了。相比于AI聊天、生成图片&#xff0c;亦…

计算机组成原理之机器:存储器之主存储器

计算机组成原理之机器&#xff1a;存储器 笔记来源&#xff1a;哈尔滨工业大学计算机组成原理&#xff08;哈工大刘宏伟&#xff09; Chapter3&#xff1a;存储器 3.1 概述 存储器可分哪些类型&#xff1f; 现代存储器的层次结构&#xff0c;为什么要分层&#xff1f; …

【自然语言处理】NLP入门(五):1、正则表达式与Python中的实现(5):字符串常用方法:对齐方式、大小写转换详解

文章目录 一、前言二、正则表达式与Python中的实现1.字符串构造2. 字符串截取3. 字符串格式化输出4.字符转义符5. 字符串常用函数函数与方法之比较 6. 字符串常用方法1. 对齐方式center()ljust()rjust() 2. 大小写转换lower()upper()capitalize()title()swapcase() 一、前言 本…

不买后悔!腾讯云99元一年服务器链接,折合8元1个月

腾讯云服务器99元一年是真的吗&#xff1f;真的&#xff0c;99元优惠购买入口 txybk.com/go/99 折合每天8元1个月&#xff0c;腾讯云99元服务器配置为2核2G3M带宽&#xff0c;2024年99元服务器配置最新报价为61元一年&#xff0c;如下图&#xff1a; 腾讯云服务器99元一年 腾讯…

【新书推荐】16.4 软中断处理程序举例

本节内容&#xff1a;打印I/O源程序和时钟显示程序。 ■打印I/O源程序&#xff1a;t16-6.asm。 ■时钟显示程序&#xff1a;t16-7.asm。 16.4.1 打印I/O源程序 我们以打印I/O程序的源程序&#xff0c;作为BIOS中断处理程序设计的例子。每个打印机有三个寄存器&#xff1a;数据…

TCP传输收发

TCP通信: TCP发端: socket connect send recv close TCP收端: socket bind listen accept send recv close 1.connect int connect(int sockfd, const struct sockaddr *addr, socklen_t ad…

selenium也能过某数、5s盾..

文章转载于&#xff1a;selenium也能过某数、5s盾… 直接安装: pip install undetected_chromedriver运行代码&#xff1a; import undetected_chromedriver as uc import timedriver uc.Chrome(executable_pathrC:\Users\chromedriver.exe,version_main111) driver.get(网…

VMware Workstation安装Linux虚拟机与虚拟机克隆

虚拟机 一、安装虚拟机二、克隆虚拟机三、配置静态IP地址一、安装虚拟机 设置虚拟机名称与安装位置 设置磁盘大小 配置硬件参数

Ubuntu环境使用docker构建并运行SpringBoot镜像

今天Ubuntu环境使用docker构建并运行SpringBoot镜像&#xff0c;看文章之前建议先查看安装流程: Linux环境之Ubuntu安装Docker流程 一、镜像打包过程及执行 1、创建一个测试目录 mkdir javaDemo 2、springBoot的包复制到此目录下 cp demo1-0.0.1-SNAPSHOT.jar /data/app/…