ZooKeeper环境搭建
一、ZooKeeper简介
在分布式领域,一个不可或缺的组件,便是ZooKeeper。
ZooKeeper是一个高可用的分布式数据管理和协调框架,并且能够很好的保证分布式环境中数据的一致性。
ZooKeeper由Yahoo公司创建,是Google Chubby的开源实现。Chubby的一致性以Paxos算法为基础,而ZK采用的是Paxos协议的变种一一ZAB(ZooKeeper Atomic Broadcast protocol,全称为:ZooKeeper 原子消息广播协议)。
ZooKeeper主要的应用场景包括:数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁、分布式队列等。目前,在越来越多的分布式系统(Hadoop、HBase、Storm、Kafka)中,Zookeeper都作为核心组件使用。
Server主要两个角色:Leader、Follower。
-
Leader:负责进行投票的发起和决议,更新系统状态;
-
Follower:接收客户端请求并向客户端返回结果,在选举过程中参与投票;
ZooKeeper名字趣闻。在立项初期,考虑到之前内部很多项目都是使用动物的名字来命名的(例如著名的Pig项目),雅虎的工程师希望给这个项目也取一个动物的名字。时任研究院的首席科学家RaghuRamakrishnan开玩笑地说:“在这样下去,我们这儿就变成动物园了!”此话一出,大家纷纷表示就叫动物园管理员吧一一因为各个以动物命名的分布式组件放在一起,雅虎的整个分布式系统看上去就像一个大型的动物园了,而Zookeeper正好要用来进行分布式环境的协调一一于是,Zookeeper的名字也就由此诞生了。
扫描二维码关注公众号,回复: 13829342 查看本文章
二、ZooKeeper安装
ZooKeeper的部署方式有以下两种:
- 独立模式(单机模式):开发环境中使用,单服务器
- 集群模式(多服务器模式):生产环境中使用,服务器个数为奇数
ZK为什么设置为奇数个?
zookeeper有这样一个特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的。也就是说如果有2个zookeeper服务器,只要有1个服务器挂掉,则整个zookeeper集群将不能使用,因为1没有过半,所以2个zookeeper服务器的错误容忍度为0;同理,要是有3个zookeeper,一个挂掉,还剩下2个正常工作,个数过半,所以3个zookeeper的容忍度为1;同理你多列举几个:2 -> 0; 3 -> 1; 4 - >1; 5 -> 2; 6 -> 2会发现一个规律,2n和2n-1的容忍度是一样的,都是n-1,所以为了更加高效,何必增加一个不必要的zookeeper呢。
由此可知,ZK集群的服务器个数最少为3个。
0. 准备工作
需求清单:
-
操作系统:Ubuntu-18.04
如果需要该操作系统的安装步骤可以参考:虚拟机安装(保姆级教程)
-
ZooKeeper 3.7.0
官网下载地址:https://zookeeper.apache.org/releases.html
-
JDK:JDK1.8
ZooKeeper基于JVM运行,本文安装的ZK要求JDK版本为1.8及以上(JDK 8 LTS, JDK 11 LTS, JDK 12; Java 9 和 10两个版本不支持 )
官网下载地址: http://java.sun.com/javase/downloads/index.jsp
为了照顾基础用户,所需软件都放置于百度网盘
链接:https://pan.baidu.com/s/1kjcuNNCY2FxYA5o7Z2tgkQ 提取码:nuli
官方给出的安装步骤:
1)安装JDK
2)设置Java heap size(Java堆栈大小)
这是为了避免发生内存交换而影响ZooKeeper性能的重要步骤。要确定正确的值,需要进行负载测试,并确保远远低于导致交换的使用限制
3)安装ZooKeeper
4)创建配置文件,文件名可以随便取,建议将配置文件放于ZooKeeper的conf目录下,命名为zoo.cfg,这样便于在启动服务时不用指定配置文件。
完成如下配置:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper/
clientPort=2181
maxClientCnxns=60
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
参数说明:
参数 | 默认值 | 说明 |
---|---|---|
tickTime | 2000 | Client-Server通信心跳时间 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。tickTime以毫秒为单位。 |
initLimit | 10 | Leader-Follower初始通信时限 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)。 |
syncLimit | 5 | Leader-Follower同步通信时限 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)。 |
dataDir | /tmp/zookeeper | 数据文件目录 Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里。 |
clientPort | 2181 | 客户端连接端口 客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。 |
maxClientCnxns | 60 | 最多支持的客户端连接数 |
server.id=host:port:port | 集群信息(服务器编号,服务器地址,LF通信端口,选举端口) 这个配置项的书写格式比较特殊,规则如下: server.N=YYY:A:B, 其中N用来表示服务器在集群中的一个序号,我们需要在dataDir目录下创建一个文件 myid , 文件内容为对应的编号NA为端口号,集群内机器通讯使用(只有Leader监听此端口 B为端口号,用于选举Leader使用(每个Zookeeper都监听此端口) |
关于参数的更多信息可参考:https://zookeeper.apache.org/doc/r3.7.0/zookeeperAdmin.html#sc_configuration
5)创建myid文件
在上一步设置的dataDir目录中创建myid
文件。
myid
文件标识了该服务器在集群中的唯一ID号,该文件内容就是对应的ID号。
ID大小介于1至255,如果开启了扩展特征,比如TTL节点,ID需要介于1至254
6)创建初始标识文件initialize
initialize
文件位于dataDir目录中,当启动一个新集群时,创建该文件。
7)采用如下方式启动ZooKeeper服务
$ java -cp zookeeper.jar:lib/*:conf org.apache.zookeeper.server.quorum.QuorumPeerMain zoo.conf
1. 单机模式
单机模式是初学者或者资源受限的用户首先的方式。本文主要介绍ZK的单机模式安装。
假设当前用户名为xiaobai
(如果你的用户名不是xiaobai,可以采取两种方式:一是创建xiaobai用户,二是结合自己的用户名修改相应配置即可),结合官方给出的安装步骤,我们按如下步骤进行安装 :
1)安装JDK
如果已经安装,跳过
约定:
将需要的安装包上传或者下载到Home目录下的soft目录
~/soft
安装目录位于Home目录下的opt目录
~/opt
将jdk上传到~/soft
目录,确保文件已经上传,输入命令ls ~/soft
进入验证
接下来解压文件
mkdir ~/opt
tar -xvf ~/soft/jdk-8u261-linux-x64.tar.gz -C ~/opt
设置软连接
cd ~/opt
ln -s jdk1.8.0_261/ jdk
配置环境变量,打开bash配置文件
cd
vi .bashrc
按i
进入插入模式,在末尾添加如下代码,然后按esc
退出编辑,输入:x
保存
export JAVA_HOME=/home/xiaobai/opt/jdk
export PATH=$PATH:$JAVA_HOME/bin
输入以下命令使修改生效,可用java
命令验证配置是否成功
source .bashrc
java
2)安装ZooKeeper
(1)上传从百度网盘上下载的ZooKeeper安装包apache-zookeeper-3.7.0-bin.tar.gz
至~/soft
目录
当然你也可以从官网复制下载链接,使用wget
命令下载。
确保文件已经上传,输入命令ls ~/soft
进入验证
(2)解压文件ZooKeeper安装包到~/opt
目录
tar -xvf ~/soft/apache-zookeeper-3.7.0-bin.tar.gz -C ~/opt
ls ~/opt/apache-zookeeper-3.7.0-bin
(3)创建软链接
cd ~/opt
ln -s apache-zookeeper-3.7.0-bin zookeeper
- bin目录包括可执行脚本,比如常用的zkServer.sh、zkCli.sh
- conf目录包括配置文件
- docs目录包含相关文档
- lib目录包含相关的jar包
(4)修改配置文件-
cd ~/opt/zookeeper/conf
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg
修改dataDir
的值为/home/xiaobai/opt/zookeeper/tmp
注意,对于小白,如果不想用vi命令,可以使用
sudo gedit ~/opt/zookeeper/conf/zoo.cfg
打开类似windows上的记事本进行文件的编辑,后面类似情况自行处理。vi命令简单使用方式:进入文件后,输入字母
i
进入插入模式 => 修改文件内容为node1 => 按Esc
键进入命令行模式 => 输入:
进入底行模式 => 输入x
或者wq
保存推出。如果文件修改后不想保存,进行底行模式后输入
q!
进行不保存退出。
3)配置环境变量
vi ~/.bashrc
在文件末尾增加下面内容:
export ZOOKEEPER_HOME=/home/xiaobai/opt/zookeeper
export PATH=$ZOOKEEPER_HOME/bin:$PATH
使环境变量生效:
source ~/.bashrc
4)启动Zookeeper
zkServer.sh start
查看进程
输入命令jps
查看是否启动成功
查看状态
输入命令 zkServer.sh status
查看状态
5)客户端连接
访问方式:
-
通过客户端工具:
-
命令行工具: zkCli.sh
-
界面工具:ZooInspector
下载地址:https://issues.apache.org/jira/secure/attachment/12436620/ZooInspector.zip
同样也可以在前面提供的百度网盘中下载。
-
-
通过通过Jave API
这里以命令行工具zkCli.sh进行简单的演示,
(1)启动客户端
zkCli.sh -server localhost:2181
(2)创建节点
create /test 888
create -s /test/lock 666
create -s /test/lock 666
(3)查看节点
ls /
ls -s /tset
ZooKeeper维护着一个树形层次结构,树中节点称为znode ,每个znode上都会保存自己的数据内容,同时会保存一系列属性信息。每个Znode其有一个唯一的路径标识;需要注意的是znode数据不能超1MB。
ZooKeeper的目录树可以通过工具ZooInspector可以查看。
通过命令
ls -s path
的方式可以查看详细的节点信息,下面就上面的信息做简单解释:
[lock0000000000, lock0000000001] //指该目录下有哪些节点
cZxid = 0xd //Created ZXID,表示该ZNode被创建时的事务ID
ctime = Thu Dec 16 20:52:57 CST 2021 //Created Time,表示该ZNode被创建的时间
mZxid = 0xd //Modified ZXID,表示该ZNode最后一次被更新时的事务ID
mtime = Thu Dec 16 20:52:57 CST 2021 //Modified Time,表示该节点最后一次被更新的时间
pZxid = 0xf //表示该节点的子节点列表最后一次被修改时的事务ID。注意,只有子节点列表变更了才会变更pZxid,子节点内容变更不会影响pZxid。
cversion = 2 //子节点的版本号
dataVersion = 0 //数据节点的版本号
aclVersion = 0 //ACL版本号
ephemeralOwner = 0x0 //创建该节点的会话的seddionID。如果该节点是持久节点,那么这个属性值为0。
dataLength = 3 //数据内容的长度
numChildren = 2 //子节点的个数
(4)删除节点
delete /test/local0000000001
deleteall /test
ls
(5)退出客户端
quit
下面列出了常用的命令
分类 | 命令 | 描述 |
帮助 | help | 查看帮助 |
创建节点 | create | create [-s] [-e] path data acl 其中,-s或-e分别指定节点特性,顺序或临时节点,若不指定,则表示持久节点;acl用来进行权限控制 |
读取节点 | ls | ls path [watch] |
get | get path [watch] | |
ls2 | ls2 path [watch] | |
stat | stat path [watch] 获取节点的状态信息 | |
更新节点 | set | set path data [version] data就是要更新的新内容,version表示数据版本 |
删除节点 | delete | delete path [version] |
deleteall | 是一个递归删除命令 | |
同步 | sync | 使客户端的Znode视图与Zookeeper同步 |
ACL | getACL/setACL | 为Znode获取/设置ACL |
配额 | setquota | 设置子节点个数以及数据长度的配额 setquota –n 4 /zookeeper/node 设置/zookeeper/node 子节点个数最大为4 |
delquota | delquota命令用于删除配额, -n为子节点个数, -b为节点数据长度,如:delquota –n 2 | |
listquota | 命令用于显示配额,如listquota /storm | |
操作历史 | history/redo | history用于列出最近的命令历史,redo命令用于再次执行某个命令,使用方式为redo cmdid 如 redo 20 |
会话 | connect | 连接服务器 |
close | 关闭当前连接,可用connect 再次连接,不会退出客户端 | |
quit | 关闭连接并退出连接客户端 |
2. 集群模式
集群模式这里只做简单介绍,假设有三台服务器node1
、node2
、node3
在单机模式的步骤:2)安装ZooKeeper -> (4)修改配置文件
1)修改zoo.cfg文件时,在后面添加如下集群信息:
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888
2)分别在node1
、node2
、node3
三台服务器的/home/xiaobai/opt/zookeeper/tmp
目录中,创建两个文件
touch myid
touch initialize
-
myid: 分别设置
node1
、node2
、node3
三台服务器的文件myid的内容分别为1
、2
、3
,比如对服务器node1
,它对应的集群id号为1
,myid文件的内容即为1
。 -
initialize: 文件initialize留空即可
注意:
- 如果服务器之间用服务器名而不是ip时,要注意修改各自服务器的hosts文件
- 多少服务器配置时,可以先配置某一台服务器,然后用远程拷贝命令
scp
进行同步,再对各自服务器进行微调,比如修改myid文件。
三、常见异常及解决办法
1. 端口被占用
错误提示:Address already in use
解决办法:
-
一方面,可以选择停止掉现在占用端口的进程,使用命令
netstat -nltp
并结合命令grep
进行查询 -
另一方面,可以修改zoo.cfg,改变端口号
2. 磁盘空间不够
错误提示:No space left on device
解决办法:清磁盘或者磁盘
3. 无法找到myid文件
错误提示:myid file is missing
解决办法:在dataDir
对应的目录中创建myid文件,并设置正确的内容(服务器对应的id)
4. 集群中其他机器Leader选举端口未开
错误提示:Cannot open channel to 2 at election address /122.228.242.21:3888
解决办法:
-
检查各服务器防火墙是否关闭,使用命令
sudo ufw status
-
检查各服务器
/etc/hosts
中的内容是否一致,是否配置了所有节点的ip -
检查各服务器的时间是一致
-
修改各服务器的zoo.cfg,将各自服务器中对应于自己的集群信息中的host修改成
0.0.0.0
比如对示例中的服务器node1,将其zoo.cfg的集群信息修改成
server.1=0.0.0.0:2888:3888 server.2=node2:2888:3888 server.3=node3:2888:3888