【中间件】zookeeper

一、概述

ZooKeeper是一个开源的分布式协调服务。分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。

二、特点

⑴顺序一致性,从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到ZooKeeper中

⑵原子性,要么整个集群中所有的机器都成功应用了某一个事务,要么都没有应用

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

⑷可靠性,一旦一次更改请求被应用,更改的结果就会被持久化,直到被下一次更改覆盖

三、组成角色

1、集群

为了保证高可用,最好以集群的方式部署ZK,而且最好是奇数台。

在ZooKeeper中,有三种角色:

①Leader   ②Follower   ③Observer

一个ZooKeeper集群同一时刻只会有一个Leader,其他都是Follower或Observer。

ZooKeeper集群的所有机器通过一个Leader选举过程来选定一台被称为『Leader』的机器,Leader服务器为客户端提供读和写服务。

Follower和Observer都能提供读服务,不能提供写服务。两者唯一的区别在于,Observer机器不参与Leader选举过程,也不参与写操作的『过半写成功』策略,因此Observer可以在不影响写性能的情况下提升集群的读性能。

为什么最好使用奇数台服务器构成 ZooKeeper 集群:

因为3个Server和4个Server都是最多允许一个Server挂掉。

2、会话(Session)

Session是指客户端会话,在讲解客户端会话之前,我们先来了解下客户端连接。在ZooKeeper中,一个客户端连接是指客户端和ZooKeeper服务器之间的TCP长连。

ZooKeeper对外的服务端口默认是2181,客户端启动时,首先会与服务器建立一个TCP连接,从第一次连接建立开始,客户端会话的生命周期也开始了,通过这个连接,客户端能够通过心跳检测和服务器保持有效的会话,也能够向ZooKeeper服务器发送请求并接受响应,同时还能通过该连接接收来自服务器的Watch事件通知。Session的SessionTimeout值用来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要SessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。

3、数据节点(ZNode)

⑴Znode概述

在谈到分布式的时候,一般『节点』指的是组成集群的每一台机器。而ZooKeeper中的数据节点是指数据模型中的数据单元,称为ZNode。由于对于程序员来说,对zk的操作主要是对znode的操作。

ZooKeeper采用了类似文件系统的的数据模型,其节点构成了一个具有层级关系的树状结构:

根节点 / 包含了两个字节点 /module1,/module2,而节点 /module1 又包含了三个字节点 /module1/app1,/module1/app2,/module1/app3。在zk中,节点以绝对路径表示,不存在相对路径,且路径最后不能以 / 结尾(根节点除外)。

⑵ZNode类型

持久节点:

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

临时节点:

临时节点的生命周期跟客户端会话绑定,一旦客户端会话失效,那么这个客户端创建的所有临时节点都会被移除。

另外,ZooKeeper还允许用户为每个节点添加一个特殊的属性:SEQUENTIAL。一旦节点被标记上这个属性,那么在这个节点被创建的时候,ZooKeeper就会自动在其节点后面追加上一个整型数字,这个整型数字是一个由父节点维护的自增数字。

⑶ZNode版本

ZooKeeper的每个ZNode上都会存储数据,对应于每个ZNode,ZooKeeper都会为其维护一个叫作Stat的数据结构,Stat中记录了这个ZNode的三个数据版本,分别是version(当前ZNode的版本)、cversion(当前ZNode子节点的版本)和aversion(当前ZNode的ACL版本)。

⑷ZNode状态信息

每个ZNode除了存储数据内容之外,还存储了ZNode本身的一些状态信息。用 get 命令可以同时获得某个ZNode的内容和状态信息。如下:

[zk: localhost:2181(CONNECTED) 23] get /yarn-leader-election/appcluster-yarn/ActiveBreadCrumb

appcluster-yarnrm1
cZxid = 0x1b00133dc0    //Created ZXID,表示该ZNode被创建时的事务ID
ctime = Tue Jan 03 15:44:42 CST 2017    //Created Time,表示该ZNode被创建的时间
mZxid = 0x1d00000063    //Modified ZXID,表示该ZNode最后一次被更新时的事务ID
mtime = Fri Jan 06 08:44:25 CST 2017    //Modified Time,表示该节点最后一次被更新的时间
pZxid = 0x1b00133dc0    //表示该节点的子节点列表最后一次被修改时的事务ID。注意,只有子节点列表变更了才会变更pZxid,子节点内容变更不会影响pZxid。
cversion = 0    //子节点的版本号
dataVersion = 11    //数据节点的版本号
aclVersion = 0    //ACL版本号
ephemeralOwner = 0x0    //创建该节点的会话的seddionID。如果该节点是持久节点,那么这个属性值为0。
dataLength = 22    //数据内容的长度
numChildren = 0    //子节点的个数

4、事务操作

一般包括数据节点创建与删除、数据内容更新和客户端会话创建与失效等操作。对应每一个事务请ZooKeeper都会为其分配一个全局唯一的事务ID,用ZXID表示,通常是一个64位的数字。每一个ZXID对应一次更新操作,从这些ZXID中可以间接地识别出ZooKeeper处理这些事务操作请求的全局顺序。

