一、zookeeper的应用场景
zookeeper是一个分布式的统一文件协调管理系统管理系统。它的数据类型与linux、unix类似,是一棵树的结构。在日常的生产开发生产中,它具有以下的作用。
1、集群管理,保证集群中的数据的强一致性。
如下图,就是一个zookeeper的集群模型,它有三个节点分别是xx,yy,zz。xx为集群中的master,yy和zz分为为slave1和slave2.三个节点中的数据保持一致性,现在加入说master节点挂掉了,那么yy和zz就会进行master的选举。如果说zz被选中,那么它就会成为新的master节点,yy则仍然为slave1节点。那么集群模式就会变成如下图右所示的模式。加入说这个时候之前挂掉的master节点重启了或者被运维人员修复了,那么它就会变成新的salve2节点。
2、统一文件配置管理
ZooKeeper 中特有 Watcher 注册与异步通知机制,能够很好的实现分布式环境下不同机器,甚至不同系统之间的通知与协调,从而实现对数据变更的实时处理。使用方法通常是不同的客户端如果 机器节点 发生了变化,那么所有订阅的客户端都能够接收到相应的Watcher通知,并做出相应的处理。
ZooKeeper的分布式协调/通知,是一种通用的分布式系统机器间的通信方式。
3、发布订阅,类似于mq。dubbo把消息存放在znode上,订阅者读取这个消息。
数据发布与订阅,即所谓的配置中心,顾名思义就是发布者将数据发布到 ZooKeeper 节点上,供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中式管理和动态更新。
对于:数据量通常比较小。数据内容在运行时动态变化。集群中各机器共享,配置一致。
这样的全局配置信息就可以发布到 ZooKeeper上,让客户端(集群的机器)去订阅该消息。
发布/订阅系统一般有两种设计模式,分别是推(Push)和拉(Pull)模式。
- 推模式
服务端主动将数据更新发送给所有订阅的客户端 - 拉模式
客户端主动发起请求来获取最新数据,通常客户端都采用定时轮询拉取的方式
ZooKeeper 采用的是推拉相结合的方式:
客户端想服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知后,需要主动到服务端获取最新的数据
4、提供分布式锁,分布式环境中不同进程之间进行资源争夺,类似于多线程之间的锁。
分布式锁是控制分布式系统之间同步访问共享资源的一种方式 分布式锁又分为排他锁和共享锁两种排它锁
ZooKeeper如何实现排它锁?
定义锁
ZooKeeper 上的一个 机器节点 可以表示一个锁
获得锁
把ZooKeeper上的一个节点看作是一个锁,获得锁就通过创建临时节点的方式来实现。
ZooKeeper 会保证在所有客户端中,最终只有一个客户端能够创建成功,那么就可以
认为该客户端获得了锁。同时,所有没有获取到锁的客户端就需要到/exclusive_lock
节点上注册一个子节点变更的Watcher监听,以便实时监听到lock节点的变更情况。
释放锁
因为锁是一个临时节点,释放锁有两种方式
当前获得锁的客户端机器发生宕机或重启,那么该临时节点就会被删除,释放锁正常执行完业务逻辑后,客户端就会主动将自己创建的临时节点删除,释放锁。无论在什么情况下移除了lock节点,ZooKeeper 都会通知所有在 /exclusive_lock 节点上注册了节点变更 Watcher 监听的客户端。这些客户端在接收到通知后,再次重新发起分布式锁获取,即重复『获取锁』过程。
ZooKeeper如何实现共享锁
共享锁在同一个进程中很容易实现,但是在跨进程或者在不同 Server 之间就不好实现了。Zookeeper 却很容易实现这个功能,实现方式也是需要获得锁的 Server 创建一个EPHEMERAL_SEQUENTIAL 目录节点,然后调用 getChildren方法获取当前的目录节点列表中最小的目录节点是不是就是自己创建的目录节点,如果正是自己创建的,那么它就获得了这个锁,如果不是那么它就调用 exists(String path, boolean watch) 方法并监控Zookeeper 上目录节点列表的变化,一直到自己创建的节点是列表中最小编号的目录节点,从而获得锁,释放锁很简单,只要删除前面它自己所创建的目录节点就行了。
5、节点选举
针对 Master 选举的需求,通常情况下,我们可以选择常见的关系型数据库中的主键特性来实现:希望成为 Master 的机器都向数据库中插入一条相同主键ID的记录,数据库会帮我们进行主键冲突检查,也就是说,只有一台机器能插入成功——那么,我们就认为向数据库中成功插入数据的客户端机器成为Master。
依靠关系型数据库的主键特性确实能够很好地保证在集群中选举出唯一的一个Master。 但是,如果当前选举出的 Master 挂了,那么该如何处理?谁来告诉我 Master 挂了呢?
显然,关系型数据库无法通知我们这个事件。但是,ZooKeeper 可以做到!
利用 ZooKeepr 的强一致性,能够很好地保证在分布式高并发情况下节点的创建一定能够保证全局唯一性,即 ZooKeeper 将会保证客户端无法创建一个已经存在的 数据单元节点。
也就是说,如果同时有多个客户端请求创建同一个临时节点,那么最终一定只有一个客户端请求能够创建成功。利用这个特性,就能很容易地在分布式环境中进行 Master 选举了。
成功创建该节点的客户端所在的机器就成为了 Master。同时,其他没有成功创建该节点的客户端,都会在该节点上注册一个子节点变更的 Watcher,用于监控当前 Master 机器是否存活,一旦发现当前的Master挂了,那么其他客户端将会重新进行 Master 选举。
这样就实现了 Master 的动态选举。
二、zookeeper单机集群部署
安装zookeeper需要安装jdk,因此首先我们先安装jdk。
1、官网下载jdk,上传到服务器上。
2、[root@nlfd home]# mv jdk-8u201-linux-x64.tar.gz /usr/local/
[root@nlfd local]# tar -zxvf jdk-8u201-linux-x64.tar.gz
3、配置环境变量
[root@nlfd jdk1.8.0_201]# vi /etc/profile
增加如下几行
export JAVA_HOME=/usr/local/jdk1.8.0_201
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
source /etc/profile
4、java -version
安装zookeeper
1、下载zookeeper安装包上传到服务器。
2、[root@nlfd local]# tar -zxvf zookeeper-3.4.9.tar.gz
[root@nlfd local]# mv zookeeper-3.4.9 zookeeper
3、vi /etc/profile 配置环境变量,加入如下内容
export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin:${JAVA_HOME}/bin
source /etc/profile
4、zookeeper配置
[root@nlfd zookeeper]# cd /usr/local/zookeeper/conf/
[root@nlfd conf]# cp zoo_sample.cfg ./zoo.cfg
[root@nlfd conf]# vi zoo.cfg
dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir
[root@nlfd zookeeper]# cd /usr/local/zookeeper
[root@nlfd zookeeper]# mkdir dataDir
[root@nlfd zookeeper]# mkdir dataLogDir
[root@nlfd zookeeper]# cd /usr/local/zookeeper/dataDir/
[root@nlfd dataDir]# vim myid
设置为1
5、拷贝两份zookeeper分别命名为zookeeper02和zookeeper03
[root@nlfd local]# cp zookeeper zookeeper02 -rf
[root@nlfd local]# cp zookeeper zookeeper03 -rf
6、修改配置文件
[root@nlfd local]# cd /usr/local/zookeeper/conf/
![](https://s1.51cto.com/images/blog/201903/03/e6e3e4266b73b8cb5ccebba5c8578658.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
[root@nlfd conf]# vi /usr/local/zookeeper02/conf/zoo.cfg
修改如下配置:
[root@nlfd dataDir]# cd /usr/local/zookeeper02/dataDir/
[root@nlfd dataDir]# vi myid
设置为2
[root@nlfd conf]# vi /usr/local/zookeeper03/conf/zoo.cfg
修改如下配置:
[root@nlfd dataDir]# cd /usr/local/zookeeper03/dataDir/
[root@nlfd dataDir]# vi myid
设置为3
7、启动
[root@nlfd dataDir]# cd /usr/local/zookeeper/bin/
[root@nlfd bin]# ./zkServer.sh start
[root@nlfd bin]# cd /usr/local/zookeeper02/bin/
[root@nlfd bin]# ./zkServer.sh start
[root@nlfd bin]# cd /usr/local/zookeeper03/bin/
[root@nlfd bin]# ./zkServer.sh start
8、检验
连接第一台节点
./zkCli.sh -server 192.168.0.104:2181
设置一个node值
[zk: localhost:2181(CONNECTED) 1] create /testAsync helloworld
[zk: localhost:2181(CONNECTED) 5] ls /
[testAsycn, zookeeper]
连接第二台节点
./zkCli.sh -server 192.168.0.104:2182
连接第三台节点
./zkCli.sh -server 192.168.0.104:2183
至此,简单的单机版三节点zookeeper集群已经安装成功。至于选举模式的配置安装,后续再研究。
原文地址:https://blog.51cto.com/12122148/2357447