基于zookeeper实现分布式配置中心(一)

  

  最近在学习zookeeper,发现zk真的是一个优秀的中间件。在分布式环境下,可以高效解决数据管理问题。在学习的过程中,要深入zk的工作原理,并根据其特性做一些简单的分布式环境下数据管理工具。本文首先对zk的工作原理和相关概念做一下介绍,然后带大家做一个简单的分布式配置中心。

zookeeper介绍

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

zookeeper使用

查看节点

  # ls /path

创建节点

  #create /path data

修改节点

  #set /path data

删除节点

  #delete /path

获取节点数据

  #get /path

zookeeper C/S连接状态

  1)KeeperState.Expired:客户端和服务器在ticktime的时间周期内,是要发送心跳通知的。这是租约协议的一个实现。客户端发送request,告诉服务器其上一个租约时间,服务器收到这个请求后,告诉客户端其下一个租约时间是哪个时间点。当客户端时间戳达到最后一个租约时间,而没有收到服务器发来的任何新租约时间,即认为自己下线(此后客户端会废弃这次连接,并试图重新建立连接)。这个过期状态就是Expired状态

  2)KeeperState.Disconnected:就像上面那个状态所述,当客户端断开一个连接(可能是租约期满,也可能是客户端主动断开)这是客户端和服务器的连接就是Disconnected状态

  3)KeeperState.SyncConnected:一旦客户端和服务器的某一个节点建立连接(注意,虽然集群有多个节点,但是客户端一次连接到一个节点就行了),并完成一次version、zxid的同步,这时的客户端和服务器的连接状态就是SyncConnected

  4)KeeperState.AuthFailed:ookeeper客户端进行连接认证失败时,发生该状态

zookeeper工作原理

  文件系统 + 监听机制

文件系统特点

  同一个目录下文件名称不能重复,同样zookeeper也是这样的,zookeeper中统一叫作znode。znode节点可以包含子znode,也可以同时包含数据。znode只适合存储非常小的数据,不能超过1M,最好都小于1K。

znode节点类型

  临时节点(EPHEMERAL):客户端关闭zk连接后清除

  永久节点(persistent):持久化节点,除非客户端主动删除

  有编号节点(Persistent_sequential):自动增加顺序编号的znode持久化节点

  临时有编号(Ephemral_ sequential):临时自动编号设置,znode节点编号会自动增加,但是会客户端连接断开而消失。分布式锁用的是这个类型的节点。

  注:EPHEMERAL 临时类型的节点不能有子节点,对于zk来说,有几个节点数据就会存储几份。

监听机制

  客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目录节 点增加删除)时,zookeeper会通知客户端。

  

  1、客户端启动时向zookeeper服务器注册信息

  2、客户端启动同时注册一系列的Watcher类型的监听器到本地的WatchManager中

  3、zookeeper服务器中节点发生变化后,触发watcher事件后通知给客户端,客户端线程从WatcherManager中取出对应的Watcher对象来执行回调逻辑。

zookeeper监听的事件类型

  EventType.NodeCreated:当znode节点被创建时,该事件被触发。

  EventType.NodeChildrenChanged:当znode节点的直接子节点被创建、被删除、子节点数据发生变更时,该事件被触发。

  EventType.NodeDataChanged:当znode节点的数据发生变更时,该事件被触发。

  EventType.NodeDeleted:当znode节点被删除时,该事件被触发。

  EventType.None:当zookeeper客户端的连接状态发生变更时,即KeeperState.Expired、KeeperState.Disconnected、KeeperState.SyncConnected、KeeperState.AuthFailed状态切换时,描述的事件类型为EventType.None。

zookeeper下server工作状态

  LOOKING:当前server不知道leader是谁,正在选举

  LEADING:当前server即为选举出来的leader

  FOLLOWING:leader已经选举出来,当前server是follower

 ZAB协议

  ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。
  ZAB 协议作用:解决分布式数据管理一致性。
  ZAB 协议定义:ZAB 协议是为分布式协调服务 Zookeeper 专门设计的一种支持 崩溃恢复 和 消息广播 协议。
  基于该协议,Zookeeper 实现了一种 主备模式 的系统架构来保持集群中各个副本之间数据一致性。

