zookeeper简介(一)

原文地址,转载请注明出处: https://blog.csdn.net/qq_34021712/article/details/82870721     ©王赛超 html

https://blog.csdn.net/qq_34021712/article/category/9278741node

 

介绍
ZooKeeper(后面称为zk)是一种用于分布式应用程序的分布式开源协调服务。主要是用来解决分布式应用中常常遇到的一些问题,假如你公司的项目仍是处于单机状态,那可能用不到zk,一旦涉及到分布式应用,不少问题均可以利用zk解决。
官网地址:http://zookeeper.apache.org/doc/current/zookeeperOver.htmlredis

1.设计目标
简单
高可靠
有序
高性能
下面一一介绍:
简单的数据模型算法

zk容许各分布式应用经过一个共享的命名空间相互联系,该命名空间相似于一个标准的文件系统:由若干注册了的数据节点构成(用zk的术语叫znode),这些节点相似于文件和目录。与专为存储而设计的典型文件系统不一样,zk数据保存在内存中,这意味着zk能够实现高吞吐量和低延迟数量。数据库

高可靠express

就像zk须要协调的分布式系统同样,它自己就是具备冗余结构,它构建在一系列主机之上,构成zk服务的各服务器之间必须相互知道,它们维护着一个状态信息的内存映像,以及在持久化存储中维护着事务日志和快照。只要大部分服务器正常工做,zk服务就能正常工做。客户端链接到一台zk服务器。客户端维护这个TCP链接,经过这个链接,客户端能够发送请求、获得应答,获得监视事件以及发送心跳。若是这个链接断了,客户端能够链接到另外一个zk服务器。
   1.客户端随机链接集群中任何一台server
   2.集群内全部server基于Zab(ZooKeeper Atomic Broadcast)协议进 行通讯
   3.集群内部根据算法自动选举出一个leader,负责向follower(其余 server)广播全部变化消息
   4.集群中每一个follower都和leader通讯
         • Follower接收来自leader的全部变化消息,保存在本身内存
         • Follower转发来自客户端的写请求给leader
         • 客户端的读请求会在follower端直接服务,无需转发给leaderapache

zk集群角色
Leader
①Leader服务器是zk集群工做机制的核心.
②事务请求的惟一调度者和处理者,保证集群事务请求处理的顺序性.
Follower
①Follower服务器是zk集群状态的跟随者.
②处理非事务请求,转发事务请求给Leader服务器
③参与事务请求的proposal投票
④参与Leader选举投票
Observer
Observer是一种新型的zk节点,Observer服务器只提供非事务服务.一般用于不影响集群事务处理能力的前提下提高集群的非事务的处理能力,Observer有另一个优点,由于它不参与投票,因此他们不属于zk集群的关键部位,即便他们Failed,或者从集群中断开,也不会影响集群的可用性。服务器

有序性
zk给每次更新附加一个数字标签,代表zk中的事务顺序,后续操做能够利用这个顺序来完成更高层次的抽象功能,例如同步原语操做。网络

高性能
zk特别适合于以读为主要负荷的场合。zk能够运行在数千台机器上,若是大部分操做为读,例如读写比例为10:1,zk的效率会很高。session

下面了解一下数据模型的一些操做:

数据模型 与其操做
和文章刚开始讲的简单的数据模型同样,zk提供的名称空间很是相似于标准文件系统。名称是由斜杠(/)分隔的路径元素序列。zk名称空间中的每一个节点都由路径标识。

节点介绍
在zk中每一个命名空间(Namespace)被称为znode,每一个znode包含一个路径和与之相关的元数据,以及继承自该节点的孩子列表(临时节点下面不能建立子节点),zk旨在存储协调数据:状态信息,配置,位置信息等,所以存储在每一个节点的数据一般很小,在字节到千字节范围内。

一个znode维护了一个属性结构,该结构包括:版本号、ACL变动、时间戳。每次znode数据发生变化,版本号都会递增,这样客户端的读请求能够基于版本号来检索状态相关数据。

每一个znode都有一个ACL,用来限制是否能够访问该znode。

在一个命名空间中,对znode上存储的数据执行读和写请求操做都是原子的。

zk中有几种节点类型
注意:节点类型在节点建立的时候就被肯定且不可改变

临时节点(EPHEMERAL):临时建立的,会话结束节点自动被删除,也能够手动删除,临时节点不能拥有子节点.
持久节点(PERSISTENT):建立后永久存在,除非主动删除。
以上两种节点为Non-sequence节点,只有一个可建立成功,其它匀失败。而且建立出的节点名称与建立时指定的节点名彻底同样.

临时顺序节点(EPHEMERAL_SEQUENTIAL):具备临时节点特征,可是它会有序列号。
持久顺序节点(PERSISTENT_SEQUENTIAL):具备持久节点特征,可是它会有序列号。
以上两种节点为sequence节点,建立出的节点名在指定的名称以后带有10位10进制数的序号。多个客户端建立同一名称的节点时,都能建立成功,只是序号不一样

