常见的锁和zookeeper

news2024/11/28 22:31:27

zookeeper

本文由 简悦 SimpRead 转码, 原文地址 zhuanlan.zhihu.com

前言

只有光头才能变强。
文本已收录至我的 GitHub 仓库,欢迎 Star:https://github.com/ZhongFuCheng3y/3y

上次写了一篇 什么是消息队列?以后,本来想入门一下 Kafka 的 (装一下环境、看看 Kafka 一些概念啥的)。后来发现 Kafka 用到了 ZooKeeper,而我又对 ZooKeeper 不了解,所以想先来学学什么是 ZooKeeper,再去看看什么是 Kafka。

ZooKeeper 相信大家已经听过这个词了,不知道大家对他了解多少呢?我第一次听到 ZooKeeper 的时候是在学 Eureka 的时候(外行人都能看懂的 SpringCloud,错过了血亏!),同样 ZooKeeper 也可以作为注册中心

后面听到 ZooKeeper 的时候,是因为 ZooKeeper 可以作为分布式锁的一种实现。

直至在了解 Kafka 的时候,发现 Kafka 也需要依赖 ZooKeeper。Kafka 使用 ZooKeeper 管理自己的元数据配置

这篇文章来写写我学习 ZooKeeper 的笔记,如果有错的地方希望大家可以在评论区指出。

一、什么是 ZooKeeper

从上面我们也可以发现,好像哪都有 ZooKeeper 的身影,那什么是 ZooKeeper 呢?我们先去官网看看介绍:

官网还有另一段话:

ZooKeeper: A Distributed Coordination Service for Distributed Applications

相比于官网的介绍,我其实更喜欢 Wiki 中对 ZooKeeper 的介绍:

(留下不懂英语的泪水)

我简单概括一下:

  • ZooKeeper 主要服务于分布式系统,可以用 ZooKeeper 来做:统一配置管理、统一命名服务、分布式锁、集群管理。

  • 使用分布式系统就无法避免对节点管理的问题 (需要实时感知节点的状态、对节点进行统一管理等等),而由于这些问题处理起来可能相对麻烦和提高了系统的复杂性,ZooKeeper 作为一个能够通用解决这些问题的中间件就应运而生了。

二、为什么 ZooKeeper 能干这么多?

从上面我们可以知道,可以用 ZooKeeper 来做:统一配置管理、统一命名服务、分布式锁、集群管理。

  • 这里我们不管统一配置管理、统一命名服务、分布式锁、集群管理每个具体的含义 (后面会讲)

那为什么 ZooKeeper 可以干那么多事?来看看 ZooKeeper 究竟是何方神物,在 Wiki 中其实也有提到:

ZooKeeper nodes store their data in a hierarchical name space, much like a file system or a tree data structure

ZooKeeper 的数据结构,跟 Unix 文件系统非常类似,可以看做是一颗,每个节点叫做 ZNode。每一个节点可以通过路径来标识,结构图如下:

那 ZooKeeper 这颗 “树” 有什么特点呢??ZooKeeper 的节点我们称之为 Znode,Znode 分为两种类型:

  • 短暂 / 临时 (Ephemeral):当客户端和服务端断开连接后,所创建的 Znode(节点) 会自动删除
  • 持久 (Persistent):当客户端和服务端断开连接后,所创建的 Znode(节点) 不会删除

ZooKeeper 和 Redis 一样,也是 C/S 结构 (分成客户端和服务端)

2.1 监听器

在上面我们已经简单知道了 ZooKeeper 的数据结构了,ZooKeeper 还配合了监听器才能够做那么多事的。

常见的监听场景有以下两项:

  • 监听 Znode 节点的数据变化
  • 监听子节点的增减变化

没错,通过监听 + Znode 节点 (持久 / 短暂 [临时]),ZooKeeper 就可以玩出这么多花样了。

三、ZooKeeper 是怎么做到的?

