【大数据入门系列1.1】zookeeper基础

官网地址:https://zookeeper.apache.org/

Zookeeper简介:

ZooKeeper是开源的分布式协调服务框架,将复杂且容易出错的分布式一致性服务封装起来,构建一系列简单的原语(原子语言,不可分割,不可中断,是操作系统或计算机网络用语范畴。是由若干条指令组成的,用于完成一定功能的一个过程)和易用的api接口,分布式应用程序可以通过zookeeper实现同步、配置管理、组和命名服务、集群管理等等。


zookeeper设计目标

Zookeeper 致力于为那些高吞吐的大型分布式系统提供一个高性能、高可用、且具有严格顺序访问控制能力的分布式协调服务。它具有以下目标:

1) 简单的数据模型

ZooKeeper允许分布式进程通过共享的层级命名空间相互协调,该命名空间的结构与标准文件系统类似。名称空间由数据寄存器组成--在ZooKeeper中称为znodes,与文件和目录类似。

1.zookeeper是一个树状结构--znode树(维系在内存中,高吞吐量和低延迟)

2.每一个节点称为znode节点,且每一个znode节点必须存储数据

3.根节点是/ ,zookeeper所有的操作都必须以根节点为基准进行计算。

4.任意一个节点的路径都是唯一的

2) 构建zookeeper集群

    可以由多个zookeeper服务(通常是奇数个)构成zookeeper集群,与它协调的分布式进程一样,ZooKeeper本身也可以在集群中进行复制。集群中每台机器都会单独在内存中(拥有高吞吐量和低延迟数维护自身的状态,并且每台机器之间都保持着通讯,zookeeper服务之间必须彼此了解它们在内存中的状态,以及持久性存储(硬盘存储)中的事务日志和快照。只要集群中有半数(过半性)机器能够正常工作,那么整个集群就可以正常提供服务,故其可靠性极高。

客户端连接到单个ZK服务,客户端维护TCP连接,通过该连接发送请求,获取响应,获取监视事件以及发送心跳。如果与ZK服务的TCP连接中断,则客户端将连接到其他可用ZK服务。

3) 顺序访问

对于来自客户端的每个更新请求,Zookeeper 都会分配一个全局唯一的递增 ID,这个 ID 反映了所有事务请求的先后顺序。保证了分布式系统的顺序一致性:从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到ZooKeeper中。

4) 基于事务的高性能、高可用

ZooKeeper 将数据存全量储在内存中以保持高性能,并通过服务集群来实现高可用,由于 Zookeeper 的所有更新和删除都是基于事务的,其在读多写少的应用场景中有着很高的性能表现。

1.原子性:所有事务请求的结果在集群中所有机器上的应用情况是一致的,也就是说要么整个集群所有集群都成功应用了某一个事务,要么都没有应用,一定不会出现集群中部分机器应用了该事务,而另外一部分没有应用的情况。

2.单一视图:无论客户端连接的是哪个ZooKeeper服务器,其看到的服务端数据模型都是一致的。

3.可靠性:一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会被一直保留下来,除非有另一个事务又对其进行了变更。

4.实时性:通常人们看到实时性的第一反应是,一旦一个事务被成功应用,那么客户端能够立即从服务端上读取到这个事务变更后的最新数据状态。这里需要注意的是,ZooKeeper仅仅保证一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。


Zookeeper 集群搭建

参考文章:https://blog.51cto.com/nileader/795230

作者:@ni掌柜  [email protected]


Zookeeper集群中的角色以及工作流程

1)Leader(领导者)

1.由集群选举所产生,接受client请求

2.恢复数据

3.负责更新系统状态

4.接收其他server转发的请求,维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型。Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。 

PING 消息是指Learner的心跳信息;

REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;

ACK消息是 Follower的对提议的回复,超过半数的Follower通过,则commit该提议;

REVALIDATE消息是用来延长SESSION有效时间。

2) Learner(学习者)

    Follower   (跟随者) :

        1.为客户端提供读写服务(读请求直接由该Follower的内存数据库直接响应,写请求转发给Leader)返回client结果  

        2.向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息)

        3.接收Leader消息并进行处理

        4.定期向 Leader 汇报自己的节点状态。同时也参与写操作“过半写成功”的策略和 Leader 的选举

    Follower的消息循环处理如下几种来自Leader的消息: 

        1 .PING消息: 心跳消息; 

        2 .PROPOSAL消息:Leader发起的提案,要求Follower投票; 

        3 .COMMIT消息:服务器端最新一次提案的信息; 

        4 .UPTODATE消息:表明同步完成; 

        5 .REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息; 

        6 .SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。


        Observer(观察者)

        1.为客户端提供读写服务(读请求直接由该Follower的内存数据库直接响应,写请求转发给Leader)  

         2.定期向 Leader 汇报自己的节点状态。不参与写操作“过半写成功”的策略和 Leader 的选举;因此Observer可以在不影响写性能的情况下提升集群的读性能

