赞
踩
官网:https://zookeeper.apache.org/index.html
分布式服务协调组件,Google Chubby的开源实现。解决分布式应用中的以下问题:配置管理、命名服务(Naming Service)、集群管理、统一命名服务、状态同步。
用于解决分布式数据一致性问题,提供顺序一致性、原子性、单一视图、可靠性、实时性等:
ZK安装分单机、伪集群、集群三种方式。伪集群指的是在一台物理机上运行多个ZK实例,每个实例使用不同的端口启动服务;所有节点都处于一个物理机,存在单点故障;但是具有集群安装部署模式的一些特性,常用于测试环境试用ZK新版本的新功能,或调试学习用。生产环境会使用真正的集群部署模式。
下面仅仅只讲述各种不同系统下简单模式的安装。伪分布式和完全分布式模式的安装,不同的仅仅只是不同节点的配置文件的部分配置。
/opt
目录下,创建两个文件夹:data和logs。zookeeper-3.9.2
文件夹下的zoo_sample.cfg
文件拷贝一份命名为zoo.cfg
,并添加data和log目录配置指向刚才创建的两个目录。2888端口号是ZK服务之间通信的端口;3888是ZK与其他应用程序通信的端口dataDir=/opt/zookeeper-3.9.2/data
下创建myid
文件并编辑,并在对应的IP的机器上输入对应的编号。如在ZK上,myid文件内容就是1。如果只在单点上进行安装配置,那么只有一个server.1。.bash_profile
文件中增加ZK配置,随后使配置生效:source .bash_profile
export ZOOKEEPER_HOME=/opt/zookeeper-3.9.2
export PATH=$ ZOOKEEPER_HOME/bin:$PATH
#停止防火墙
systemctl stop firewalld.service
#禁止防火墙开机启动
systemctl disable firewalld.service
zkServer.sh start
,看到Mode:standalone就表示启动成功。zkServer.sh stop
vim rc.local
添加su – root -c '/opt/zookeeper-3.4.10/bin/zkServer.sh start'
,在centos7中,/etc/rc.local
的权限被降低,需执行命令赋予其可执行权限:chmod +x /etc/rc.d/rc.local
zoo.cfg
配置文件:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial synchronization phase can take
initLimit=10
# The number of ticks that can pass between sending a request and getting an acknowledgement
syncLimit=5
dataDir=/root/fmm/data/zookeeper
dataLogDir=xxx/zookeeper/server1/
clientPort=2181
server.1=10.20.20.76:2887:3887
server.2=10.20.20.239:2887:3887
server.3=10.20.21.27:2887:3887
minSessionTimeout=4000
maxSessionTimeout=100000
参数说明:
也叫文件系统。ZK中数据是以目录结构的形式存储的。其中的每一个存储数据的节点都叫做ZNode,每个ZNode都有一个唯一的路径标识。和目录结构类似,每一个节点都可以可有子节点(临时节点除外)。节点中可以存储数据和状态信息,每个ZNode上可以配置监视器(Watcher),用于监听节点中的数据变化。节点不支持部分读写,而是一次性完整读写。
ZNode节点的Stat结构体由字段:
即Znode,有四种类型,PERSISTENT(持久节点)、PERSISTENT_SEQUENTIAL(持久的连续节点)、EPHEMERAL(临时节点)、EPHEMERAL_SEQUENTIAL(临时的连续节点)。Znode的类型在创建时确定并且之后不能再修改。节点中除了可以存储数据,还包含状态信息。
临时节点的生命周期和客户端会话绑定。如果客户端会话失效,即关闭连接,则节点自动被清除。临时节点不能有子节点。
指在节点创建后,就一直存在,直到有删除操作来主动清除这个节点;不会因创建该节点的客户端会话失效而消失。
与临时节点不同的是,创建的节点会自动加上编号。
和持久节点类型是一致的。在ZK中,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。基于这个特性,在创建子节点的时候,可以设置这个属性,那么在创建节点过程中,ZK会自动为给定节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。
即数据变更通知,ZK允许客户端向服务端的某个Znode注册一个Watcher监听,当服务端的一些指定事件触发这个Watcher,服务端会向指定客户端发送一个事件通知来实现分布式的通知功能,然后客户端根据Watcher通知状态和事件类型做出业务上的改变。
工作机制:
Watcher特性:
Access Control List,访问控制列表。每一个Znode节点都拥有一个ACL,该列表规定用户对节点的访问权限。ZK定义5种权限:
CREATE和DELETE都是针对子节点的权限控制。
3.2.0版本后,添加Chroot特性,允许每个客户端为自己设置一个命名空间。如果一个客户端设置Chroot,那么该客户端对服务器的任何操作,都将会被限制在其自己的命名空间下。
通过设置Chroot,能够将一个客户端应用于ZK服务端的一颗子树相对应,在那些多个应用公用一个ZK集群的场景下,用于实现不同应用间的相互隔离。
ZK集群中有以下角色:
领导者(Leader):负责进行投票的发起和决议,更新系统状态;
跟随者(Follower):接受客户端请求、并将请求转发到Leader,向客户端返回结果,在选主过程中参与投票;
观察者(observer):可以接受客户端连接,将写请求转发给Leader,但不参加投票过程,只同步Leader的状态,目的是为了扩展系统,提高读取速度;
客户端(Client):请求发起方。
一个ZK集群同一时刻只会有一个Leader,其他都是Follower或Observer。默认只有Leader和Follower两种角色,没有Observer角色。为了使用Observer模式,在任何想变成Observer的节点的配置文件中加入peerType=observer
,并在所有Server的配置文件中,配置成observer模式的Server的那行配置追加:observer,例如:server.1:localhost:2888:3888:observer
在装有ZK的机器的终端执行zookeeper-server status
可查看当前节点的角色(Leader or Follower)。
集群的所有机器通过一个Leader选举过程来选定一台被称为Leader的机器,Leader服务器为客户端提供读和写服务。
Follower和Observer都能提供读服务,不能提供写服务。区别在于,Observer机器不参与Leader选举过程,也不参与写操作的『过半写成功』策略,因此Observer可以在不影响写性能的情况下提升集群的读性能。
API是ZK原生提供的命令,而客户端是基于API加以封装,旨在简化操作。本文只考虑Java客户端。
ZK提供以下API,供Client操作ZNode和其中存储的数据:
create(path, data, flags)
:创建路径为path的ZNode,在其中存储data[]
数据,flags可设置为Regular或Ephemeral,并可选打上sequential标志,父ZNode必须存在。delete(path, version)
:删除相应path及version的ZNode;必须得确保没有子ZNode,否则删除失败;exists(path,watch)
:如果存在path对应ZNode,则返回true;否则返回false,watch标志可设置监听事件getData(path, watch)
:返回对应ZNode的数据和元信息(如version等)setData(path, data, version)
:将data[]
数据写入对应path和version的ZNodegetChildren(path, watch)
:返回指定ZNode的子节点集合sync
:使客户端的ZNode视图与ZK同步;getACL/setACL
:获取ZNode的ACL,或设置ACL;更新ZK操作是有限制的。delete或setData必须明确要更新的Znode的版本号,通过exists找到。如果版本号不匹配,更新将会失败。更新ZK操作是非阻塞式的。因此客户端如果失去一个更新(由于另一个进程在同时更新这个Znode),他可以在不阻塞其他进程执行的情况下,选择重新尝试或进行其他操作。
尽管ZK可以被看做是一个文件系统,但是出于便利,摒弃一些文件系统地操作原语。因为文件非常的小并且使整体读写的,所以不需要打开、关闭或是寻地的操作。
原生客户端。
另起一篇,参考Zookeeper系列之客户端Curator。
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
最后一次release是18年10月23日,不建议使用。
解决如下问题:
ZkClient对原生API进行封装,但也有不足之处:
使用ZK的分布式选举功能开源组件包括:
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。参考微服务系列之分布式锁。
Server启动时与ZK建立会话,创建EPHEMERAL节点,Server停止时,会话终止,EPHEMERAL节点被删除。
配置信息,一般都是常数,如数据库连接池信息,通常具备以下3个特性。
推崇配置和代码分离。一般都是使用配置文件的方式,然后在代码中引入这些配置文件。早期,配置比较少,应用简单数量不多,修改配置重启应用,不是大问题。但是不适应互联网常规做法。常规做法是引入分布式配置中心,统一管理所有应用的配置文件,支持热修改。一般,不会改变的配置信息,可以放在代码中(在类私有或者类共有),或者配置文件中,变化频繁的配置信息放在配置中心。
一般有推拉两种模式:
推拉结合是值得推荐的配置生效方式。ZK采用的是推拉相结合的方式。客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知后,需要主动到服务端获取最新的数据(推拉结合)。
诸多服务的正常运行都依赖这个配置中心,所以需要保证很高的可靠性,即高可用。故而配置中心一般用集群来保证可靠性,那如何保证配置在集群中的一致性呢?
ZK使用ZAB一致性协议来提供一致性。HBase中,客户端就是连接一个ZK,获得必要的HBase集群的配置信息,然后才可以进一步操作。消息队列Kafka中,也使用ZK来维护broker的信息。Dubbo中也广泛的使用ZK管理一些配置来实现服务治理。
即Naming Service,在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体通常可以是集群中的机器,提供的服务地址列表,远程对象等——这些都可以统称为名字(Name)。
通过在ZK里创建顺序节点,能够很容易创建一个全局唯一的路径,这个路径就可以作为一个名字。ZK的命名服务即生成全局唯一的ID。
可以实现两种类型的队列:
机器间的心跳检测机制是指在分布式环境中,不同机器(或进程)之间需要检测到彼此是否在正常运行。在传统的开发中,通常是通过主机直接是否可以相互PING通来判断,更复杂一点的话,则会通过在机器之间建立长连接,通过TCP连接固有的心跳检测机制来实现上层机器的心跳检测,这些都是非常常见的心跳检测方法。
基于ZK的临时节点的特性,可以让不同的进程都在ZK的一个指定节点下创建临时子节点,不同的进程直接可以根据这个临时子节点来判断对应的进程是否存活。通过这种方式,检测和被检测系统直接并不需要直接相关联,而是通过ZK上的某个节点进行关联,大大减少系统耦合。
ZK提供一些4字命令,用于获得ZK集群中,某台ZK的角色、ZNode数、健康状态等信息;
通过ZK自带的zkCli.sh
模拟Client创建ZNode:
/usr/local/zookeeper/bin/zkCli.sh create /zookeeper/test 'test' >/dev/null 2>&1
删除ZNode:
/usr/local/zookeeper/bin/zkCli.sh delete /zookeeper/test >/dev/null 2>&1
再根据返回值判断添加、删除ZNode是否成功,从而判断该台ZK状态是否正常。
Google Chubby。ZooKeeper参考Chubby的开源实现版本。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。