zookeeper - yaokun123/php-wiki GitHub Wiki
ZooKeeper
一、概述
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。Zookeeper是一个分布式协调服务;就是为用户的分布式应用程序提供协调服务
1、为别的分布式程序服务的
2、本身就是一个分布式程序
3、主从协调 服务器节点动态上下线 统一配置管理 分布式共享锁 统一名称服务
4、管理(存储,读取)用户程序提交的数据 并为用户程序提供数据节点监听服务
二、Zookeeper的集群机制
Zookeeper是为其他分布式程序提供服务的,所以本身自己不能随便就挂了,所以zookeeper自身的集群机制就很重要。zookeeper的集群机制采用的是半数存活机制,也就是整个集群节点中有半数以上的节点存活,那么整个集群环境可用。这也就是说们的集群节点最好是奇数个节点。
Zookeeper集群节点的角色
2.1、Leader Leader服务器是Zookeeper集群工作的核心,其主要工作如下
1、事务请求的唯一调度和处理者,保证集群事务处理的顺序性。
2、集群内部各服务器的调度者
2.2、Follower Follower是Zookeeper集群的跟随者,其主要工作如下
1、处理客户端非事务性请求(读取数据),转发事务请求给Leader服务器。
2、参与事务请求Proposal的投票
3、参与Leader选举投票。
2.3、Observer
Observer充当观察者角色,观察Zookeeper集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给Leader服务器进行处理。Observer不会参与任何形式的投票,包括事务请求Proposal的投票和Leader选举投票
三、集群环境准备
通过上面的介绍我们了解到zookeeper的集群环境应该配置奇数个节点,所以我们在本文中搭建的zookeeper环境准备在3个节点上搭建。接下来我们介绍下需要准备的环境。
3.1、准备3个节点
准备3个centos7.0的虚拟机节点,并且安装配置好JDK版本最好是8
ip | 主机名 |
---|---|
172.16.164.137 | mynode3 |
172.16.164.139 | mynode4 |
172.16.164.140 | mynode5 |
3.2、节点的映射关系
每个节点设置相应的ip和主机名的映射关系,方便集群环境的部署。修改hosts配置文件中的信息
172.16.164.137 mynode3
172.16.164.139 mynode4
172.16.164.140 mynode5
3.3、配置免密登录
生成公钥和私钥:ssh-keygen 输入命令后根据提示,四次回车即可
发送公钥给需要免密登录的节点:
ssh-copy-id mynode3
ssh-copy-id mynode4
ssh-copy-id mynode5
四、Zookeeper集群环境搭建
4.1、获取安装文件
下载地址:https://mirrors.bfsu.edu.cn/apache/zookeeper/
通过wget命令将安装文件下载到/software/目录下
注意:apache-zookeeper-3.5.9-bin.tar.gz和apache-zookeeper-3.5.9.tar.gz的区别 -bin是编译后的文件 我们用这个
解压缩文件
进入Zookeeper目录
4.2、修改配置
修改zoo.cfg文件,系统默认的名称是 zoo_smple.cfg我们需要重命名为zoo.cfg
修改cfg的内容
#ZooKeeper保存数据的目录
dataDir=/opt/data/zookeeper
#日志目录
dataLogDir=/var/msbjy/zookeeper/datalog
# 集群节点配置,2881是心跳检测使用,3881是数据端口使用
server.1=mynode3:2881:3881
server.2=mynode4:2881:3881
server.3=mynode5:2881:3881
配置myid文件
我们需要在Zookeeper的数据存储的目录中创建一个myid文件,文件中的内容只有一行信息,
即表示我们集群几点的标识,范围是1-255,每个节点的myid的数字和我们在zoo.cfg中配置的server.数字是对应的
4.3、分发文件
当我们配置好了一个Zookeeper节点后,我们就可以将Zookeeper文件夹分发给其他几个节点了
scp -r zookeeper mynode4:`pwd`
scp -r zookeeper mynode5:`pwd`
分发成功后我们需要修改各个节点中的myid的信息为配置文件中对应的数字
4.4、启动测试
启动命令
./bin/zkServer.sh start
当我们仅仅启动一个节点的时候,因为半数存活机制,3个节点只启动一个节点是没有效果的,当我们启动第二个节点后发现集群环境可以使用了,然后第一个节点的状态也改变了,然后再把第三个节点也启动起来。
五、Zookeeper的选举机制
为什么要进行Leader选举? Leader 主要作用是保证分布式数据一致性,即每个节点的存储的数据同步。遇到以下两种情况需要进行Leader选举
-
服务器初始化启动
-
服务器运行期间无法和Leader保持连接,Leader节点崩溃,逻辑时钟崩溃。
5.1 服务器初始化时Leader选举
Zookeeper由于其自身的性质,一般建议选取奇数个节点进行搭建分布式服务器集群。
以3个节点组成的服务器集群为例,说明服务器初始化时的选举过程。
启动第一台安装Zookeeper的节点时,无法单独进行选举,启动第二台时,两节点之间进行通信,开始选举Leader。
1、每个Server投出一票。他们两都选自己为Leader,投票的内容为(SID,ZXID)。
SID即Server的id,安装zookeeper时配置文件中所配置的myid;ZXID,事务id, 为节点的更新程度,ZXID越大,代表Server对Znode的操作越新。
由于服务器初始化, 每个Sever上的Znode为0,所以Server1投的票为(1,0),Server2为(2,0)。 两Server将各自投票发给集群中其他机器。
2、每个Server接收来自其他Server的投票。集群中的每个Server先判断投票有效性, 如检查是不是本轮的投票,是不是来Looking状态的服务器投的票。
3、对投票结果进行处理。先了解下处理规则
- 首先对比ZXID。ZXID大的服务器优先作为Leader
- 若ZXID相同,比如初始化的时候,每个Server的ZXID都为0,就会比较myid,myid大的选出来做Leader。
对于Server1而言,他接受到的投票为(2,0),因为自身的票为(1,0),所以此时它会选举Server2为Leader, 将自己的更新为(2,0)。
而Server2收到的投票为Server1的(1,0)由于比他自己小, Server2的投票不变。Server1和Server2再次将票投出,投出的票都为(2,0)。
- 统计投票。每次投票之后,服务器都会统计投票信息,如果判定某个Server有过半的票数投它, 那么该Server将会作为Leader。
对于Server1和Server2而言,统计出已经有两台机器接收了(2,0)的投票信息, 此时认为选出了Leader。
- 改变服务器状态。当确定了Leader之后,每个Server更新自己的状态, Leader将状态更新为Leading,Follower将状态更新为Following。
5.2、服务器运行期间的Leader选举
Zookeeper运行期间,如果有新的Server加入,或者非Leader的Server宕机,那么Leader将会同步数据到新Server或者寻找其他备用Server替代宕机的Server。若Leader宕机,此时集群暂停对外服务,开始在内部选举新的Leader。假设当前集群中有Server1、Server2、Server3三台服务器,Server2为当前集群的Leader,由于意外情况,Server2宕机了,便开始进入选举状态。过程如下
1、变更状态。其他的非Observer服务器将自己的状态改变为Looking,开始进入Leader选举。
2、每个Server发出一个投票(myid,ZXID),由于此集群已经运行过,所以每个Server上的ZXID可能不同。
假设Server1的ZXID为145,Server3的为122,第一轮投票中,Server1和Server3都投自己, 票分别为(1,145)、(3,122),将自己的票发送给集群中所有机器。
3、每个Server接收接收来自其他Server的投票,接下来的步骤与初始化时相同。
六、Zookeeper客户端使用
6.1、 配置Zookeeper的环境变量
为了简化我们每次操作Zookeeper而不用进入到Zookeeper的安装目录,我们可以将Zookeeper的安装信息配置到系统的环境变量中
vim /etc/profile 添加内容
export ZOOKEEPER_HOME=/software/apache-zookeeper-3.6.4-bin
export PATH=$PATH:$ZOOKEEPER_HOME/bin
// 执行source命令
source /etc/profile
// 我们就可以在节点的任意位置操作Zookeeper了。通过scp命令将profile文件发送到其他几个节点上
6.2、客户端连接
通过bin目录下的zkCli.sh 命令连接即可
zkCli.sh
// zkCli.sh默认连接的是当前节点的Zookeeper节点,如果我们要连接其他节点执行如下命令即可
zkCli.sh -timeout 5000 -server bobo02:2181
6.3、数据操作
Zookeeper的数据结构
1、层次化的目录结构,命名符合常规文件系统规范
2、每个节点在Zookeeper中叫做znode,并且有一个唯一的路径标识
3、节点znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)
4、客户端应用可以在节点上设置监听器
节点类型
znode有两种类型:
短暂性(ephemeral)(断开连接自己删除) 持久性(persistent)(断开连接不删除)
znode有四种形式的目录节点(默认是persistent)如下
序号 | 节点类型 | 描述 |
---|---|---|
1 | PERSISTENT | 持久节点 |
2 | PERSISTENT_SEQUENTIAL | 持久有序节点 |
3 | EPHEMERAL | 短暂节点 |
4 | EPHEMERAL_SEQUENTIAL | 短暂有序节点 |
创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,有父节点维护 在分布式系统中, 顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序
常用命令
命令 | 描述 | 示例 |
---|---|---|
ls | ls用来查看某个节点下的子节点信息 | ls / |
ls2/ls -s | 增强的命令,查看节点下的子节点及当前节点的属性信息 | ls -s / |
create | 创建节点信息 | |
get | get命令用来查看节点的数据 | 如果要查看节点的属性信息那么我们可以通过get -s 来实现 |
delete | delete只能删除没有子节点的节点 | 要删除非空节点可以通过 rmr 或者 deleteall 命令实现 |
set | set命令可以用来修改节点的内容 | 要删除非空节点可以通过 rmr 或者 deleteall 命令实现 |
6.4、事件监听
数据改变的监听
监听某个节点的数据内容变化,通过get命令 带 -w 参数即可,在3.4版本的Zookeeper中是通过get path watch 来说实现监控的
get -w /app1
然后我们在其他节点上修改app1节点的数据,会触监听事件
set /app1 aaaaaa
注意监听一次节点只会触发一次,如果要实现多次监听,那么可以在触发事件的处理函数中再次追加对节点的监听操作
子节点的改变
监听节点下面的子节点的改变。
ls -w /app1
触发
create /app1/a1 aaaa