了解 ZooKeeper:关键概念和架构

ZooKeeper 是一种分布式协调服务,广泛用于分布式系统中,用于维护配置信息、命名、同步和组服务。它最初由雅虎开发,现在是一个 Apache 项目,已成为许多大型分布式应用程序不可或缺的一部分。本文深入探讨 ZooKeeper 的关键概念和架构,全面了解其功能和重要性。

介绍

随着分布式系统变得越来越复杂,对可靠协调服务的需求也变得至关重要。ZooKeeper 通过为分布式应用程序提供高性能协调服务来满足这一需求。它有助于管理配置信息、跨分布式节点同步任务以及维护组成员身份,从而确保分布式系统能够协同运行。

关键概念

  1. ZooKeeper 集合: ZooKeeper 中的集合由一组服务器(通常是奇数)组成,它们共同管理分布式协调。集合中的每个服务器都维护相同数据的副本,以确保高可用性和可靠性。在典型设置中,如果大多数服务器正常运行,集合就可以继续运行。这称为仲裁。
  2. ZNodes: ZooKeeper 将其数据存储在类似于文件系统的分层命名空间中。此层次结构中的每个节点称为 ZNode。ZNode 是 ZooKeeper 中的基本数据单元,可以是持久的,也可以是临时的。持久 ZNode 会一直存在,直到被明确删除,而临时 ZNode 会在创建它们的会话结束时自动删除。
  3. 会话: 当客户端连接到 ZooKeeper 集合时,会建立一个会话。会话是客户端与集合之间的临时连接,在此期间客户端可以执行各种操作。如果客户端在一定超时时间内断开连接并重新连接,则会重新建立会话。如果客户端在此期限内无法重新连接,则会话被视为已过期。
  4. 监视: ZooKeeper 允许客户端在 ZNode 上设置监视。监视是一种让客户端接收 ZNode 更改通知的机制。发生更改时(例如,创建、删除或修改 ZNode),ZooKeeper 会向设置监视的客户端发送事件通知。此功能对于需要随时了解分布式环境中的更改的应用程序非常方便。
  5. 原子广播协议 (Zab): ZooKeeper 原子广播 (Zab) 协议是 ZooKeeper 可靠性和一致性的核心。Zab 是一种崩溃恢复原子广播协议,可确保集合中的所有服务器都收到相同的状态更改序列。它分为两个阶段运行:领导者选举阶段和广播阶段。在领导者选举期间,一台服务器被选为领导者,然后向追随者广播状态更改。这可确保所有服务器保持一致的状态。

ZooKeeper 架构

ZooKeeper 的架构旨在提供高吞吐量、低延迟和高可用性。它由三个主要组件组成:客户端库、ZooKeeper 服务器和数据存储。

  1. 客户端库: 客户端库是客户端与 ZooKeeper 集合交互的接口。它提供用于创建、删除和管理 ZNode、设置监视和处理会话的 API。客户端库设计为轻量级且高效,可确保客户端应用程序的开销最小。
  2. ZooKeeper 服务器: ZooKeeper 集群由多个服务器(通常为 3、5 或 7 个)组成,它们协同工作以提供可靠的协调服务。这些服务器可分为三种角色:领导者、追随者和观察者。
  • Leader: Leader 负责处理来自客户端的所有写入请求,并与跟随者同步状态更改。它确保状态更改在整个集合中有序且一致。
  • **追随者:**追随者从领导者处接收状态变化并相应地更新其本地状态。它们还处理来自客户端的读取请求,在整个集合中分配读取负载。
  • **观察者:**观察者与追随者类似,但不参与仲裁。他们从领导者那里接收状态变化并更新其本地状态,但不参与领导者选举。观察者可用于在不影响仲裁的情况下扩展读取吞吐量。
  1. 数据存储: ZooKeeper 将数据存储在内存中,并定期将快照存储到磁盘以进行持久保存。内存存储提供快速数据访问,确保读写操作的低延迟。快照机制确保在服务器发生故障时可以恢复数据。此外,ZooKeeper 维护事务日志以记录所有状态更改,从而提供可靠的恢复机制。

