文章标签: java-zookeeper zookeeper 分布式
ZooKeeper介绍
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper包含一个简单的原语集, [1] 提供Java和C的接口。
官网:https://zookeeper.apache.org
一、前期准备
准备3台机器,一样系统(cent os7),安装同样的jdk;关闭防火前;SSH无密登录配置好。
集群部署规划
名称 | 角色 | 地址 | 编号(myid) |
hadoop130 | 节点 | 192.168.64.130 | 1 |
hadoop131 | 节点 | 192.168.64.131 | 2 |
hadoop132 | 节点 | 192.168.64.132 | 3 |
准备zookeeper压缩包
apache-zookeeper-3.8.2-bin.tar.gz
二、加压并配置
2.1》解压
tar -zxvf apache-zookeeper-3.8.2-bin.tar.gz
mv apache-zookeeper-3.8.2-bin /opt/module
2.2》修改配置文件
a>在apache-zookeeper-3.8.2-bin目录下创建一个tmp目录
编辑myid文件内容为1
echo 1>myid
b>修改zoo.cfg文件
apache-zookeeper-3.8.2-bin/conf/
cp zoo_sample.cfg zoo.cfg
#将dataDir后边的路径修改为自己tmp 的路径,此处为
dataDir=/opt/module/apache-zookeeper-3.8.2-bin/tmp
#继续添加如下内容:
server.1= hadoop130:2888:3888
server.2= hadoop131:2888:3888
server.3= hadoop132:2888:3888
2.3》修改环境变量
vi /etc/profile
增加zooKeeper环境
export ZOOKEEPER_HOME=/opt/module/apache-zookeeper-3.8.2-bin
export PATH=$ZOOKEEPER_HOME/bin:$PATH
2.4》把zookeeper拷贝到另外两台机器上
scp -r apache-zookeeper-3.8.2-bin hadoop131:/opt/module
scp -r apache-zookeeper-3.8.2-bin hadoop132:/opt/module
修改hadoop131机器上myid文件内容为2
修改hadoop132机器上myid文件内容为3
三、启动集群
在hadoop130上编辑一键启动集群文件zkStart-all.sh
for host in hadoop130 hadoop131 hadoop132
do
ssh $host "source /etc/profile;nohup zkServer.sh start "
echo "$host zk is running"
done
在hadoop130上编辑一键停止集群文件zkStop-all.sh
for host in hadoop130 hadoop131 hadoop132
do
ssh $host "source /etc/profile; zkServer.sh stop"
echo "$host zk is stopping"
done
启动集群
zkStart-all.sh
四、测试集群
1》查看进程
在hadoop130上编辑一键查询集群状态文件zkJps-all.sh
#zk status
echo '---------------------查看集群状态---------------'
for i in hadoop130 hadooop131 hadoop132
do
echo ${i} '的节点状态'
ssh ${i} /usr/local/jdk1.8.0_381/bin/jps
done
运行 zkJps-all.zh
2》查看集群状态
在每台机器上查看状态(一个leader,两个follower)
zkServer.sh status
leader
follower
follower
3》客户端操作
客户端连接
zkCli.sh -server hadoop130:2181
出现
创建节点 查看
create /zk-testp 123
ls /zk-testp
get /zk-testp
stat /zk-testp
退出客户端
quit
五、总结
1》配置文件中参数说明:
tickTime=2000 ##Client-Server通信心跳时间,单位是毫秒
initLimit=10 ##集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数
syncLimit=5 ##集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数
clientPort=2181 ## 监听端口
maxClientCnxns=100 ## 最大连接数
dataDir=/opt/module/zookeeper-3.8.2/data ## 数据目录
dataLogDir=/opt/module/zookeeper-3.8.2/log ## 日志目录
tickTime这个时间是作为zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是说每个tickTime时间就会发送一个心跳。
initLimit这个配置项是用来配置zookeeper接受客户端(这里所说的客户端不是用户连接zookeeper服务器的客户端,而是zookeeper服务器集群中连接到leader的follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过10个心跳的时间(也就是tickTime)长度后 zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 10*2000=20秒。
syncLimit这个配置项标识leader与follower之间发送消息,请求和应答时间长度,最长不能超过多少个tickTime的时间长度,总的时间长度就是5*2000=10秒。
dataDir顾名思义就是zookeeper保存数据的目录,默认情况下zookeeper将写数据的日志文件也保存在这个目录里;
clientPort这个端口就是客户端连接Zookeeper服务器的端口,Zookeeper会监听这个端口接受客户端的访问请求;
2》集群选择说明:
ZooKeeper能够完成选举即能够正常对外提供服务。ZooKeeper选举时,当某一个实例获得了半数以上的票数时,则变为leader。对于n个实例的服务,n可能为奇数或偶数。n为奇数时,假定 n=2X+1,则成为leader的节点需获得x+1票,容灾能力为x。n为偶数时,假定 n=2X+2,则成为leader的节点需要获得x+2票 (大于一半),容灾能力为x。
3》端口
配置文件中
#server.2代表myid=2的服务器
#2888: Leader和Flower的通信端口
#3888: 如果集群中唯一的Leader挂了,通过这个端口来重新选举Leader
clientPort=2181 # 客户端端口号
admin.serverPort=8080 #AdminServer端口
2888端口用于follower调用leader进行写操作,3888端口为选主使用端口,2181端口为客户端连接zk服务节点端口。
4》zk选举
如果leader宕机或者zookeeper启动时初始化,就会发生选举机制,各个节点会传递票据
票据
epoch:票据是否过期
zxid:要推举节点的事务id
myid:要推举节点的节点id
每个zookeeper的节点都需要将票据传递给其他节点,刚开始的选举都是选择自己作为节点,最后选择收到票数最多的节点作为leader。
六、zookeeper基本操作
1:Zookeeper的客户端命令
2:Zookeeper的java的api操作
1>Zookeeper的数据结构
ZooKeeper 的数据模型是层次模型。层次模型常见于文件系统。例如:我的电脑可以分为多个盘符(例如C、D、E等),每个盘符下可以创建多个目录,每个目录下面可以创建文件,也可以创建子目录,最终构成了一个树型结构。通过这种树型结构的目录,我们可以将文件分门别类的进行存放,方便我们后期查找。而且磁盘上的每个文件都有一个唯一的访问路径。
ZooKeeper 的层次模型称作data tree。Datatree 的每个节点叫作znode(Zookeeper node)。不同于文件系统,每个节点都可以保存数据。每个节点都有一个版本(version)。版本从0 开始计数。
2>节点的分类
持久性 临时性
(一):一个znode可以是持久性的,也可以是临时性的
持久性znode[PERSISTENT],这个znode一旦创建不会丢失,无论是zookeeper宕机,还是client宕机。
临时性的znode[EPHEMERAL],如果zookeeper宕机了,或者client在指定的timeout时间内没有连接server,都会被认为丢失。 -e
顺序
(二):znode也可以是顺序性的,每一个顺序性的znode关联一个唯一的单调递增整数。这个单调递增整数是znode名字的后缀。
持久顺序性的znode(PERSISTENT_SEQUENTIAL):znode 处理具备持久性的znode的特点之外,znode的名称具备顺序性。 -s
临时顺序性的znode(EPHEMERAL_SEQUENTIAL):znode处理具备临时性的znode特点,znode的名称具备顺序性。-s
3>客户端命令(创建、查询、修改、删除)
运行ZooKeeper命令行客户端
执行zkCli.sh -server 192.168.64.130:2181命令,运行ZooKeeper命令行客户端
3.1、查询所有命令
help
3.2、查询跟路径下的节点
ls /zookeeper
3.3、创建普通永久节点
create /app1 "helloworld"
创建app1节点,值为helloworld
3.4、创建带序号永久节点
create -s /hello "helloworld"
3.5、创建普通临时节点
create -e /app3 'app3'
-e:表示普通临时节点
关闭客户端,再次打开查看 app3节点消失
3.6、创建带序号临时节点
create -e -s /app4 'app4'
-e:表示普通临时节点
-s:表示带序号节点
关闭客户端,再次打开查看 app4节点消失
3.7、查询节点数据
get /app1
3.8、修改节点数据
set /app1 'hello'
3.9、删除节点
delete /hello0000000006
3.10、递归删除节点
delete /hello
rmr /hello
3. 11、查看节点状态
stat /zookeeper
4>Zookeeper的java的api介绍(创建、查询、修改、删除)
原生Java API(不推荐使用)
ZooKeeper 原生Java API位于org.apache.ZooKeeper包中
ZooKeeper-3.x.x. Jar (这里有多个版本)为官方提供的 java API
Apache Curator(推荐使用)
Apache Curator是 Apache ZooKeeper的Java客户端库。
Curator.项目的目标是简化ZooKeeper客户端的使用。
另外 Curator为常见的分布式协同服务提供了高质量的实现。
Apache Curator最初是Netflix研发的,后来捐献了 Apache基金会,目前是 Apache的顶级项目
ZkClient(不推荐使用)
Github上一个开源的ZooKeeper客户端,由datameer的工程师Stefan Groschupf和Peter Voss一起开发。 zkclient-x.x.Jar也是在源生 api 基础之上进行扩展的开源 JAVA 客户端。
5>Zookeeper的watch机制
NodeCache PathChildrenCache TreeCache
zookeeper作为一款成熟的分布式协调框架,订阅-发布功能是很重要的一个。所谓订阅发布功能,其实说白了就是观察者模式。观察者会订阅一些感兴趣的主题,然后这些主题一旦变化了,就会自动通知到这些观察者。
zookeeper的订阅发布也就是watch机制,是一个轻量级的设计。因为它采用了一种==推(服务端通知应用)拉(客户端获取服务端数据)==结合的模式。一旦服务端感知主题变了,那么只会发送一个事件类型和节点信息给关注的客户端,而不会包括具体的变更内容,所以事件本身是轻量级的,这就是所谓的“推”部分。然后,收到变更通知的客户端需要自己去拉变更的数据,这就是“拉”部分。watche机制分为添加数据和监听节点。
Curator在这方面做了优化,Curator引入了Cache的概念用来实现对ZooKeeper服务器端进行事件监听。Cache是Curator对事件监听的包装,其对事件的监听可以近似看做是一个本地缓存视图和远程ZooKeeper视图的对比过程。而且Curator会自动的再次监听,我们就不需要自己手动的重复监听了。
Curator中的cache共有三种
NodeCache(监听和缓存根节点变化) 只监听单一个节点(变化 添加,修改,删除)
PathChildrenCache(监听和缓存子节点变化) 监听这个节点下的所有子节点(变化 添加,修改,删除)
TreeCache(监听和缓存根节点变化和子节点变化) NodeCache+ PathChildrenCache 监听当前节点及其下的所有子节点的变化。
七、Zk特性
zk拥有以下几个重要特性:
1)顺序一致性:来自客户端的相关指令会按照顺序执行,不会出现乱序的情况,客户端发送到服务的指令1->2->3->4,那个这些指令就会按照顺序执行;
2)原子性:更新只有成功和失败,没有中间状态;
3)可靠性:也可以称之为持久性,节点更新以后,在下次更新之前,它的数据不会发生变更;
4)准实时性:也可以称之为最终一致性,在zk集群中,一个客户端修改了其中的一个节点,一定时间以后,所有可用的服务对应的节点都会变成更新以后的值。