消息广播

  zookeeper集群采用主从(leader-follower)模式保证服务高可用。leader节点可读可写,follower节点只读,这种模式就需要保证leader节点和follower节点的数据一致性。对于客户端发送的写请求,全部由 Leader 接收,Leader 将请求封装成一个事务 Proposal,将其发送给所有 Follwer ,然后,根据所有 Follwer 的反馈,如果超过半数成功响应,则执行 commit 操作(先提交自己,再发送 commit 给所有 Follwer)。

  注:上述中有一个概念:两阶段提交过程(分布式系统中数据一致性经常会涉及到的方案)。follower节点是可以处理写请求的,会转发给leader节点。leader节点通过消息广播(二阶段提交)同步写操作到follower节点,保证数据一致性。

  zookeeper中每个事务都对应一个ZXID(全局的、唯一的、顺序的)。ZXID 是一个 64 位的数字,其中低 32 位可以看作是一个简单的递增的计数器,针对客户端的每一个事务请求,Leader 都会产生一个新的事务 Proposal 并对该计数器进行 + 1 操作。而高 32 位则代表了 Leader 服务器上取出本地日志中最大事务 Proposal 的 ZXID,并从该 ZXID 中解析出对应的 epoch 值,然后再对这个值加一。

崩溃恢复

  即如果在消息广播的过程中,leader死掉了,如何保证数据的一致性问题。

  假设两种异常情况:
  1、一个事务在 Leader 上提交了,并且过半的 Folower 都响应 Ack 了,但是 Leader 在 Commit 消息发出之前挂了。
  2、假设一个事务在 Leader 提出之后,Leader 挂了。

  考虑到上述两种异常情况,Zab 协议崩溃恢复要求满足以下两个要求:
  1)确保已经被 Leader 提交的 Proposal 必须最终被所有的 Follower 服务器提交。
  2)确保丢弃已经被 Leader 提出的但是没有被提交的 Proposal。

  崩溃恢复主要包含:leader选举 和 数据恢复。

  leader选举:

  1、要求 可用节点数量 > 总节点数量/2  。注意 是 > , 不是 ≥。

     2、新选举出来的 Leader 不能包含未提交的 Proposal(新选举的 Leader 必须都是已经提交了 Proposal 的 Follower 服务器节点) 、新选举的 Leader 节点中含有最大的 zxid(可以避免 Leader 服务器检查 Proposal 的提交和丢弃工作。如果zxid相同,选择server_id【zoo.cfg中的myid】最大的。)

  数据恢复

  1、上面讲过了ZXID的高 32 位代表了每代 Leader 的唯一性,低 32 代表了每代 Leader 中事务的唯一性。同时,也能让 Follwer 通过高 32 位识别不同的 Leader。简化了数据恢复流程。

  2、基于这样的策略:当 Follower 链接上 Leader 之后,Leader 服务器会根据自己服务器上最后被提交的 ZXID 和 Follower 上的 ZXID 进行比对,比对结果要么回滚,要么和 Leader 同步。

zookeeper集群脑裂

  集群的脑裂通常是发生在节点之间通信不可达的情况下,集群会分裂成不同的小集群,小集群各自选出自己的master节点,导致原有的集群出现多个master节点的情况。