用例:分布式锁服务

要了解 ZooKeeper 的影响,请考虑分布式锁服务,这是分布式系统中的常见要求。分布式锁服务可确保在任何给定时间只有一个进程可以持有锁,从而防止出现竞争条件并确保数据一致性。

执行

  1. 创建锁 ZNode: 当客户端想要获取锁时,它会/lock在 ZooKeeper 中创建一个临时 ZNode(例如)。如果 ZNode 创建成功,则该客户端持有该锁。如果 ZNode 已经存在,则意味着另一个客户端持有该锁。

  2. 释放锁: 当持有锁的客户端完成任务时,它会删除 ZNode /lock,释放锁。如果客户端的会话过期或断开连接,则会自动删除临时 ZNode,确保释放锁。

  3. **等待锁:**如果客户端尝试创建/lockZNode 并失败(因为它已经存在),它会对 ZNode 设置监视。当 ZNode 被删除(锁被释放)时,ZooKeeper 会通知客户端,然后客户端会再次尝试获取锁。

示例场景

假设有一个分布式应用程序,其中多个实例需要更新共享资源(例如数据库)。如果没有适当的同步,这些实例可能会尝试同时更新资源,从而导致不一致。通过使用 ZooKeeper 进行分布式锁定,应用程序可确保每次只有一个实例可以更新资源。

  1. 客户端A 通过创建 ZNode 尝试获取锁/lock。如果成功,客户端 A 会更新共享资源,然后删除 ZNode 并释放锁。
  2. 与此同时,客户端B也尝试获取锁,但发现该/lockZNode已经存在。客户端B在该ZNode上设置监视并等待。
  3. 当客户端 A 释放锁(删除 ZNode)时,ZooKeeper 会通知客户端 B。然后客户端 B 尝试创建 ZNode /lock、获取锁并更新共享资源。

此示例演示了 ZooKeeper 的协调服务如何确保数据一致性并防止分布式环境中的竞争条件。

使用 ZooKeeper 的好处

ZooKeeper 提供了多种优势,使其成为分布式协调的首选:

  1. 高可用性: ZooKeeper 采用基于仲裁的方法,确保只要大多数服务器正常运行,服务就可用。这使其对服务器故障具有很强的弹性。

  2. 一致性: ZooKeeper 保证强一致性,确保所有客户端都看到相同的数据视图。这对于维护分布式系统的完整性至关重要。

  3. **可扩展性:**通过在集合中分发读取请求并使用观察者,ZooKeeper 可以处理大量读取操作,使其适用于大规模应用程序。

  4. 简单性: ZooKeeper 简单的 API 和分层命名空间使其易于使用并集成到现有应用程序中。开发人员可以快速实现协调任务,而无需处理分布式系统的复杂性。

挑战与限制

尽管 ZooKeeper 具有诸多优势,但它也存在一些挑战和局限性:

  1. **写入可扩展性:**由于所有写入请求都通过领导者,因此领导者的容量限制了写入吞吐量。在写入密集型应用程序中,这可能会成为瓶颈。

  2. **延迟:**虽然 ZooKeeper 提供低延迟数据访问,但客户端和集合之间的网络延迟可能会影响性能,尤其是在地理分布式部署中。

  3. **配置的复杂性:**正确配置和管理 ZooKeeper 集合需要深入了解其内部结构。配置错误可能会导致性能问题甚至数据丢失。

  4. 单点故障(领导者): ZooKeeper 集合中的领导者是写入操作的单点故障。虽然集合可以在当前领导者发生故障时选出新的领导者,但有一段短暂的时间无法处理写入操作。

结论

ZooKeeper 是一款强大的分布式协调工具,具有高可用性、强一致性和可扩展性。其简单的 API 和强大的架构使其适用于从配置管理到分布式锁定等各种分布式应用程序。通过了解 ZooKeeper 的关键概念和架构,开发人员可以利用其功能构建可靠、高效的分布式系统。