下面我们来看看用 ZooKeeper 怎么来做:统一配置管理、统一命名服务、分布式锁、集群管理。

3.1 统一配置管理

比如我们现在有三个系统 A、B、C,他们有三份配置,分别是ASystem.yml、BSystem.yml、CSystem.yml,然后,这三份配置又非常类似,很多的配置项几乎都一样。

  • 此时,如果我们要改变其中一份配置项的信息,很可能其他两份都要改。并且,改变了配置项的信息很可能就要重启系统

于是,我们希望把ASystem.yml、BSystem.yml、CSystem.yml相同的配置项抽取出来成一份公用的配置common.yml,并且即便common.yml改了,也不需要系统 A、B、C 重启。

做法:我们可以将common.yml这份配置放在 ZooKeeper 的 Znode 节点中,系统 A、B、C 监听着这个 Znode 节点有无变更,如果变更了,及时响应。

参考资料:

  • 基于 zookeeper 实现统一配置管理

  • https://blog.csdn.net/u011320740/article/details/78742625

3.2 统一命名服务

统一命名服务的理解其实跟域名一样,是我们为这某一部分的资源给它取一个名字,别人通过这个名字就可以拿到对应的资源。

比如说,现在我有一个域名www.java3y.com,但我这个域名下有多台机器:

  • 192.168.1.1
  • 192.168.1.2
  • 192.168.1.3
  • 192.168.1.4

别人访问www.java3y.com即可访问到我的机器,而不是通过 IP 去访问。

3.3 分布式锁

锁的概念在这我就不说了,如果对锁概念还不太了解的同学,可参考下面的文章

  • Java 锁?分布式锁?乐观锁?行锁?

我们可以使用 ZooKeeper 来实现分布式锁,那是怎么做的呢??下面来看看:

系统 A、B、C 都去访问/locks节点

访问的时候会创建带顺序号的临时 / 短暂 (EPHEMERAL_SEQUENTIAL) 节点,比如,系统 A 创建了id_000000节点,系统 B 创建了id_000002节点,系统 C 创建了id_000001节点。

接着,拿到/locks节点下的所有子节点 (id_000000,id_000001,id_000002),判断自己创建的是不是最小的那个节点

  • 如果是,则拿到锁。

  • 释放锁:执行完操作后,把创建的节点给删掉

  • 如果不是,则监听比自己要小 1 的节点变化

举个例子:

  • 系统 A 拿到/locks节点下的所有子节点,经过比较,发现自己 (id_000000),是所有子节点最小的。所以得到锁

  • 系统 B 拿到/locks节点下的所有子节点,经过比较,发现自己 (id_000002),不是所有子节点最小的。所以监听比自己小 1 的节点id_000001的状态

  • 系统 C 拿到/locks节点下的所有子节点,经过比较,发现自己 (id_000001),不是所有子节点最小的。所以监听比自己小 1 的节点id_000000的状态

  • ……

  • 等到系统 A 执行完操作以后,将自己创建的节点删除 (id_000000)。通过监听,系统 C 发现id_000000节点已经删除了,发现自己已经是最小的节点了,于是顺利拿到锁

  • …. 系统 B 如上

3.4 集群状态

经过上面几个例子,我相信大家也很容易想到 ZooKeeper 是怎么 " 感知 " 节点的动态新增或者删除的了。

还是以我们三个系统 A、B、C 为例,在 ZooKeeper 中创建临时节点即可:

只要系统 A 挂了,那/groupMember/A这个节点就会删除,通过监听groupMember下的子节点,系统 B 和 C 就能够感知到系统 A 已经挂了。(新增也是同理)

除了能够感知节点的上下线变化,ZooKeeper 还可以实现动态选举 Master 的功能。(如果集群是主从架构模式下)