zookeeper集群节点数(奇数or偶数?)

  只要我们清楚集群leader选举的要求(可用节点数量 > 总节点数量/2  。注意 是 > , 不是 ≥),我相信很容易明白奇数节点集群相比偶数节点的集群有更大的优势。

  1、发生脑裂(分成2个小集群)的情况下,奇数节点的集群总会有一个小集群满足可用节点数量 > 总节点数量/2,所以zookeeper集群总能选取出leader。

  2、在容错能力相同的情况下,奇数集群更节省资源。还是要清楚leader选举的要求哈,举个列子:3个节点的集群,如果集群可以正常工作(即leader选举成功),至少需要2个节点是正常的;4个节点的集群,如果集群可以正常工作(即leader选举成功),至少需要3个节点是正常的。那么3个节点的集群和4个节点的集群都有一个节点宕机的容错能力。很明显,在容错能力相同的情况下,奇数节点的集群更节省资源。

 zookeeper和eureka对比

  在分布式系统领域有个著名的 CAP定理(C- 数据一致性;A-服务可用性;P-服务对网络分区故障的容错性,这三个特性在任何分布式系统中不能同时满足,最多同时满足两个)。

  zookeeper基于CP,即任何时刻对ZooKeeper的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性;但是它不能保证每次服务请求的可用性(注:也就 是在极端环境下,zookeeper可能会丢弃一些请求,消费者程序需要重新请求才能获得结果)。至于zookeeper为啥不能保证服务的高可用,大家可以想一下发生脑裂后无法选取leader、选取leader过程中丢弃某些请求。当网络出现故障时,剩余zk集群server会发起投票选举新的leader,但是此过程会持续30~120s,此过程对于高并发来说十分漫长,会导致整个注册服务的瘫痪,这是不可容忍的。 

  Eureka基于AP,不会有类似于ZooKeeper的选举leader的过程,采用的是Peer to Peer 对等通信,没有leader/follower的说法,每个peer都是对等的;客户端请求会自动切换 到新的Eureka节点;当宕机的服务器重新恢复后,Eureka会再次将其纳入到服务器集群管理之中。当Eureka节点接受客户端请求时,所有的操作都会在节点间进行复制(replicate To Peer)操作,将请求复制到该 Eureka Server 当前所知的其它所有节点中。至于为啥Eureka不能保证数据一致性,源于Eureka的自我保护机制:如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况: 

  1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务 。

  2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用) 。

  3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中。

  因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。

总结

  以上是对zookeeper的工作原理和相关概念的一些整理,希望能对大家认识zookeeper有所帮助。下一篇文章开始基于zookeeper做一个简单的分布式配置中心,敬请期待!!!

参考链接

  https://blog.csdn.net/pml18710973036/article/details/64121522

  https://www.cnblogs.com/stateis0/p/9062133.html

  https://www.jianshu.com/p/2bceacd60b8a

  

  

 

转载于:https://www.cnblogs.com/hujunzheng/p/10887937.html

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

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

相关文章

基于zookeeper实现分布式配置中心(二)

上一篇(基于zookeeper实现分布式配置中心(一))讲述了zookeeper相关概念和工作原理。接下来根据zookeeper的特性,简单实现一个分布式配置中心。 配置中心的优势 1、各环境配置集中管理。 2、配置更改,实时推…

Redis分布式锁实战

背景 目前开发过程中,按照公司规范,需要依赖框架中的缓存组件。不得不说,做组件的大牛对CRUD操作的封装,连接池、缓存路由、缓存安全性的管控都处理的无可挑剔。但是有一个小问题,该组件没有对分布式锁做实现&#xff…

基于RobotFramework实现自动化测试

