赞
踩
Zookeeper作为高可用的分布式协调与管理框架,在越来越多的分布式系统中作为核心组件引入使用,本文简要介绍Zookeeper的集群架构和一些基本概念,以及基于ZAB一致性协议的选主流程,并列举了一些常见的使用场景。
与典型的分布式架构Master/Slave主从模式不同,Zookeeper使用了Leader、Follower和Observer三种角色。如下表所示:
1)领导者Leader
Zookeeper集群在启动的时候需要从集群所有服务器中选举出一个Leader,由这个Leader来负责管理集群。Leader在整个集群中是唯一的,集群中的其它服务为这个Leader的follower。当集群中的Leader故障时候,Zookeeper需要能够快速的从Followers中选举出下一个Leader。因此,Leader是整个集群工作机制的核心,主要职责如下:
2)跟随者Follower
3)观察者Observer
Observer通常用于提升Zookeeper集群的非事务处理能力,通过水平扩展Observer机器来提升Zookeeper集群的读性能。Observer和Follower的区别在于:
Zookeeper中的数据模型和Linux文件系统类似的树形结构,不同的是在zookeeper中没有目录和文件的区别,每个节点统一称为znode。Znode是Zookeeper中数据的最小单元,每个Znode上都可以保存数据,同时还可以增加子节点。
提示:比如/Nginx/conf,/是一个znode,/Nginx是/的子znode,/Nginx还可以包含数据,数据内容就是所有安装Nginx的机器IP,/Nginx/conf是/Nginx子znode,它也可以包含内容,数据就是Nginx的配置文件内容。在应用中,我们可以通过这样一个路径就可以获得所有安装Nginx的机器IP列表,还可以获得这些机器上Nginx的配置文件。
Zookeeper中的znode包含四部分内容:
在Zookeeper中,事务是指能够改变ZooKeeper服务器状态的操作,一般包括节点创建与删除、数据节点内容更新和客户端会话创建与失效等。对于每个事务请求,Zookeeper都会为其分配一个全局唯一的事务ID,用ZXID表示,通常是64位的数字。每个ZXID对应一次更新操作,从这些ZXID中可以间接地识别出Zookeeper处理这些更新操作请求的全局顺序。
Zookeeper中的znode节点都有其生命周期,根据不同的生命周期分为不同的类型:持久的(persistent)和短暂的(ephemeral)。
根据上面两种类型,Znode有以下四种形式:
Znode节点的属性如下表所示:
属性名称 | 类型 | 描述 |
---|---|---|
czxid | long | 节点被创建的Zxid值 |
mzxid | long | 节点被修改的Zxid值 |
pzxid | long | 子节点最后一次被修改时候的zxid值 |
ctime | long | 节点被创建的时间 |
mtime | long | 节点最后一次被修改的时间 |
version | long | 节点被修改的版本号 |
dataVersion | long | 节点的内容被修改的版本号 |
aversion | long | 节点的ACL被修改的版本号 |
ephemeralOwner | long | 如果为临时节点,该值为这个节点拥有的会话id;否则,该值为0 |
dataLength | int | 节点数据域的长度 |
numChildren | int | 节点拥有的子节点个数 |
ZooKeeper使用版本号来保证分布式数据原子性操作,对znode的任何更新操作都会引起版本号的变化。每个Znode都具有三种类型的版本信息:
需要注意的是,Zookeeper中的版本表示对Znode节点的数据内容、子节点列表,或是节点ACL信息的修改次数。这里强调的是修改次数,即使前后两次变更子节点中的数据内容并没有发生变化,version的值依然会更新。
Zookeeper中的数据是运行在内存中的,必然需要持久化机制以保证数据的可恢复。Zookeeper中的持久化有两种方式:
在故障恢复时,Zookeeper会先用快照进行恢复,然后使用事务日志进行增量恢复。
Zookeeper允许客户端向服务器注册一个Watcher监听,当服务端发生了一些指定的事件,如节点创建删除、数据更新等,就会触发Watcher,并向指定的客户端发送一个事件通知。Zookeeper是通过Watcher机制实现分布式数据的发布/订阅功能。
ZooKeeper的Watcher机制主要包括客户端线程、客户端WatcherManager、ZooKeeper服务器三部分。客户端在向ZooKeeper服务器注册的同时,会将Watcher对象存储在客户端的WatcherManager当中。当ZooKeeper服务器触发Watcherls /事件后,会向客户端发送通知,客户端线程从WatcherManager中取出对应的Watcher对象来执行回调逻辑。
Zookeeper的主要特性如下:
Zookeeper通过广播机制实现各个节点之间的数据同步,实现这个机制的协议称为Zab协议。Zab协议的全称是Zookeeper Atomic Broadcast(Zookeeper原子广播),是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议 ,是Zookeeper保证数据一致性的核心算法。在前文“分布式一致性算法介绍”中专门有介绍相关内容。
ZAB协议主要有四个阶段:
当Zookeeper集群中的leader故障或者失去大部分的follower,zookeeper会进入恢复模式,恢复模式需要选举一个新的leader,让所有的节点恢复正常的状态。ZK的选举算法有两种:一种是基于basic-paxos实现的,另外一种是基于fast-paxos实现的。系统默认的算法为fast-paxos,这里重点介绍fast-paxos的选主流程。
选举完Leader后,Zookeeper进入状态同步过程,将Leader数据同步到Follower节点:
从前文中知道Zookeeper中Leader是整个集群内部各服务的调度者,对外提供读写服务。在集群内部,Leader主要有以下功能:
Leader整个工作流程如下图所示:
在Zookeeper集群内部,Follower主要功能如下:
Follower整个工作流程如下图所示:
Zookeeper作为高可用的分布式协调与管理框架,在越来越多的分布式系统中作为核心组件引入使用。以下将介绍Zookeeper一些典型的使用场景,比如集群管理、服务订阅与发现、配置中心以及分布式锁的实现等。
Zookeeper具有两大特性:
集群管理就是利用以上两个特性实现集群中各个主机的运行状态、主机的存活情况的实时监控。Zookeeper集群管理如下图所示:
所谓的配置中心也称为数据发布/订阅系统,就是发布者将数据发布到Zookeeper的一个或多个节点上以动态的获取数据,实现配置信息的集中式管理和数据的动态更新。
在Zookeeper中,客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送Watcher事件通知。客户端在接收到这个消息通知后,需要主动从服务器获取最新的数据。
在前文1.2.2中介绍了Znode节点类型,Zookeeper分布式锁是基于临时顺序节点实现的。基于Zookeeper的分布式锁实现在“分布式锁的几种实现机制”中也深入介绍过。
排他锁实现机制是线程在zookeeper上创建临时有序节点,使用watch监控资源节点等待获得锁。具体流程如下:
在上述流程中,客户端通过调用create方法创建表示锁的临时节点/lock,创建成功的客户端获得了锁,同时让没有获得锁的节点在该节点上注册Watcher监听,以便实时监听到lock节点的变更情况。当当前获得锁的客户端正常执行完业务逻辑,客户端会主动删除创建的临时节点。同时,如果获得锁的客户端发生宕机或异常,那么zookeeper上这个节点就会被删除也会释放锁资源。
排他锁有一个缺点就是,如果并发量大,那么同一时刻会有很多连接对同一节点进行监听,但检测到删除事件后,zk需要通知所有的连接,所有连接收到监听后,会同一时间在发生高并发竞争,给性能带来严重损耗。多数场景下考虑使用共享锁实现:
同时为了避免锁竞争,会使用公平锁机制,将没有获得锁的线程放入队列进行排队,等锁资源释放以后,按照先进先出的算法取出一个线程尝试获取锁。
Zookeeper实现分布式锁有以下特征:
Zookeeper的服务发现功能主要是根据指定名称来获取资源或服务的地址、提供者等信息。利用znode的特点以及watcher机制,将服务名称和对应的服务器列表信息动态注册到znode节点中,能够实时感知到后端服务器的状态变化。服务发现有以下作用:
从集群管理到Leader选举,从服务发现到服务订阅发布,再到分布式锁的实现,Zookeeper已经作为基础软件广泛应用于分布式应用系统中。本文从Zookeeper的集群架构入手,简要介绍了Leader和Learner几种角色,以及Znode的数据模型,并深入分析了基于ZAB一致性协议的选主流程和工作机制。最后结合几种常见的应用场景进行分析,以加深对Zookeeper的理解。
参考资料:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。