3.Apache ZooKeeper数据模型

1. ZooKeeper自下向上的服务视图

Apache ZooKeeper是分布式应用程序的协调服务。 它旨在解决分布式应用程序中与组件协调相关的棘手问题。 它通过暴露一个简单而强大的接口来实现这一点。 应用程序可以设计在通过ZooKeeper API实现的这些接口上,以解决分布式同步,集群配置管理,组成员身份等问题。

ZooKeeper本身就是一个复制和分布式应用程序,其目的作为服务运行,类似于我们运行DNS或任何其他集中式服务的方式。 ZooKeeper服务的视图如下图所示:
ZooKeeper服务以及客户端如何连接到服务

从之前的图(该图从http://zookeeper.apache.org/doc/r3.4.6/zookeeperOver.html上能够找到),将看到运行ZooKeeper服务的复制服务器集,被称为ensemble。 客户可以通过连接到集合的任何成员来连接到ZooKeeper服务。 你可以发送和接收请求和响应,以及客户端和服务之间的事件通知,这些都是通过维护TCP连接并定期发送心跳来完成的。

Note
ensemble中的成员知道彼此的状态。 这意味着当前的内存中状态,事务日志以及服务状态的时间点副本通过构成整体的各个主机以持久的方式存储在本地数据存储中。 ZooKeeper是一个高度可用的服务,所以只要大部分服务器都可用,服务将始终可用。

ZooKeeper对事务进行了严格的排序,从而实现了简单可靠的高级分布式同步原语。 凭借其强大,可靠,高性能和快速的设计,该协调服务使其可用于大型复杂的分布式应用程序。

2. ZooKeeper数据模型

根据ZooKeeper wiki的定义,ZooKeeper允许分布式进程通过数据寄存器的共享分层命名空间相互协调。命名空间看起来非常类似于Unix文件系统。 数据寄存器在ZooKeeper命名中被称为znode。 可以在下面的图片中看到znodes的例子:
一个ZooKeeper的分层命名空间

在这里,可以看到znode是一个标准的文件系统,层次结构很像一棵树。 需要注意的一些要点如下:

  • 根节点有一个名为/zoo的子节点,它又有三个znode。
  • ZooKeeper树中的每个znode都由一个路径标识,路径元素由『/』分隔。
  • 这些节点被称为数据寄存器,因为它们可以存储数据。 因此,一个znode可以有子节点以及与之相关的数据。 这与文件系统可以把文件作为路径很类似。

znode中的数据通常以字节格式存储,每个znode中的最大数据大小不超过1 MB。 ZooKeeper是为协调而设计的,几乎所有形式的协调数据都比较小, 因此,对数据大小的限制是强制的。 建议实际的数据大小也要小于这个限制。

斜杠分隔的znode路径是规范的,必须是绝对路径。 相对路径和引用不被ZooKeeper识别。 znode名称可以由Unicode字符组成并且znode可以具有任何名称。 这个例外是ZooKeeper这个词是保留的。 最重要的是,使用“.” 作为一个路径组件是非法的。

与文件系统中的文件一样,znode维护一个stat结构,其中包含数据更改的版本号以及随更改相关的时间戳而更改的访问控制列表。 只要znode的数据发生变化,版本号就会增加。 ZooKeeper使用版本号以及相关的时间戳来验证它的核心内缓存。 znode版本号还允许客户端通过ZooKeeper API更新或删除特定的znode。 如果指定的版本号与znode的当前版本不匹配,则操作失败。 但是,执行znode更新或删除操作时,可以通过指定0作为版本号来覆盖。

(1) znode的类型

ZooKeeper有两种类型的znode:persistent和ephemeral。 可能已经听说过第三种类型,称为sequential的znode,这是另一种类型的限定符。 persistent和ephemeral的znode也可以是sequential的znode。 请注意,znode的类型是在创建时设置的。

(2) persistent类型的znode

顾名思义,persistent的znode在ZooKeeper的命名空间中有一个生命周期,直到它们被明确的删除。 一个znode可以通过调用delete API调用来删除。 没有必要只有创建持久化znode的客户端才能删除它。 请注意,任何ZooKeeper服务的授权客户端都可以删除一个znode。

现在使用ZooKeeper Java shell创建一个持久化的znode:

[zk: localhost(CONNECTED) 1] create /[PacktPub] "ApacheZooKeeper"
Created /[PacktPub]
[zk: localhost(CONNECTED) 2] get /[PacktPub]
"ApacheZooKeeper"

persistent的znodes对于存储需要高度可用且可由分布式应用程序的所有组件访问的数据时非常有用。 例如,应用程序可以将配置数据存储在持久的znode中。 即使创建者客户端死亡,数据以及znode也会存在。

(3) ephemeral类型的znode

相比之下,当创建客户端的会话结束时,ZooKeeper服务会删除一个ephemeral的znode。 客户端会话的结束可能由于客户端崩溃或连接的明确终止而发生断开连接。 尽管临时节点与客户端会话绑定,但它们对所有客户端均可见,具体取决于配置的访问控制列表(ACL)策略。

创建者客户端或任何其他授权客户端也可以通过使用删除API调用来显式删除ephemeral 的znode。 一旦其创建者客户端与ZooKeeper服务的会话结束,ephemeral 的znode就不复存在。 因此,在当前版本的ZooKeeper中,短暂的znodes不允许有子节点。

要使用ZooKeeper Java Shell创建一个ephemeral的znode,必须在create命令中指定-e标志,可以使用以下命令完成:

[zk: localhost(CONNECTED) 1] create -e /[PacktPub] "ApacheZooKeeper"
Created /[PacktPub]

现在,由于一个ephemeral的znode不允许有子节点,如果我们试图创建一个刚刚创建的子节点znode时,会被抛出一个错误,如下所示:

[zk: localhost(CONNECTED) 2] create -e /[PacktPub]/EphemeralChild "ChildOfEphemeralZnode"
Ephemerals cannot have children: /[PacktPub]/EphemeralChild

ephemeral的节点的用途可用于构建分布式应用程序,其中组件需要知道其他组件或资源的状态。 例如,分布式组成员资格服务可以通过使用ephemera 的znode来实现。 当创建者客户端会话结束时,ephemeral节点被删除的属性可用作加入或离开分布式集群的节点的模拟。 使用会员服务,任何节点都能够在任何特定的时间发现组的成员。

(4)sequential类型的znode

一个sequential的znode在ZooKeeper创建它的时候,分配一个序列号作为其名字的一部分。 一个单调递增的计数器(由父znode维护)的值被附加到znode的名称上。

计数器是一个有符号整数类型(4个字节),用来存储序号的。 它一共10位的格式,前面填充0。 例如,/path/to/znode-0000000001。 这个命名约定对分配给它们的值对sequential的znode进行排序很有用。

Note
sequential的节点可以用于实现分布式全局队列,因为顺序号可以强制一个全局顺序。 它们也可以用来为分布式应用程序设计一个锁定服务。

由于persistent和ephemeral的znode都可以是sequential类型的znode,因此总共有四种znode模式:

  • persistent
  • ephemeral
  • persistent_sequential
  • ephemeral_sequential

使用ZooKeeper Java shell创建一个sequential的znode,我们必须使用create命令的-s标志:

[zk: localhost(CONNECTED) 1] create -s /[PacktPub] "PersistentSequentialZnode"
Created /[PacktPub]0000000001
[zk: localhost(CONNECTED) 3] create -s -e /[PacktPub] "EphemeralSequentialZnode"
Created /[PacktPub]0000000008

(5) 关注znode变化 —— ZooKeeper 监视

对于大型分布式应用程序,ZooKeeper的设计是一种可伸缩的、健壮的集中式服务。在客户端访问此类服务时,常见的设计反模式是通过轮询或拉式(pull)模型。当在大型和复杂的分布式系统中实现时,拉模型常常会受到可伸缩性问题的影响。为了解决这个问题,ZooKeeper设计了一种机制,客户端可以从ZooKeeper服务中获取通知,而不是轮询事件。这类似于一个推(push)模型,在这个模型中,通知被推送到ZooKeeper服务的注册客户端。

客户可以使用ZooKeeper服务注册与znode相关的任何更改。 这种注册被称为在ZooKeeper术语中的znode上设置监视(watch)。 监视允许客户以任何方式更改znode时收到通知。 监视是一次性操作,这意味着它只触发一个通知。 要继续接收通知,客户必须在收到每个事件通知后重新注册一个监视。

让我们通过一个集群组成员模型的例子来说明ZooKeeper监视和通知的概念:

  • 在群集中,一个节点(例如Client1)在另一个节点加入群集时收到通知。 任何加入群集的节点都会在ZooKeeper路径/Members下创建一个ephemeral节点。
  • 现在,另一个节点Client2加入群集,并在/Members下创建一个名为Host2的ephemeral节点。
  • Client1在ZooKeeper路径/Members上发出一个getChildren请求,并设置一个任何改动的监视。 当Client2创建一个znode作为/Members/Host2时,监视被触发,Client1收到来自ZooKeeper服务的通知。 如果Client1现在在ZooKeeper路径/Members上发出getChildren请求,它将看到新的Host2的znode。 以下图片显示了监视设置的流程,以及监视的通知和后续重置:
    两个客户端和ZooKeeper之间的关系是如何通过监视和通知进行工作的

ZooKeeper监视是一次性触发器。 这意味着如果一个客户端收到一个监视事件并想要得到未来变化的通知,那么它必须设置另一个监视。 每当监视被触发时,就会将一个通知分派给已经设置监视的客户端。 监视在维护与客户端连接的ZooKeeper服务器上,这使得它成为事件通知的快速和精益的方式。

监视触发以下三个变化到一个znode:

  1. 对znode数据的任何更改,例如使用setData操作将新数据写入znode的数据字段时。
  2. 对znode的子节点的任何更改。 例如,一个znode的子节点被删除。
  3. 正在创建或删除的znode,如果将新的znode添加到路径中或现有的znode被删除,则可能发生这种情况。

同样,ZooKeeper针对监视和通知声明以下保证:

  • ZooKeeper确保监视始终以先进先出(FIFO)方式排序,并且通知总是按顺序发送
  • 在对同一个znode进行任何其他更改之前,监视会将通知发送给客户端
  • 监视事件的顺序是按照ZooKeeper服务的更新顺序排列的。

Note
由于ZooKeeper的监视是一次性触发的,由于在获取监视事件和重新设置监视之间存在延迟,所以客户端可能会在此期间丢失对znode的更改。在分布式应用程序中,一个znode在事件的调度和对事件的重新设置之间进行多次更改,开发人员必须小心处理应用程序逻辑中的这种情况。

当客户端与ZooKeeper服务器断开连接时,在连接重新建立之前,它不会收到任何监视。 如果客户重新连接,任何以前注册的监视也将被重新注册并触发。 如果客户端连接到一个新的服务器,监视将会触发任何会话事件。 从服务器断开连接并重新连接到新服务器对于客户端应用程序而言是透明的。

虽然ZooKeeper保证所有已注册的监视都被分派到客户端,但即使客户端从一台服务器断开连接并重新连接到ZooKeeper服务中的另一台服务器,也有一种可能的情况值得一提,即客户可能会错过一个监视。 这个特定的场景是,当客户端已经设置了一个尚未创建的znode的存在。 在这种情况下,在客户端处于断开状态创建和删除znode时,监视就会丢失。

转载于:https://www.cnblogs.com/IcanFixIt/p/7818592.html

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

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

相关文章

STS插件_ springsource-tool-suite插件各个历史版本

目前spring官网(http://spring.io/tools/sts/all)上可下载的spring插件只有:springsource-tool-suite-3.8.4(sts-3.8.4)。但这只针对指定的eclipse版本适用。 原贴更精彩:http://blog.csdn.net/u010203767/article/details/69211072 sts-3.8.3的下载地址…

c语言中空格的占位符,HTML空格占位符

ScrollView 里的 EditText 与输入法的用例情景是这样的: 我希望页面可以滚动,因为长页面,内容多,必须滚动来满足不同手机的显示 点击 EditText 输入法弹出来,并将布局顶起来,并且EditText有足够的显示空间 进入页面时,输入法不能 ...decltype在C中,decltype作为操作符,用于查询…

仔细看看,您会发现需要改进的地方

我建议您做一个练习:明天早上返回工作时,浏览项目的源代码,并尝试寻找重构的机会。 即使您的老板不要求也这样做。 这样做是因为您想要一些激动人心的工作时间。 重构是改变已经可以正常工作的艺术 。 但是要进行重构,您需要一个…

idea运行项目时报Error:java无效的源发行版:1.8

如果你安装的是JDK1.7,而在file->project structure中设置的是language level是8的话,就会出现这个错误提示:无效的源发行版:8。 解决办法:将语言级别改为7,或6。即语言级别不能高于你安装的版本。 另外…

0x123C语言,and esp, 0xfffffff0

问题I dont entirely understand the line with comment in it below. I read a few posts on SO and in the gcc manual and learned that it is for stack address alignment but fail to understand how it does so. The code is show below:(gdb) disas mainDump of assemb…

JUnit:在参数化测试中命名单个测试用例

几年前,我写了有关JUnit参数化测试的文章 。 我不喜欢它们的一件事是JUnit使用数字命名了单个测试用例,因此,如果它们失败,您将不知道是哪个测试参数导致了失败。 以下Eclipse屏幕快照将向您展示我的意思: 但是&#…

如何在 React Native 中写一个自定义模块

前言 在 React Native 项目中可以看到 node_modules 文件夹,这是存放 node 模块的地方,Node.js 的包管理器 npm 是全球最大的开源库生态系统。提到npm,一般指两层含义:一是 Node.js 开放式模块登记和管理系统,另一种是…

小程序canvasu真机上数据图片不能使用

canvas遇到的坑 1.文字换行 2.真机不能使用网络数据图片(真坑) 点击显示效果我就不写了,你们可以自己加一下 全部代码贴出来 css#preview {width: 100%;height: 100%;background: rgba(0, 0, 0, 0.6);position: fixed;z-index: 999;top: 0;ov…

c语言 两条线段位置,C++/STL实现判断平面内两条线段的位置关系代码示例

概念平面内两条线段位置关系的判定在很多领域都有着广泛的应用,比如游戏、CAD、图形处理等,而两线段交点的求解又是该算法中重要的一环。本文将尽可能用通俗的语言详细的描述一种主流且性能较高的判定算法。外积,又称叉积,是向量代…

Thunder团队Beta周贡献分规则

小组名称:Thunder 项目名称:i阅app 组长:王航 成员:李传康、翟宇豪、邹双黛、苗威、宋雨、胡佑蓉、杨梓瑞 分配规则 规则1:基础分,拿出总分的20%(8分)进行均分,剩下的80%…

SiftingAppender:将不同的线程记录到不同的日志文件中

Logback的一项新颖功能是SiftingAppender &#xff08; JavaDoc &#xff09;。 简而言之&#xff0c;它是一个代理附加器&#xff0c;它为给定运行时属性的每个唯一值创建一个子附加器。 通常&#xff0c;此属性来自MDC 。 这是基于上面链接的官方文档的示例&#xff1a; <…

gulp webpack整合

为什么需要前端工程化&#xff1f; 前端工程化的意义在于让前端这个行业由野蛮时代进化为正规军时代&#xff0c;近年来很多相关的工具和概念诞生。好奇心日报在进行前端工程化的过程中&#xff0c;主要的挑战在于解决如下问题&#xff1a;✦ 如何管理多个项目的前端代码&…

SpringBoot 入门第一章

一、前言 Spring Boot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。 本系列以快速入门为主&#xff0c;可当作工具小手册阅…

C语言游戏传递小秘密,C语言的那些小秘密之链表

大多数的读者在学习编程语言的时候都不喜欢那些枯燥的文字描述&#xff0c;包括我自己在开始学习编程的时候也是这样&#xff0c;对于代码的热情远远高于文字&#xff0c;所以我在我写东西的时候也不喜欢用枯燥的文字描述来向读者讲解&#xff0c;更喜欢用代码加上适当的文字描…

【转】 VC++6.0 在Win7 64位下调试,Shift+F5无法退出

Win7 64位VC6.0调试代码无法关闭窗口解决方法  VC6.0 在64位Windows7下调试的时候&#xff0c;再结束调试&#xff0c;程序无法退出&#xff0c;只能关闭VC6.0 IDE环境。  问题描述&#xff1a;当我击F5开始一个项目的调试时&#xff0c;程序在我设置的断点处停止&#xff…

使用Infinispan创建自己的Drools和jBPM持久性

我 在这里发表的原始文章&#xff1a; 您好&#xff0c;欢迎来到我打算向您展示如何创建自己的Drools和jBPM持久性实现的帖子。 我已经为流口水对象开发了基于infinispan的持久性方案&#xff0c;并且在此过程中学到了很多东西。 如果您想做某种事情&#xff0c;我打算给您一些…

Html5 填表 表单(二) input type 各种输入, 各种用户选择,上传等等泛输入用户交互

<input> 无限制输入 type 限制输入 type 如下类型 type 后还可以跟一些属性: 如<input typetext maxlength 10> 限制文本的长度为10字节 list 可以用的时候再来查, list就是当一个建议值不够的时候添加到几个. <form> <input typ…

c语言 输出音频 单片机,单片机播放WAV格式音频的理解

CSDN账号注册了3年&#xff0c;一直没有上来过&#xff0c;更不用说写博客了。我不知道博客的具体用途&#xff0c;我只想把它当做一种心得来发表&#xff0c;可能是一些技术上的理解或者生活上的小故事。好了&#xff0c;下面我将记录我对WAV播放器的理解。很久以前就看到过某…

UVALive3989 Ladies' Choice —— 稳定婚姻问题 Gale - Shapely算法

题目链接&#xff1a;https://vjudge.net/problem/UVALive-3989 题解&#xff1a; 题意&#xff1a;有n个男生和n个女生。每个女生对男神都有个好感度排行&#xff0c;同时每个男生对每个女生也有一个好感度排行。问&#xff1a;怎样配对&#xff0c;才能使的每个女生尽可能幸福…

通过命令行界面使用AWS ElasticMapReduce

在本文中&#xff0c;我将通过针对EMR的CLI使用AWS MapReduce服务&#xff08;称为ElasticMapReduce &#xff09;。 使用EMR的过程可以大致分为三个步骤&#xff1a; 设置并填充S3存储桶 创建并运行EMR作业 从S3存储桶中获取结果 在开始这三个高级步骤之前&#xff0c;还…