容器节点(CONTAINER):若是节点中最后一个子Znode被删除,将会触发删除该Znode;
持久定时节点(PERSISTENT_WITH_TTL):客户端断开链接后不会自动删除Znode,若是该Znode没有子Znode且在给定TTL时间内无修改,该Znode将会被删除;TTL单位是毫秒,必须大于0且小于或等于 EphemeralType.MAX_TTL
持久顺序定时节点(PERSISTENT_SEQUENTIAL_WITH_TTL):同PERSISTENT_WITH_TTL,且Znode命名末尾自动添加递增编号;
以上三种节点是在3.5.3-beta版中才有的

节点信息
每个Znode都有对应的stat结构,和文件系统相似。stat状态主要包含下面的信息:

cZxid. 节点被建立时候的事务ID
mZxid 节点最后一次被修改时候的事务ID
pZxid 该节点的子节点最后一次被修改时的事务ID。子节点删除或添加才会影响pZxid
ctime 节点被建立的时间
mtime 节点被修改的世界
dataVersion 这个节点数据改变的次数
cversion 子节点被改变的次数
aclVersion 节点的ACL(访问控制列表被改变的次数)
ephemeralOwner 建立该临时节点的 session ID。若是是持久节点,设置为0
dataLength 数据内容长度
numChildren 当前节点子节点的个数
可使用ls2和stat命令查看ZooKeeper节点下的信息。

节点的访问控制(ACL)
zk提供了ACL来控制znode节点的访问,只有符合了ACL控制,才能够操做该节点,不然将没法操做。
Zookeeper支持可配置的认证机制。它利用一个三元组来定义客户端的访问权限:
(scheme:expression, perms) 。其中:

Schema 表明权限控制模式,分别为:
● World 任何人
● Auth 不须要ID
● Digest 用户名和密码方式的认证
● IP Address IP地址方式的认证
perms(权限),ZooKeeper支持以下权限
● CREATE: 建立子节点
● READ: 获取子节点与自身节点的数据信息
● WRITE:在Znode节点上写数据
● DELETE:删除子节点
● ADMIN:设置ACL权限
注意:
Znode的Acl只是针对某个节点,不会做用到它的子节点上
任何链接到ZooKeeper的客户端均可以使用exist操做,exist是不须要权限的。

zk能够保证以下特性:
顺序一致性
客户端的更新顺序与它们被发送的顺序一致。

原子性
更新操做要么成功,要么失败,没有第三种结果。

单系统映像
不管客户端链接到哪个服务器,他都将看到相同的zk视图。

可靠性
一旦一个更新操做被应用,那么在客户端再次更新以前,其值不会再改变。

实时性
zk保证客户端将在一个时间间隔范围内得到服务器的更新信息,或者服务器失效的信息。 但因为网络延时等缘由,zk不能保证两个客户端能同时获得刚更新的数据,若是须要最新数据,应该在读数据以前调用sync()接口。

Zookeeper Watch机制
zk支持监听, 客户端可以设置监听znode节点. 当znode节点变动时可能触发或者移除监听.当监听事件被触发了,客户端将会收到数据通知包,告诉客户端节点数据被修改了. 同时若是当前客户端和zk节点的链接被断开了.客户端将收到一个本地通知.

有以下的Watcher事件类型可能出现:
NodeChildrenChanged: zNode的子节点建立或删除的时候
NodeCreated: 新的Znode节点被建立的时候
NodeDataChanged: Znode节点的数据改变了的时候
NodeDeleted: Znode节点被删除的时候。
Watcher操做特色
主动推送 Watch被触发时,由 zk 服务器主动将更新推送给客户端,而不须要客户端轮询。
一次性 数据变化时,Watch 只会被触发一次。若是客户端想获得后续更新的通知,必需要在 Watch 被触发后从新注册一个 Watch。
可见性 若是一个客户端在读请求中附带 Watch,Watch 被触发的同时再次读取数据,客户端在获得 Watch 消息以前确定不可能看到更新后的数据。换句话说,更新通知先于更新结果。
顺序性 若是多个更新触发了多个 Watch ,那 Watch 被触发的顺序与更新顺序一致。避免安装大量watches侦听在同一个节点
没法保证跟踪到每个变化
ZooKeeper Session
客户端和server间采用长链接
链接创建后,server产生session ID(64位)返还 给客户端
客户端按期发送ping包来检查和保持和server的 链接
一旦session结束或超时,全部ephemeral节点会 被删除
客户端可根据状况设置合适的session超时时间
客户端可以异步接收来自服务端的Watcher事件通知
ZooKeeper典型8大应用场景及对应的特性:
配置管理服务
例如当当的configtoolkit配置中心,就是将配置信息放到了zk上,假如你有20个节点,须要修改配置文件的时候,你总不能一个节点一个节点去更改吧 那假若有100个节点呢?在分布式系统中,有不少实例中的大多数配置项是相同的(好比数据库链接等),须要改变配置项,若是有zk的话,不须要在每一个实例去修改。全部实例在启动时,都回去zk拉取节点信息,当节点信息修改的时候会通知到每个实例,某些配置项也能够达到热配置的效果。