随着分布式系统的发展,对 ZooKeeper 等可靠协调服务的需求只会增长。通过应对挑战和限制并不断改进其架构,ZooKeeper 将在未来几年继续成为分布式系统的基石。

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

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

相关文章

【Android】Activity子类之间的区别

从底层往顶层的继承顺序依次是: Activity,最原始的Activity androidx.core.app.ComponentActivity,仅仅优化了一个关于KeyEvent的拦截问题,一般不继承这个类 androidx.activity.ComponentActivity,支持和Android Arc…

Spark Join优化案例:Join Key 远大于 Payload

在一个案例中,大表 100GB、小表 10GB,它们全都远超广播变量阈值(默认 10MB)。因为小表的尺寸已经超过 8GB,在大于 8GB 的数据集上创建广播变量,Spark 会直接抛出异常,中断任务执行,所…

C语言 求 n 个数的阶乘之和

求n个数的阶乘之和&#xff08;即求1&#xff01;2&#xff01;3&#xff01;…n!&#xff09; 这个程序读取用户输入的正整数 n&#xff0c;计算并输出 1! 2! 3! ... n! 的值。 #include <stdio.h>// 计算阶乘的函数 long factorial(int num) {long result 1;for…

恢复 IntelliJ IDEA 中消失的菜单栏

要恢复 IntelliJ IDEA 中消失的菜单栏&#xff0c;可以按照以下简单步骤操作&#xff1a; 使用快捷键打开搜索&#xff1a;首先&#xff0c;双击 Shift 键打开全局搜索对话框。 搜索“Menu”&#xff1a;在搜索框中输入 menu&#xff0c;然后从搜索结果中选择与“Main Menu”相…

python-基础篇-选择-是什么

文章目录 定义一&#xff1a;Python 条件语句跟其他语言基本一致的&#xff0c;都是通过一条或多条语句的执行结果&#xff08; True 或者 False &#xff09;来决定执行的代码块。1、什么是条件语句2、if 语句的基本形式3、if 语句多个判断条件的形式4、if 语句多个条件同时判…

次序统计量

内容来源 概率论与数理统计教程&#xff08;第三版&#xff09; 茆诗松 高等教育出版社 数理统计学导论&#xff08;原书第7版&#xff09; 机械工业出版社 定义 设 X 1 , X 2 , ⋯ , X n X_1,X_2,\cdots,X_n X1​,X2​,⋯,Xn​ 是来自连续分布的随机样本 此分布具有 p d f…

【机器学习】Python reversed 函数

目录&#xff1a; reversed()函数初探应用于列表和元组实战演练&#xff1a;山海经故事文本处理 Python中的内置函数——reversed()。 这个函数能够帮助你高效地处理序列类型数据&#xff0c;比如列表、元组、字符串等&#xff0c;通过它你可以轻松地反转这些序列中的元素顺…

JSON 简述与应用

1. JSON 简述 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;常用于客户端与服务器之间的数据传递。它基于JavaScript对象表示法&#xff0c;但独立于语言&#xff0c;可以被多种编程语言解析和生成。 1.1 特点 轻量级&#…

JS对数据类型的检测方式

1. typeof()对于基本数据类型没问题&#xff0c;遇到引用数据类型就不管用 console.log( typeof 666 ); // number console.log( typeof [1,2,3] ); // object 2. instanceof()只能判断引用数据类型&#xff0c;不能判断基本数据类型 console.log( [] instanceof Array ) // tr…

Unity--协程--Coroutine

Unity–协程–Coroutine 1. 协程的基本概念 基本概念:不是线程,将代码按照划分的时间来执行,这个时间可以是具体的多少秒,也可以是物理帧的时间,也可以是一帧的绘制结束的时间。 协程的写法&#xff1a;通过返回IEnumerator的函数实现&#xff0c;使用yield return语句暂停执…