原理也很简单,如果想要实现动态选举 Master 的功能,Znode 节点的类型是带顺序号的临时节点 (EPHEMERAL_SEQUENTIAL) 就好了。

  • Zookeeper 会每次选举最小编号的作为 Master,如果 Master 挂了,自然对应的 Znode 节点就会删除。然后让新的最小编号作为 Master,这样就可以实现动态选举的功能了。

最后

这篇文章主要讲解了 ZooKeeper 的入门相关的知识,ZooKeeper 通过 Znode 的节点类型 + 监听机制就实现那么多好用的功能了!

当然了,ZooKeeper 要考虑的事没那么简单的,后面有机会深入的话,我还会继续分享,希望这篇文章对大家有所帮助~

参考资料:

  • 分布式服务框架 Zookeeper

  • https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/index.html

  • ZooKeeper 初识整理 (老酒装新瓶)

  • https://lxkaka.wang/2017/12/21/zookeeper/

  • ZooKeeper

  • https://www.cnblogs.com/sunshine-long/p/9057191.html

  • ZooKeeper 的应用场景

  • https://zhuanlan.zhihu.com/p/59669985

Redis分布式锁

乐观锁和悲观锁

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

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

相关文章

Ubuntu 20.04.5 LTS x86_64 Docker stable diffusion webui 及 http api接口

资源 Docker镜像 docker pull darkroot1234/ayanami:latest 参考地址: docker一键运行stable diffusion webui,常用插件和功能完备,获得镜像后可打包带走 - 哔哩哔哩 nvidia cuda 驱动 https://us.download.nvidia.cn/XFree86/aarch64/…

Django框架005:阶段性`实战小案例`“答辩“公司员工表

大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页: lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

基于 DDR3 的串口传图帧缓存系统设计实现(整体设计)

文章目录 前言一、串口传图顶层系统设计框图二、各模块说明三、系统工程及 IP 创建四、uart_ddr3_tft模块五、uart_ddr3_tft模块仿真文件六、uart_ddr3_tft模块仿真文件 前言 结合串口接收模块和 tft 显示屏控制模块,设计一个基于 DDR3 的串口传图帧缓存系统。 提示…

DES加密算法、RSA加密算法

DES加密算法 DES加密过程 1、将明文和密钥转化为ASCII码,明文64位bit,密钥56位 2、明文进行初始置换 3、明文初始置换后前32位为L0,后32位为R0 4、第一轮算法,L1R0,R0进行F运算后跟L0异或的结果为R1 5、F运算&#x…

jmeter如何测试一个get请求

目录 1.配置测试计划1.1.创建线程组1.2.创建GET的HTTP请求取样器(模拟GET请求)1.3.添加查看结果树和聚合报告 2.执行压测并查看结果2.1.验证接口2.2.执行压力测试 使用jmeter测试一个http的get请求示例. 1.配置测试计划 1.1.创建线程组 打开jmeter - 测…

C语言实现扫雷(包含递归展开)

目录 一:扫雷游戏的基础逻辑 二:关于扫雷相关的信息存储 三:游戏大体实现逻辑 四:具体实现 (1)初始化 (2)打印 (3)布置雷 (4)查雷 五:全部代码 (1)game.h (2)game.c (3)test.c 六:实际效果演示…

【操作系统复习】第6章 虚拟存储器 2

请求分页中的内存分配 在为进程分配物理块时,要解决下列的三个问题: 1. 保证进程可正常运行所需要的最少物理块数 2. 每个进程的物理块数,是固定值还是可变值(分配策略) 3. 不同进程所分配的物理块数&#xff…

Python基础入门编程代码练习(三)

一、猜数游戏 有一个数列:8,4,2,1,23,344,12循环输出数列的值求数列中所有数值的和猜数游戏:从键盘中任意输入一个数据,判断数列中是否包含此数 实现代码如下&#xf…

【云原生】Kubrenetes二进制--单节点Master集群