集群管理(Master选举)
在分布式的集群中,常常会因为各类缘由,好比硬件故障,软件故障,网络问题,有些节点会进进出出。有新的节点加入进来,也有老的节点退出集群。这个时候,集群中其余机器须要感知到这种变化,而后根据这种变化作出对应的决策。好比咱们是一个分布式存储系统,有一个中央控制节点负责存储的分配,当有新的存储进来的时候咱们要根据如今集群目前的状态来分配存储节点。这个时候咱们就须要动态感知到集群目前的状态。还有,好比一个分布式的SOA架构中,服务是一个集群提供的,当消费者访问某个服务时,就须要采用某种机制发现如今有哪些节点能够提供该服务(这也称之为服务发现,好比Alibaba开源的SOA框架Dubbo就采用了zk做为服务发现的底层机制)。还有开源的Kafka队列就采用了zk做为Cosnumer的上下线管理。
还有一个场景:集群选master,一旦master挂掉可以立刻能从slave中选出一个master,这个实现和上面实现同样。

命名服务
命名服务就是指经过指定的名字来获取资源或者服务的地址。zk会在本身的文件系统上(树结构的文件系统)建立一个以路径为名称的节点,它能够指向提供的服务的地址,远程对象等。分布式服务框架Dubbo中使用ZooKeeper来做为其命名服务,维护全局的服务地址列表。

分布式计数器
在分布式环境下,获取惟一id,功能和redis自增返回值同样,指定一个Zookeeper数据节点做为计数器,多个应用实例在分布式锁的控制下,经过更新该数据节点的内容来实现计数功能。

分布式协调通知
说分布式协调通知就有点广了,上面所说的配置服务和集群管理就是用到了分布式协调通知,分布式协调/通知服务是分布式系统中不可缺乏的一个环节,是将不一样的分布式组件有机结合起来的关键所在。
利用zk中特有的Watcher注册与异步通知机制,可以很好的实现分布式环境下不一样机器,甚至是不一样系统之间的协调与通知,从而实现对数据变动的实时处理。
利用zk的心跳机制和临时节点特性,可让不一样的机器都在zk的一个指定节点下建立临时子节点,不一样的机器之间能够根据这个临时节点来判断对应的客户端机器是否存活。经过这种方式,检测系统和被检测系统之间并不须要直接相关联,而是经过zk上的某个节点进行关联,大大减小了系统耦合。

发布订阅
发布/订阅模式是一对多的关系,多个订阅者对象同时监听某一主题对象,这个主题对象在自身状态发生变化时会通知全部的订阅者对象。使它们能自动的更新本身的状态。发布/订阅可使得发布方和订阅方独立封装、独立改变。当一个对象的改变须要同时改变其余对象,并且它不知道具体有多少对象须要改变时可使用发布/订阅模式。发布/订阅模式在分布式系统中的典型应用有配置管理和服务发现、注册。

配置管理是指若是集群中的机器拥有某些相同的配置而且这些配置信息须要动态的改变,咱们可使用发布/订阅模式把配置作统一集中管理,让这些机器格子各自订阅配置信息的改变,当配置发生改变时,这些机器就能够获得通知并更新为最新的配置。

服务发现、注册是指对集群中的服务上下线作统一管理。每一个工做服务器均可以做为数据的发布方向集群注册本身的基本信息,而让某些监控服务器做为订阅方,订阅工做服务器的基本信息,当工做服务器的基本信息发生改变如上下线、服务器角色或服务范围变动,监控服务器能够获得通知并响应这些变化。

分布式锁
每一个客户端对某个方法加锁时,在zk上的与该方法对应的指定节点的目录下,生成一个惟一的瞬时有序节点。 判断是否获取锁的方式很简单,只须要判断本身建立的子节点是否为当前子节点列表中序号最小的子节点,若是是则认为得到锁,不然监听/lock的子节点变动消息,得到子节点变动通知后重复此步骤直至得到锁。

队列管理zk队列不太适合要求高性能的场合,能够考虑在数据量不大的状况下使用。毕竟引进一个消息中间件会增长系统的复杂性和运维的压力。固然了,首先已有项目中要使用zk。使用zk实现先进先出队列就是在特定的目录下建立PERSISTENT_EQUENTIAL(永久、序列化)节点,建立成功时Watcher通知等待的队列,队列删除序列号最小的节点用以消费。此场景下zk的znode用于消息存储,znode存储的数据就是消息队列中的消息内容,SEQUENTIAL序列号就是消息的编号,按序取出便可。因为建立的节点是持久化的,因此没必要担忧队列消息的丢失问题。SEQUENTIAL:一旦节点被标记上SEQUENTIAL这个属性,那么在这个节点被建立的时候,ZooKeeper 就会自动在其节点后面追加上一个整型数字,这个整型数字是一个由父节点维护的自增数字。————————————————版权声明:本文为CSDN博主「这个名字想了好久」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接及本声明。原文连接:https://blog.csdn.net/qq_34021712/article/details/82870721

相关文章
相关标签/搜索