5、Watcher

Watcher(事件监听器),是ZooKeeper中一个很重要的特性。ZooKeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去。该机制是ZooKeeper实现分布式协调服务的重要特性。

6、ACL

ZooKeeper采用ACL(Access Control Lists)策略来进行权限控制。ZooKeeper定义了如下5种权限。
CREATE: 创建子节点的权限。
READ: 获取节点数据和子节点列表的权限。
WRITE:更新节点数据的权限。
DELETE: 删除子节点的权限。
ADMIN: 设置节点ACL的权限。
注意:CREATE 和 DELETE 都是针对子节点的权限控制。

三、Zookeeper的核心----原子广播

很多人以为ZooKeeper也是Paxos算法的工程实现。事实上,ZooKeeper并没有完全采用Paxos算法,而是Zab(ZooKeeper原子广播协议)协议作为其数据一致性的核心算法

ZAB协议核心原理:

⑴崩溃恢复

崩溃恢复模式包括两个阶段:Leader选举和数据同步。

在整个ZooKeeper集群启动过程中,或是当Leader服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB协议就会进入恢复模式并选举产生新的Leader服务器。当选举产生了新的Leader服务器,同时集群中有过半的机器与该Leader服务器完成了状态同步之后,ZAB协议就会退出恢复模式。其中,状态同步是指数据同步,用来保证集群中的机器能够和Leader服务器的数据状态保持一致。

之后整个集群就可以进入消息广播模式了。

⑵消息广播

根据zab协议实现分布式系统数据一致性,zab核心将所有写操作的请求都转换为事物(proposal)。Leader节点再数据写完之后,将向所有follower节点发送数据广播请求,等待所有follower响应。在zab协议中只要有半数以上follower反馈即可。leader节点就会向所有follower服务器发送commit消息。即将leader节点上的数据同步到follower节点上。 

四、ZooKeeper典型应用场景

1.分布式锁

ZooKeeper上的一个ZNode可以表示一个锁。例如/exclusive_lock/lock节点就可以被定义为一个锁。

⑴获得锁

如上所说,把ZooKeeper上的一个ZNode看作是一个锁,获得锁就通过创建ZNode的方式来实现。所有客户端都去/exclusive_lock节点下创建临时子节点/exclusive_lock/lock。ZooKeeper会保证在所有客户端中,最终只有一个客户端能够创建成功,那么就可以认为该客户端获得了锁。同时,所有没有获取到锁的客户端就需要到/exclusive_lock节点上注册一个子节点变更的Watcher监听,以便实时监听到lock节点的变更情况。

⑵释放锁

因为/exclusive_lock/lock是一个临时节点,因此在以下两种情况下,都有可能释放锁。
当前获得锁的客户端机器发生宕机或重启,那么该临时节点就会被删除,释放锁。
正常执行完业务逻辑后,客户端就会主动将自己创建的临时节点删除,释放锁。
无论在什么情况下移除了lock节点,ZooKeeper都会通知所有在/exclusive_lock节点上注册了节点变更Watcher监听的客户端。这些客户端在接收到通知后,再次重新发起分布式锁获取,即重复『获取锁』过程。

2.Zookeeper实现注册中心

⑴首先我们贴上一张结构图,这里我们这里以Dubbo为例

/dubbo:这是dubbo在ZooKeeper上创建的根节点;

/dubbo/com.foo.BarService:这是服务节点,代表了Dubbo的一个服务;

/dubbo/com.foo.BarService/providers:这是服务提供者的根节点,其子节点代表了每一个服务真正的提供者;

/dubbo/com.foo.BarService/consumers:这是服务消费者的根节点,其子节点代表每一个服务真正的消费者;

⑵注册中心的工作流程

①服务提供者启动时,会在providers节点下注册一个临时节点。

②服务消费者启动时,它会在读取并订阅providers下所有子节点并解析它们的URL地址作为服务提供者列表,同时会在consumers下注册一个临时节点。

③服务消费者,从提供者地址列表中,基于软负载均衡算法,选一个提供者进行调用,如果调用失败,再选另一个提供者调用。

④增加提供者,也就是在providers下面新建子节点。一旦服务提供方有变动,zookeeper就会把最新的服务列表推送给消费者。

⑤所有提供者在ZooKeeper上创建的节点都是临时节点,利用的是临时节点的生命周期和客户端会话相关的特性,因此一旦提供者所在的机器出现故障导致该提供者无法对外提供服务时,该临时节点就会自动从ZooKeeper上删除,同样,zookeeper会把最新的服务列表推送给消费者。

⑥消费者每次调用服务提供方是不经过ZooKeeper的,消费者只是从zookeeper那里获取服务提供方地址列表。所以当zookeeper宕机之后,不会影响消费者调用服务提供者,影响的是zookeeper宕机之后如果提供者有变动,增加或者减少,无法把最新的服务提供者地址列表推送给消费者,所以消费者感知不到。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值