Golang | Leetcode Golang题解之第205题同构字符串

题目&#xff1a; 题解&#xff1a; func isIsomorphic(s, t string) bool {s2t : map[byte]byte{}t2s : map[byte]byte{}for i : range s {x, y : s[i], t[i]if s2t[x] > 0 && s2t[x] ! y || t2s[y] > 0 && t2s[y] ! x {return false}s2t[x] yt2s[y] …

python 查找轮廓

在Python中&#xff0c;查找图像的轮廓通常使用OpenCV库。以下是一个简单的示例代码&#xff0c;展示了如何使用OpenCV来查找并绘制图像的轮廓&#xff1a; pythonimport cv2 import numpy as np# 读取图像 image cv2.imread(your_image.jpg, 0) # 请将your_image.jpg替换为您…

设备树下的 platform 驱动编写

设备树下的 platform 驱动编写 设备树下的 platform 驱动简介 platform 驱动框架分为总线、设备和驱动&#xff0c;其中总线不需要我们这些驱动程序员去管理&#xff0c;这个是 Linux 内核提供的&#xff0c;我们在编写驱动的时候只要关注于设备和驱动的具体实现即可。在没有…

《昇思25天学习打卡营第6天 | 函数式自动微分》

《昇思25天学习打卡营第6天 | 函数式自动微分》 目录 《昇思25天学习打卡营第6天 | 函数式自动微分》函数式自动微分简单的单层线性变换模型函数与计算图微分函数与梯度计算Stop Gradient 函数式自动微分 神经网络的训练主要使用反向传播算法&#xff0c;模型预测值&#xff0…

建站小记:迁移域名DNS到CloudFlare

CloudFlare一直有赛博菩萨之称&#xff0c;据说用它做DNS解析服务又快又好又免费&#xff0c;还能防DDOS攻击&#xff0c;并且可以提供页面访问统计功能。 正好我博客网页打开略卡顿&#xff0c;所以决定将自己的DNS解析迁移到CloudFlare。 1.登录CF控制台&#xff0c;添加自己…

LeetCode-刷题记录-二分法合集(本篇blog会持续更新哦~)

一、二分查找概述 二分查找&#xff08;Binary Search&#xff09;是一种高效的查找算法&#xff0c;适用于有序数组或列表。&#xff08;但其实只要满足二段性&#xff0c;就可以使用二分法&#xff0c;本篇博客后面博主会持续更新一些题&#xff0c;来破除一下人们对“只有有…

(已解决)Adobe Flash Player已不再受支持

文章目录 前言解决方案 前言 一般来说&#xff0c;很少遇到官方网站使用Adobe Flash Player来进行录用名单公示了。但是&#xff0c;今天就偏偏遇到一次&#xff0c; 用谷歌浏览器打不开&#xff0c; 点了没有反应&#xff0c;用其他的浏览器&#xff0c;例如windows自带的那…

Golang | Leetcode Golang题解之第207题课程表

题目&#xff1a; 题解&#xff1a; func canFinish(numCourses int, prerequisites [][]int) bool {var (edges make([][]int, numCourses)indeg make([]int, numCourses)result []int)for _, info : range prerequisites {edges[info[1]] append(edges[info[1]], info[0]…

数据结构:期末考 第六次测试(总复习)

一、 单选题 &#xff08;共50题&#xff0c;100分&#xff09; 1、表长为n的顺序存储的线性表&#xff0c;当在任何位置上插入或删除一个元素的概率相等时&#xff0c;插入一个元素所需移动元素的平均个数为&#xff08; D &#xff09;.&#xff08;2.0&#xff09; A、 &am…

在node环境使用MySQL

什么是Sequelize? Sequelize是一个基于Promise的NodeJS ORM模块 什么是ORM? ORM(Object-Relational-Mapping)是对象关系映射 对象关系映射可以把JS中的类和对象&#xff0c;和数据库中的表和数据进行关系映射。映射之后我们就可以直接通过类和对象来操作数据表和数据了, 就…