单节点Master集群 一、Kubernetes概述1、Master组件2、Node组件 二、Kubernetes核心概念1、Pod概述2、Pod控制器3、Label标签4、Label选择器5、Service6、Ingress 三、部署kubernetes1、所有节点关闭防火墙 核心防护 Swap交换2、将三台服务器的地址hosts中3、调整内核参数4、时…

十分钟教你搭建ChatGPT 图片生成的安卓应用

十分钟教你搭建ChatGPT 图片生成的安卓应用 大家好,我是易安! 今天,我们将集成 OpenAI API (ChatGPT)来构建一个简单的类似 ChatGPT 的 android 应用程序,让它返回我们想要的图片,本文是上一篇的姊妹篇。 详细步骤 第…

防止表单重复提交的几种方式,演示一个自定义注解方式的实现

防止表单重复提交的几种方式,演示一个自定义注解方式的实现 一、防止表单重复提交的几种方式方式一:Token 机制方式二:去重表(主要是利用 MySQL 的唯一索引机制来实现的)方式三:Redis 的 setnx方式四&#…

数组(C语言版)

🤩本文作者:大家好,我是paperjie,感谢你阅读本文,欢迎一建三连哦。 🥰内容专栏:这里是《C知识系统分享》专栏,笔者用重金(时间和精力)打造,基础知识一网打尽,…

3 ES快速入门

3 ES快速入门 ES作为一个索引及搜索服务,对外提供丰富的REST接口,快速入门部分的实例使用head插件来测试,目的是对ES 的使用方法及流程有个初步的认识。 3.1 创建索引库 ES的索引库是一个逻辑概念,它包括了分词列表及文档列表…

电力系统负荷与电价预测优化模型(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【C++】vector的模拟实现及深度剖析

目录 一、模拟实现二、使用memcpy拷贝问题三、动态二维数组理解 一、模拟实现 namespace hxj {template<class T>class vector{public:// Vector的迭代器是一个原生指针typedef T* iterator;typedef const T* const_iterator;//构造和销毁vector():_start(nullptr), _fi…

Spring更简单的存储和读取Bean对象

目录 1.第一个Spring项目 2.存储Bean对象 2.1 准备工作 2.2 五大类注解 2.3 方法注解Bean 2.4 Bean对象的默认命名规则 3. 读取Bean对象 3.1 属性注入 3.2 setter注入 3.3 构造方法注入 3.4 注入异常问题 3.5 注入方式优缺点 3.6 Autowired和Resource的区别 1.第一…

python web开发(二):HTML标签语言

文章目录 简介标签语法标题div和span超链接插入图片列表表格Input系列提交表单 参考 简介 如下展示了一段简单的HTML模板&#xff0c; <head></head>标签中主要包含一些基本配置&#xff0c;如编码方式&#xff0c;标题等&#xff0c;注意标题的作用如下图所示 …

【java BUG收集-持续更~】

JAVA BUG JAVA BUGliquibase.lockservice锁异常1、启动参数增加jvm参数 -Dliquibase.lockservicefalse2、修改或清空 包含有 DATABASECHANGELOGLOCK的表 JAVA BUG 该章收集工作中遇到的java bug,作为工作日志&#xff0c;方便回顾。 liquibase.lockservice锁异常 报错信息&a…

Spring Boot实用技巧之单元测试

文章目录 一、单元测试的概念二、单元测试的优势三、Spring Boot实现单元测试&#xff08;一&#xff09;添加依赖&#xff08;二&#xff09;生成单元测试的类&#xff08;三&#xff09; 添加注解和业务代码1. 添加 SpringBootTest 注解2. 添加单元测试的业务代码3. 执行测试…

MySQL部分常用函数总结

数值计算函数 使用方法&#xff1a; ABS&#xff08;x&#xff09; date函数 获取date中对应部分&#xff1a; YEAR(date) 字符串函数 用法举例&#xff1a; 左侧截取字符 SELECT LEFT(‘MySQL’,2); 按符号拆分字符&#xff0c;返回拆分后的部分 SUBSTRING_INDEX(profile,“…