3)Client (客户端)

 1.发起读写请求,接收server端的响应。

当前节点角色状态查询:

在装有ZooKeeper的机器的终端执行 zookeeper-server status 可以看当前节点的ZooKeeper是什么角色(Leader or Follower or Observer)。一个ZooKeeper集群同一时刻只会有一个Leader,其他都是Follower或Observer。


hadoop01节点可用   follower
hadoop02节点可用   follower
hadoop03节点可用   leader

Zookeeper数据节点类型和状态

『节点』指的是组成集群的每一台机器。而ZooKeeper中的数据节点是指数据模型中的数据单元,称为ZNode。ZooKeeper将所有数据存储在内存中,数据模型是一棵树(ZNode Tree),由斜杠(/)进行分割的路径,就是一个ZNode,如/hbase/master,其中hbase和master都是ZNode。每个ZNode上都会保存自己的数据内容,同时会保存一系列属性信息。在ZooKeeper中,ZNode可以分为持久节点和临时节点两类。

1. 持久节点(PERSISTENT) 默认创建持久节点是指一旦这个ZNode被创建了,除非主动进行ZNode的移除操作,否则这个ZNode将一直保存在ZooKeeper上。

2. 持久顺序节点(PERSISTENT_SEQUENTIAL)基本特性与持久节点一致,创建节点的过程中,zookeeper会在其名字后自动追加一个单调增长的数字后缀,作为新的节点名,这种节点会根据当前已存在的节点数自动加 1

3. 临时节点(EPHEMERAL) 在客户端退出之后就自动删除

4.临时顺序节点(EPHEMERAL_SEQUENTIAL)临时自动编号节点,在客户端退出之后就自动删除


Zookeeper 节点数据操作流程 

1.在Client向Follwer发出一个写的请求

2.Follwer把请求发送给Leader

3.Leader接收到以后开始发起投票并通知Follwer进行投票

4.Follwer把投票结果发送给Leader

5.Leader将结果汇总后如果需要写入,则开始写入同时把写入操作通知给Leader,然后commit;

6.Follwer把请求结果返回给Client


Zookeeper 客户端命令

zookeeper-cli  进行连接, 输入help可以查看zookeeper客户端中支持的命令

1. ls /节点名称 

查看节点目录

        ls  /      查看根节点下有zookeeper 、ngdata、hbase 、solr 节点

2. create  /节点名称   值                            

 创建节点

        create   /lijiaxin  "good_girl"      在根节点下创建子节点lijiaxin并且赋值为good_girl 

   注意 create  /lijiaxin  "good  girl" 会报错,提示如下:

这是因为 ZooKeeper有一个分层的名字空间,跟分布式文件系统很相似。唯一的不同是,名字空间中的每个节点都可以有关联的数据和子节点。这就像一个允许文件也是目录的文件系统。节点路径总是表达为规则的、斜杠分隔的绝对路径,不存在相对路径。路径可以使用任何Unicode字符,但是需要遵循下列限制:不能使用空字符(\?)。(这在C绑定中会导致问题) 因为不能正确显示,或者容易弄混淆,不能使用这些字符:\ - \和\� - \?。不允许使用这些字符:\? - uF8FFF、\? - uFFFF、\uXFFFE - \uXFFFF(X是1到E之间的一个数字)、\? - \?。可以使用小数点,但是不能单独使用.和..来指示路径中的节点,因为ZooKeeper不使用相对路径。/a/b/./c或者/a/b/../c是无效的。 记号zookeeper是保留的。 set 同理

3. get  /节点名称     

获取节点的信息

     get  /lijiaxin    获取节点/lijiaxin的相关信息

每个 ZNode 节点在存储数据的同时,都会维护一个叫做 Stat 的数据结构,里面存储了关于该节点的全部状态信息。如下:

状态属性                   说明

czxid                         数据节点创建时的事务 ID

ctime                         数据节点创建时的时间

mzxid                        数据节点最后一次更新时的事务 ID

mtime                        数据节点最后一次更新时的时间

pzxid                         数据节点的子节点最后一次被修改时的事务 ID

