一、什么是ZooKeeper
Zookeeper是一个开源的分布式协同服务系统。Zookeeper的设计目标是将那些复杂且容易出错的分布式协同服务封装起来,抽象出一个高效可靠的原语集,并以一系列简单的接口提供给用户使用。
使用Zookeeper著名的开源项目:
Hadoop Hbase Kafka
二、Zookeeper应用场景
1、配置管理
2、DNS服务
3、组成员管理
4、各种分布式锁
即:Zookeeper适用于存储和协同相关的关键数据,不适用于大数据量存储
三、Zookeeper服务的使用
各个application使用Zookeeper客户端库使用Zookeeper服务。
Zookeeper客户端负责和Zookeeper集群的交互。
四、Zookeeper数据模型
Zookeeper的数据模型是层次模型,层次模型常见于文件系统。层次模型和KV模型是两种主流的数据模型。Zookeeper使用文件系统模型主要基于以下几点考虑;
1、文件系统的树型结构便于表达数据之间的层次关系;
2、文件系统的树型结构便于为不同的应用分配独立的命名空间
Zookeeper的层次模型叫做data tree。Data tree的每个节点叫做znode。不同于文件系统,每个节点都可以保存数据。每个节点都有一个版本(version)。版本从0开始计数。
五、data tree示例
在下图中data tree有两颗子树,一个是/Data1,另外一个是/Data2。
/Data2的子树实现了一个简单的组成员协议:每个客户端进程创建一个Znode节点s*在/Data2下面,只要/Data2/s*节点存在就代表进程在正常运行。
六、data tree接口
Zookeeper对外提供一个用来访问data tree的简化文件系统API:
1、使用UNIX风格的路径名来定位znode,例如/X/Y/Z表示znode X的子节点Y的子节点Z;
2、znode的数据只支持全量写入和读取,没有像通用文件系统那边支持部分写入和读取;
3、data tree的所有API都是wait-free的,正在执行中的API调用不会影响其他API的完成;
4、data tree的API都是对文件系统的wait-free操作,不直接提供锁这样的分布式系统机制。但是data tree的API非常强大,可以用来实现多种分布式协同机制。
七、znode 4种分类
一个znode节点可以是持久性的,也可以是临时性的;
znode节点也可以是顺序性的。每一个顺序性的znode关联一个唯一的单调递增整数,这个单调递增整数是znode名字的后缀;
所以总共有四种znode:
1、持久性的PERSISTENT znode:该类型节点在创建之后即使Zookeeper集群宕机或者client宕机也不会丢失数据;
2、临时性的EPHEMERAL znode:client宕机或者client在设定的timeout时间内没有给ZooKeeper集群发消息,该类型的节点就会丢失;
3、持久顺序性的PERSISTENT_SEQUENTIAL znode:具备持久性和名字具有顺序性的特点;
4、临时顺序性的EPHEMERAL_SEQUENTIAL znode:具备临时性和名字具有顺序性的特点。
八、安装ZooKeeper
1、ZooKeeper唯一的依赖是JDK7+;
2、到https://zookeeper.apache.org/下载ZooKeeper,我用的是apache-zookeeper-3.6.0-bin.tar.gz;
3、把apache-zookeeper-3.6.0-bin.tar.gz解压到本地目录/usr/local/softwares;
4、把zoo.cfg.example重命名为zoo.cfg;
5、配置系统环境变量vi ~/.bash_profile
export ZOOKEEPER_HOME=/usr/local/softwares/zookeeper/apache-zookeeper-3.6.0-bin/bin
export PATH=$ZOOKEEPER_HOME:$JAVA_HOME/bin:$PATH
九、启动Zookeeper
1、zkServer.sh start启动服务
2、进入/usr/local/softwares/zookeeper/apache-zookeeper-3.6.0-bin/logs路径,执行grep -E -i "((exception)|(error))" *查询日志文件是否有报错,正常情况下无内容输出
3、zkCli.sh启动客户端
4、常用命令
ZooKeeper -server host:port cmd args
addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] - default is PERSISTENT_RECURSIVE
addauth scheme auth
close
config [-c] [-w] [-s]
connect host:port
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
delete [-v version] path
deleteall path [-b batch size]
delquota [-n|-b] path
get [-s] [-w] path
getAcl [-s] path
getAllChildrenNumber path
getEphemerals path
history
listquota path
ls [-s] [-w] [-R] path
printwatches on|off
quit
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
redo cmdno
removewatches path [-c|-d|-a] [-l]
set [-s] [-v version] path data
setAcl [-s] [-v version] [-R] path acl
setquota -n|-b val path
stat [-w] path
sync path
version十、一个栗子-实现分布式锁
开两个终端:
1、终端1执行步骤1,创建临时节点/lock;
2、终端2执行步骤2,创建临时节点/lock失败;
3、终端2执行步骤3,监控/lock节点,即监听锁是否释放;
4、终端1执行步骤4,会删除/lock;
5、终端2执行步骤5,创建节点/lock成功
十一、master-worker架构
master-work是一个广泛使用的分布式架构。master-work架构中有一个master负责监控worker的状态,并为worker分配任务。
1、在任务时刻,系统中最多只能有一个master,不可以出现两个master的情况,多个master共存会导致脑裂;
2、系统中除了处于active状态的master还有一个backup master,如果active master失败了,backup master可以很快的进入active状态;
3、master实时监控worker的状态,能够及时收到worker成员变化的通知。master在收到worker成员变化的时候,通常重新进行任务的重新分配。
如上图所示:
1、使用一个临时节点/master表示master。在集群初始化的时候,集群的各个机器会创建这个/master znode,但是只会有一个创建成功,进入active状态,成为master。否则,进入backup状态,使用watch机制监听/master。假设系统中有一个active master和一个backup master,如果active master失败,那么它创建的/master就会被zookeeper自动删除。此时backup master就会收到通知,并且通过再次创建/master节点成为新的active master;
2、worker通过在/workers下面创建临时节点来加入集群;
3、处于active状态的master会通过watch机制监听/workers下面znode列表来实时获取worker成员的变化。
十二、Zookeeper总体架构
application可以通过zookeeper客户端库使用zookeeper服务。
zookeeper集群有两种模式: standalone和quorum模式。前者有一个独立运行的zookeeper节点,后者包含多个zookeeper节点。
十三、Session
zookeeper客户端库和zookeeper集群中的某个节点创建一个session。
session关闭的场景:
1、客户端可以主动关闭session;
2、如果zookeeper节点没有在session关联的timeout时间内收到客户端的消息的话,zookeeper节点也会关闭session;
3、zookeeper客户端库如果发现连接的zookeeper出错,会自动和其他zookeeper节点建立连接。
如上图所示,本来客户端库和节点1建立的连接,假如节点1down了之后,客户端库就会重新建立session连接,此时和节点3自动建立了连接。
十四、 Quorum模式
Quorum模式的ZooKeeper集群包含多个ZooKeeper节点。即会有一个leader节点,多个follower节点。leader节点可以处理读写请求,follower只可以处理读请求。follower在接到写请求时会把写请求转发给leader来处理。
十五、数据一致性
全局可线性化Linearizable写入:先到达leader的写请求会被先处理,leader决定写请求的执行顺序。
客户端FIFO顺序:来自给定客户端的请求按照发送顺序执行。