Java robotframework seleniumlibrary 使用Robot Framework Maven Plugin(http://robotframework.org/MavenPlugin/)执行自动化测试chromedriver下载: http://chromedriver.storage.googleapis.com/index.htmlchromedriver和chrome版本对应…

Springboot国际化信息(i18n)解析

国际化信息理解 国际化信息也称为本地化信息 。 Java 通过 java.util.Locale 类来表示本地化对象,它通过 “语言类型” 和 “国家/地区” 来创建一个确定的本地化对象 。举个例子吧,比如在发送一个具体的请求的时候,在header中设置一个键值对…

C语言一看就能上手的干货!你确定你不来看吗?

本地环境设置 如果您想要设置 C 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C 编译器。 文本编辑器 这将用于输入您的程序。文本编辑器包括 Windows Notepad、OS Edit command、Brief、Epsilon、EMACS 和 vim/vi。文本编辑器的名称…

10万码农五年的C语言笔记!你现在知道别人为什么这么优秀了吗?

c语言对许多同学来说确实是一门比较难学的课程,不仅抽象,而且繁琐,但这又是一门不得不学的课程。前两节可能还有兴致听一听,然而,再过几节课就是一脸蒙比。凭空要想出一道题的算法和程序,根本无从下手。 所…

C语言/C++编程学习:C语言环境设置!

C语言是面向过程的,而C++是面向对象的 C和C的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得…

C语言指针原来也可以这么的通俗易懂!

C语言是面向过程的,而C++是面向对象的 C和C的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得…

C语言过时了?你在做梦?

为什么要使用C语言? 在过去的四十年里,C语言已经成为世界上最流行、最重要的一种编程语言。 C是一种融合了控制特性的现代语言,而我们已发现在计算机科学的理论和实践中,控制特性是很重要的。其设计使得用户可以自然地采用自顶向…

C语言深入理解!助你向大佬迈进!

Dennis Ritchie 过世了,他发明了C语言,一个影响深远并彻底改变世界的计算机语言。一门经历40多年的到今天还长盛不衰的语言,今天很多语言都受到C的影响,C,Java,C#,Perl, PHP&#xf…

【初涉C语言】程序员欢迎来到C语言的世界!

计算机发展史 机器语言所有的代码里面只有0和1优点:直接对硬件产生作用,程序的执行效率非常高缺点:指令又多又难记、可读性差、无可移植性汇编语言符号化的机器语言,用一个符号(英文单词、数字)来代表一条…

C语言和C++的区别整理详解!

c和c主要区别 根据书中的描述,进行了整理 推荐一个我自己的C/C交流裙815393895 1、 源代码文件的扩展名 摘自1.4.1 C实现源代码文件的扩展名UNIXC、cc、cxx、cGNU CC、cc、cxx、cpp、cDigital Marscpp、cxxBorland CcppWatcomcppMicrosoft Visual Ccpp、cxx、cc…

揭示C语言函数调用的本质解析

C语言是面向过程的,而C++是面向对象的C和C的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到…

C语言/C++编程学习:不找C/C++的工作也要学C/C++的原因

C语言是面向过程的,而C++是面向对象的 C和C的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得…

【网络攻防】精通C语言的黑客才是真正的黑客!

精通C语言的黑客才是真正的黑客 黑客界,有两样重要的课程,一是计算机的本质,二是编译原理。相对于汇编等底层语言,它简单;相对于其它高级语言,它更为接近计算机;同样它对黑客的两大课程很有帮助…

我两小时学完指针,你学会数组/指针与函数需要多久?

数组与函数: 这段函数中 函数的参数是数组,注意数组作为函数参数时,数组名和数组元素个数时分别传递的。 指针与函数: 这段函数中的参数是指针变量,传入的是数组的数组名或者首元素的地址,然后用引领操作…

C语言发展历史,C语言特点,C语言利于弊,入门须知三招

C语言是面向过程的,而C++是面向对象的 这些是C/C能做的 服务器开发工程师、人工智能、云计算工程师、信息安全(黑客反黑客)、大数据 、数据平台、嵌入式工程师、流媒体服务器、数据控解、图像处理、音频视频开发工程…

程序员怎么看待C语言?最伟大?最落后?

一,前言 对我来说,C语言应该可以算得上是世界上最伟大的编程语言。全中国口气最大的程序员,业界称之为“垠神”,曾经发过文章吐槽过业界各种主流的编程语言(对Java,的Python稍微宽容一些)&…

如何学习C语言?就是这么简单粗暴!

C语言是面向过程的,而C++是面向对象的。 C和C的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理…

C/C++对编程的重要性!其他编程语言都是弟弟!

C语言是面向过程的,而C++是面向对象的 C和C的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得…