cversion                    子节点的更改次数,当znode的子节点变化时,cversion的值会加1

dataversion               节点数据的更改次数,每当对节点进行set操作时,dataversion的值就会加1

aversion                    节点的 ACL 的更改次数

ephemeralOwner      如果节点是临时节点,则表示创建该节点的会话的 SessionID;如果节点是持久节点,则该属性值为 0

dataLength               数据内容的长度

numChildren            数据节点当前的子节点个数


4.  set   /节点名称   值

更改节点的值

set /lijiaxin "good_women"   将lijiaxin的数据更新为good_women  

5. delete  /节点名称   

删除子节点要求这个节点中没有子节点

在/lijiaixn姐殿下创建/weihao 节点,直接删除/lijiaxin节点会提示节点不为空无法删除。delete只能删除没有子节点的节点

6. rmr  /节点名称

删除节点及其子节点

删除/lijiaxin节点及其子节点

7. quit 

退出客户端

退出客户端,session会话关闭

8. creaet   /节点名称   值

创建持久节点(默认)  属性值如下:

create /weihao ”good_man“ 创建持久节点/weihao,  ephemeralowner =0x0  的是持久化节点

9.create  -e /节点名称   值

 表示创建临时节点

创建临时节点/weihao1 ephemeralOwner = 0x3714514f1c00582 该属性是临时节点的事务ID  

quit 退出后再次登录查看,会发现该临时节点已删除

临时节点/weihao1已删除

10. create  -s   /节点名称   值

创建持久顺序节点

创建持久顺序节点/weihao1和/weihao2, 创建节点的过程中,zookeeper会在其名字后自动追加一个单调增长的数字后缀,作为新的节点名,这种节点会根据当前已存在的节点数自动加 1  
ephemeralOwner = 0x0 说明该节点是持久节点

11.create -e -s /节点名称  值 

创建临时顺序节点

创建临时顺序节点/weihao3和/weihao4, 创建节点的过程中,zookeeper会在其名字后自动追加一个单调增长的数字后缀,作为新的节点名, 这种节点会根据当前已存在的节点数自动加 1 ,ephemeralOwner = 0x1714823254503bb说明该节点为临时节点
quit退出重新登录后发现该临时顺序节点已被删除

Zookeeper   Session

Session(会话)是ZooKeeper中的会话实体,代表了一个客户端会话,其包含4个属性。

SESSIONID:唯一标识一个会话,每个客户端创建会话时,服务器都会为其分配一个全局唯一的SessionID

TimeOut:会话超时时间,在客户端创建TCP连接时指定

TickTime:Zookeeper自定义的时间单位,超时时间一般为2*TickTime~~20*TickTime

IsClosing:客户端重新成功连接服务器后,客户端当前状态

Zookeeper客户端启动时会与服务器建立一个TCP长连接。从连接指令发出后,客户端Session的生命周期就开始了,在整个生命周期内会切换不同的会话状态。

CONNECTING客户端开始创建Zookeeper对象时,客户端当前状态

CONNECTED:客户端成功连接服务器后,客户端当前状态

RECONNECTING:由于网络抖动等原因导致客户端与服务器闪断,客户端会尝试重连,客户端当前状态

RECONNECTED:客户端重新成功连接服务器后,客户端当前状态

CLOSE: 当会话过期时,客户端当前状态

通过该TCP连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向服务器发送请求并接受响应,还能够接收来自服务器的 watch 事件通知,便于实时响应某些操作。


Zookeeper  Watcher

        Zookeeper提供了分布式数据发布/订阅功能,一个典型的发布订阅模型系统定义了一种一对多的订阅关系,能让订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使他们能够做出相应的处理。

        Zookeeper中引入了watcher机制来实现这种分布式的通知功能。Zookeeper允许客户端向服务端注册一个Watcher监听,当服务端的一些事件触发了这个watcher,那么就会向指定客户端发送一个事件通知来实现分布式通知功能。

        触发事件总类很多,如:节点创建,节点删除,节点改变,子节点改变等等。总的来说可以概括为Watcher为以下三个过程:客户端向服务端注册watcher、服务端事件发生触发watcher、客户端回调watcher得到触发事件情况。

Watcher机制特点

1)一次性触发

事件发生触发监听,一个Watcher Event就会被发送到设置监听的客户端、这种效果是一次性的,后面再次发生同样的事件,不会再次触发。

2)事件封装

zookeeper使用watchdEvent 对象来封装服务端事件并传递,WatchedEvent包含了每一个事件的三个基本属性;

