Zookeeper

  • Post author:
  • Post category:其他


Zookeeper

前言

前段时间,被问到过Zookeeper的相关问题,蛋挞一筹莫展,所以在工作之余整理了Zookeeper的一些基本知识已作知识储备的提升。下面是个人在学习Zookeeper过程中整理的思维导图,此篇基础也是围绕这个思维导图展开的。许多概念性整理大多来自书籍和网络,在这里感谢许多大神博主的分享。

Zookeeper
标题

什么是Zookeeper

官宣概念:Zookeeper是一个高性能,分布式的,开源分布式应用协调服务。它提供了简单原始的功能,分布式应用可以基于它实现更高级的服务(如Dubbo基于Zookeeper),比如,配置管理,集群管理,命名空间。它被设计为易于编程,使用文件系统目录树作为数据模型。服在端跑在java上,提供java和C的客户端API。

我个人通常会通俗的理解成节点管理器。

Zookeeper的特点

  1. 最终一致性:client不论连接到哪个Server,展示给它都是同一个视图。

  2. 可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受。

  3. 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。

  4. 等待无关:慢的或者失效的client不得干预快速的client的请求,使得每个 client都能有效的等待。

  5. 原子性:更新只有成功或者失败,没有中间状态。

  6. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。

Zookeeper的作用

命名服务

在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体通常可以是集群中的机器,提供的服务地址,远程对象等等——这些我们都可以统称他们为名字(Name)。其中较为常见的就是一些分布式服务框架中的服务地址列表。通过调用ZK提供的创建节点的API,能够很容易创建一个全局唯一的path,这个path就可以作为一个名称。

配置管理

程序总是需要配置的,如果程序分散部署在多台机器上,要逐个改变配置就变得困难。现在把这些配置全部放到Zookeeper上去,保存在 Zookeeper的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到Zookeeper 的通知,然后从 Zookeeper获取新的配置信息应用到系统中就可以了。

集群管理

所谓集群管理无在乎两点:是否有机器退出和加入以及选举master。 对于第一点,所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知。

分布式锁

有了zookeeper的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。 对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁。 对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,编号最小的获得锁,用完删除,依次方便。

队列管理

两种类型的队列: 1、同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。 2、队列按照 FIFO方式进行入队和出队操作。 第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。 第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。

Zookeeper的基本角色

leader

事务请求的唯一调度者和处理者,保证集群中事务处理顺序,集群内部各服务器的调度者

Follower

处理客户端非事务请求,转发事务请求给leader服务器。参与事务请求proposal的投票,参与leader选举投票。

Observer(可伸缩性)

充当一个观察者的角色,和Follower类似,对非事务请求,都可以进行独立处理。而对于事务请求,则交给leader来处理。和follower的区别是,Observer不参与任何形式的投票。通常用于不影响集群事务处理能力的情况下增加集群非事务处理能力。

Zookeeper的基本结构

Zookeeper采用树形层次结构,树中的每个节点被称为—Znode。 Znode,兼具文件和目录两种特点:

  1. 像文件一样维护着数据、元信息、ACL、时间戳等数据结构

  2. 像目录一样可以作为路径标识的一部分。 每个Znode由3部分组成: ① stat:此为状态信息, 描述该Znode的版本, 权限等信息 ② data:与该Znode关联的数据 ③ children:该Znode下的子节点

cZxid = 0x100000009         节点创建时的zxid.     
ctime = Mon Sep 18 10:55:36 CST 2017  节点创建时的时间
mZxid = 0x100000009      节点最新一次更新发生时的zxid
mtime = Mon Sep 18 10:55:36 CST 2017 节点最新一次更新发生时的时间
pZxid = 0x100000009子节点最新一次更新发生时的时间戳
cversion = 0    其子节点的更新次数
dataVersion = 0   节点数据的更新次数
aclVersion = 0      节点ACL(授权信息)的更新次数.
ephemeralOwner = 0x0 ephemeralOwner值表示与该节点绑定的session id
dataLength = 7      节点数据的字节数
numChildren = 0     子节点个数

节点类型

1、PERSISTENT-持久化目录节点 客户端与zookeeper断开连接后,该节点依旧存在 2、PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点 客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 3、EPHEMERAL-临时目录节点 客户端与zookeeper断开连接后,该节点被删除 4、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点 客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 临时节点不允许有子节点

Zookeeper的原理

ZAB协议

ZAB 协议包括两种基本的模式,分别是崩溃恢复和消息广播。

崩溃恢复

当整个服务框架在启动过程中,或是当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时, ZAB 协议就会进入恢复模式并选举产生新的 Leader 服务器。当选举产生了新的Leader 服务器同时集群中已经有过半的机器与该 Leader 服务器完成了状态同步之后,ZAB 协议就会退出恢复模式。

消息广播

当集群中已经有过半的 Follower 服务器完成了和 Leader 服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。当一台同样遵守 ZAB 协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个 Leader 服务器在负责进行消息广播 , 那么新加人的服务器就会自觉地进人数据恢复模式:找到 Leader 所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。

Leader选举

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的server都恢复到一个正确的状态。

  1. 客户端发送写请求给Follower

  2. Followe把请求转发给Leader

  3. Leader接受到请求之后发起投票

  4. Leader汇总投票结果,同意则写入,然后由Follower返回结果给Client,否则不写入,也是通过这种方式实现 了原子事务性

所以ZK的节点一般推荐为奇数个: 当多数Server写成功,则任务数据写成功如果有3个Server,则两个写成功即可;如果有4或5个Server,则三个写成功即可。Server数目一般为奇数(3、5、7)如果有3个Server,则最多允许1个Server挂掉;如果有4个Server,则同样最多允许1个Server挂掉由此,可以节省服务器资源。

Zookeeper实现分布式锁

zookeeper 可以根据有序节点+watch实现,实现思路,如:

为每个线程生成一个有序的临时节点,为确保有序性,在排序一次全部节点,获取全部节点,每个线程判断自己是否最小,如果是的话,获得锁,执行操作,操作完删除自身节点。如果不是第一个的节点则监听它的前一个节点,当它的前一个节点被删除时,则它会获得锁,以此类推

总结

Zookeeper作为一个节点管理系统,在日常的工作应用中也是比较多的,此前ZK的运维开发我不曾涉及,也就荒废了学习,在最近的一些事情中也是发现,知识储备的提高只有好处没有坏处,在后续的工作学习当中,蛋挞也会不停自勉,更加深入全面的学习知识。


作者:蛋挞

日期:2019.02.18


多少事,从来急;天地转,光阴迫;一万年太久,只争朝夕!



版权声明:本文为weixin_42642341原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。