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的下载地址…

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

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

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

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

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

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

gulp webpack整合

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

SpringBoot 入门第一章

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

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

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

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

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

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;还…

[UE4]关卡蓝图

转载于:https://www.cnblogs.com/timy/p/9053876.html

iframe的缺点

一、iframe会阻塞主页面的onload事件&#xff1b; 二、搜索引擎检索程序无法解读这种页面&#xff0c;不利于SEO&#xff1b; 三、会影响页面的并行加载。 并行加载&#xff1a;同一时间对同一域名下的加载数量是有限制的&#xff1a; 解决方法&#xff1a; 使用js动态给ifr…

使用可视化工具redisclient连接redis

可视化工具推荐&#xff1a;http://database.51cto.com/art/201505/477692.htm 1.连接redis服务端 1.1 设置连接密码&#xff1a;在redis根目录下&#xff0c;双击redis-cli.exe&#xff0c; 输入命令&#xff1a;redis-cli.exe -h 127.0.0.1 -p 6379 -n 1 1就是密码 1.2 使…

android 蓝牙项目代码,Android蓝牙聊天开源项目

前言基于Android Classic Bluetooth的蓝牙聊天软件&#xff0c;目前仅支持一对一实时通信、文件传输、好友添加、好友分组、好友在线状态更新等功能&#xff0c;其中消息发送支持文本、表情等方式。前景蓝牙技术作为一种小范围无线连接技术&#xff0c;能够在设备间实现方便快捷…

你必须知道的.NET之特性和属性(转)

你必须知道的.NET之特性和属性2008-10-13 来源&#xff1a;网络 1. 引言 attribute是.NET框架引入的有一技术亮点&#xff0c;因此我们有必要花点时间走进一个发现attribute登堂入室的入口。因为.NET Framework中使用了大量的定制特性来完成代码约定&#xff0c;[Serializable]…

宽带阻抗匹配的工程实现-第一步,端口驻波仿真

概要 ADS仿真&#xff0c;Matlab仿真&#xff0c;宽带阻抗匹配&#xff0c;smith圆图。 其实阻抗匹配我工作以来经常说&#xff0c;也经常做&#xff0c;但是基本上都是直接在印制板上进行调试。现在想先用仿真软件直接设计出来&#xff0c;才发现很多东西嘴上说容易&#xf…

学web前端一定要这样学,不然学完找不到工作哭都来不及!

因为工作原因&#xff0c;经常关注有关互联网行业的最新动态。这不&#xff0c;刚送走了高考&#xff0c;又迎来了每年的毕业季&#xff0c;看到好多人都说今年的前端工作不好找&#xff0c;很多童鞋简历投了一大堆&#xff0c;也没有回应&#xff0c;发现连实习的机会都没有&a…

android视频通信和web端,探讨用webrtc在手机和浏览器之间实现音视频实时通信的实施环境...

探讨用webrtc在手机和浏览器之间实现音视频实时通信的实施环境Walker.Xuproduct/develop flow&#xff1a;技术需求&#xff1a;任务拆解:1.android客户端2.前端js网页客户端技术产品&#xff1a;落地&#xff0c;实施在实际应用环境中1.技术因素2.非技术因素选择浏览器的标准&…