通知状态(keeperState),事件类型(EventType) 和节点路径(path)

3)event异步发送

watcher的通知事件从服务端到客户端是异步的

4)先注册再触发

zookeeper中的watcher机制,必须客户端先去服务端测试监听,这样事件发送才会触发监听,通知给客户端。

shell  客户端设置监听

创建/lijiaxin 节点,  get /lijiaxin watch   监听lijiaxin节点,注册监听事件

                在另一个客户端修改/lijiaixin节点就会触发watcher监听

在另一个zookeeper节点修改/lijiaxin的值,触发监听事件
客户端监听到了变化,/lijiaxin节点数据改变。

                再次在另一个Zookeeper节点修改znode节点/lijiaxin的值

修改/lijiaxin 为good_womens
此时会发现监听没有触发,说明监听只触发一次

Zookeeper的ACL--权限控制

Zookeeper 采用 ACL(Access Control Lists) 策略来进行权限控制,类似于 UNIX 文件系统的权限控制。

它定义了如下五种权限:

    CREATE:允许创建子节点

    READ:允许从节点获取数据并列出其子节点

    WRITE:允许为节点设置数据

    DELETE:允许删除子节点

    ADMIN:允许为节点设置权限。 

使用zkCli时,ACL的格式由::三段组成。

schema:可以取下列值:world, auth, digest, host/ip

id: 标识身份,值依赖于schema做解析。

acl:就是权限:c、d 、w、r、a分别表示create, delete,write,read, admin

注意:zookeeper对权限的控制是znode级别的,不具有继承性,即子节点不继承父节点的权限。这种设计在使用上还是有缺陷的,因为很多场景下,我们还是会把相关资源组织一下,放在同一个路径下面,这样就会有对一个路径统一授权的需求。

1.schema world

这是默认方式,表示没有认证。当创建一个新的节点(znode),而又没有设置任何权限时,就是这个值,例如: 

世界上所有人都有权限(默认),任何人都能访问

等价于:

setAcl  /znode  world:anyone:cdrwa 任何人都能访问该节点

2.schema auth

这种授权不针对任何特定ID,而是对所有已经添加认证的用户,换句话说,就是对所有已经通过认证的用户授权。 

格式:

addauth digest      添加认证用户

setAcl    auth::     对认证用户进行授权

必须要先添加认证用户,否则会失败。如上所示:

setAcl命令中的id域是被忽略的,可以填任意值,或者空串,例如:`setAcl auth::crdwa。因为这个域是忽略的,会把所有已经添加的认证用户都加进来。

如图:我们只设置了auth:weihao,但是查看acl权限的时候发现上面添加的用户都有权限,根据前面的说法,这个id值是被忽略的,写任何值,甚至空值也得到一样的结果。我们看到最后getAcl查询出来的结果包含所有前面添加的三个认证用户。

3.schema digest

这就是最普通的用户名:密码的验证方式,在一般业务系统中最常用。格式如下:

格式:setAcl     digest:::

和schema auth相比,有两点不同:

1.不需要预先添加认证用户(但是在zkCli访问的时候,肯定还是要添加认证用户的)。

2.密码是经过sha1及base64处理的密文。

密码可以通过如下shell的方式生成:

echo-n:|openssl dgst-binary-sha1|openssl base64

例如:

输出的+w4Bol0tkQ0bdBTE1Hc8kqZc7ec=就是传递给setAcl使用的id串。

注意,只有通过zkCli.sh设置digest的ACL时id才需要密文,而通过zookeeper的客户端设置digest的ACL时对应的auth数据是明文。这个属于编码实现的问题了。

和auth比较,digest有如下特性:

setAcl不需要事先添加认证用户。

授权是针对单个特定用户。

setAcl使用的密码不是明文,是sha1摘要值,无法反推出用户密码内容。

4.schema host/ip

格式:setAcl  /znode  ip:xxx.xxx.xxx.xxx:

就是客户机地址,或者是主机名、或者是IP地址。

主机名可以是单个主机名,也可以是域名。IP可以是单个IP地址,也可以是IP地址段,比如ip:192.168.1.0/16。


参考:

作者:CodingCode    链接:https://www.jianshu.com/p/392248ab27f4 来源:

作者:Jeffbond     链接:https://www.jianshu.com/p/84ad63127cd1  来源:

作者:@ni掌柜[email protected]  链接:https://blog.51cto.com/nileader/795230

作者:gs80140  链接:https://blog.csdn.net/gs80140/article/details/51496925

你可能感兴趣的:(【大数据入门系列1.1】zookeeper基础)