zookeeper原理与使用

一. Zookeeper
第一章:Zookeeper入门
1.1 概述
zookeeper是一个开源的分布式的,为分布式应用提供协调的Apache项目

1.2 工作机制
Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它是负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化 ,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。

1.3 特点


1)Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群

 

2)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务

3)全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的

4)更新请求顺序进行,来自同一个Client的更新请求按其发送顺序依次执行

5)数据更新原子性,一次数据更新要么成功,要么失败

6)实时性,在一定时间范围内,Client能读到最新数据

1.4 数据结构
ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一 

个ZNode。每一个ZNode默认能够存储1M B的数据,每个ZNode都可以通过其路径唯一标识。

 

1.5 应用场景
提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等

安装包下载地址:​ ​http://archive.apache.org/dist/zookeeper/​​

第二章:Zookeeper安装
2.1 本地模式安装
1.安装前准备

(1)安装 Jdk

(2)拷贝 Zookeeper 安装包到 Linux 系统下

(3)解压到指定目录

[root@zookeeper software]# tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
2.配置修改

(1)将/opt/module/zookeeper-3.4.10/conf 这个路径下的 zoo_sample.cfg 修改为 zoo.cfg

[root@zookeeper conf]# mv zoo_sample.cfg zoo.cfg

(2)打开 zoo.cfg 文件,修改 dataDir 路径

[root@zookeeper zookeeper-3.4.10]# vim zoo.cfg

修改如下内容:

dataDir=/opt/module/zookeeper-3.4.10/zkData

(3)在/opt/module/zookeeper-3.4.10/这个目录上创建 zkData 文件夹

[root@zookeeper zookeeper-3.4.10]# mkdir zkData

3.操作 Zookeeper

(1)启动 Zookeeper

[root@zookeeper zookeeper-3.4.10]# bin/zkServer.sh start

(2)查看进程是否启动

[root@zookeeper zookeeper-3.4.10]# jps

4020 Jps

4001 QuorumPeerMain

(3)查看状态:

[root@zookeeper zookeeper-3.4.10]# bin/zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /opt/module/zookeeper-

3.4.10/bin/../conf/zoo.cfg

Mode: standalone

(4)启动客户端:

[root@zookeeper zookeeper-3.4.10]# bin/zkCli.sh

(5)退出客户端:

[zk: localhost:2181(CONNECTED) 0] quit

(6)停止 Zookeeper

[root@zookeeper zookeeper-3.4.10]# bin/zkServer.sh stop

2.2 配置参数解读
Zookeeper中的配置文件zoo.cfg中参数含义解读如下:

(1)tickTime =2000:通信心跳数,Zookeeper 服务器与客户端心跳时间,单位毫秒

Zookeeper使用的基本时间,服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个tickTime时间就会发送一个心跳,时间单位为毫秒。它用于心跳机制,并且设置最小的session超时时间为两倍心跳时间(session最小超时时间是2*tickTime)

(2)initLimit =10:LF 初始通信时限

集群中的Follower跟随者服务器与Leader领导者服务器之间初始连接时能容忍的最多心跳数(tickTime的量),用它来限定集群中的Zookeeper服务器连接到Leader的时限。

(3)syncLimit =5:LF 同步通信时限

集群中Leader与Follower之间的最大响应时间单位,假如响应超过syncLimit * tickTime,Leader认为Follwer死掉,从服务器列表中删除Follwer。

(4)dataDir:数据文件目录+数据持久化路径

主要用于保存 Zookeeper 中的数据

(5)clientPort =2181:客户端连接端口

监听客户端连接的端口

2.3 分布式模式安装
1.集群规划

主机

服务

端口

192.158.21.146

zookeeper_1

2181,2888,3888,

192.158.21.147

zookeeper_2

2181,2888,3888,

192.158.21.148

zookeeper_3

2181,2888,3888,

2.解压安装

(1)解压 Zookeeper 安装包到/opt目录下

[root@zookeeper software]# tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/

[root@zookeeper software]# mv zookeeper-3.4.10.tar.gz zookeeper

(2)同步/opt/zookeeper目录内容到 zookeeper_2、zookeeper_3

scp -rp  /opt/zookeeper root@192.158.21.147:/opt/zookeeper

scp -rp  /opt/zookeeper root@192.158.21.148:/opt/zookeeper

3.配置服务器编号

(1)在/data这个目录下创建 zkData

[root@zookeeper zookeeper]# mkdir -p /data/zookeeper

(2)在/data/zookeeper 目录下创建一个 myid 的文件

[root@zookeeper zookeeper]# touch myid

(3)编辑 myid 文件

[root@zookeeper zookeeper]# echo "1" > myid

(4)拷贝配置好的 zookeeper 到其他机器上

scp -rp  /data/zookeeper root@192.158.21.147:/data/zookeeper

scp -rp  /data/zookeeper root@192.158.21.148:/data/zookeeper

并分别在 zookeeper_2、zookeeper_3上修改 myid 文件中内容为 3、4

4.配置 zoo.cfg 文件

(1)重命名/opt/zookeeper/conf 这个目录下的 zoo_sample.cfg 为 zoo.cfg

[root@zookeeper zookeeper]# mv zoo_sample.cfg zoo.cfg

(2)编辑 zoo.cfg 文件

[root@zookeeper zookeeper]# vim zoo.cfg

#根据情况来设置这个

/dataDir=/data/zookeeper

#在文件末尾添加集群配置:

server.1=192.158.21.146:2888:3888

server.2=192.158.21.147:2888:3888

server.3=192.158.21.148:2888:3888

配置参数解读:

server.A=B:C:D

A 是一个数字,表示这个是第几号服务器;

集群模式下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据

就是 A 的值,Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比

较从而判断到底是哪个 server。

B 是这个服务器的地址;

C 是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口;

D 是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的

Leader,而这个端口就是用来执行选举时服务器相互通信的端口

(3)同步 zoo.cfg 配置文件

scp -rp  /opt/zookeeper/conf/zoo.cfg root@192.158.21.147:/opt/zookeeper/conf

scp -rp  /opt/zookeeper/conf/zoo.cfg root@192.158.21.148:/opt/zookeeper/conf

4.集群操作

(1)分别启动 Zookeeper

[root@zookeeper_1 zookeeper]# bin/zkServer.sh start

[root@zookeeper_2 zookeeper]# bin/zkServer.sh start

[root@zookeeper_3 zookeeper]# bin/zkServer.sh start

(2)查看集群状态

[root@zookeeper_1 ~/zookeeper/bin]# ./zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /root/zookeeper/bin/../conf/zoo.cfg

Mode: leader

[root@zookeeper_2 ~/zookeeper/bin]# ./zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /root/zookeeper/bin/../conf/zoo.cfg

Mode: follower

[root@zookeeper_3 ~/zookeeper/bin]# ./zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /root/zookeeper/bin/../conf/zoo.cfg

Mode: follower

第三章:Zookeeper客户端操作
3.1 启动客户端
[root@zookeeper zookeeper]# ./zkCli.sh
1.
3.2 显示所有操作命令
[zk: localhost:2181(CONNECTED) 1] help
1.
3.3 查看当前 znode 中所包含的内容
[zk: localhost:2181(CONNECTED) 0] ls /
1.
[zookeeper]
1.
3.4 查看当前节点详细数据
[zk: localhost:2181(CONNECTED) 2] ls2 /
1.
[zookeeper]
1.
cZxid = 0x0
1.
ctime = Thu Jan 01 08:00:00 CST 1970
1.
mZxid = 0x0
1.
mtime = Thu Jan 01 08:00:00 CST 1970
1.
pZxid = 0x0
1.
cversion = -1
1.
dataVersion = 0
1.
aclVersion = 0
1.
ephemeralOwner = 0x0
1.
dataLength = 0
1.
numChildren = 1
1.
###
1.
cZxid :创建节点的id
1.
ctime : 节点的创建时间
1.
mZxid :修改节点的id
1.
mtime :修改节点的时间
1.
pZxid :子节点的id
1.
cversion : 子节点的版本
1.
dataVersion : 当前节点数据的版本
1.
aclVersion :权限的版本
1.
ephemeralOwner :判断是否是临时节点

dataLength : 数据的长度
1.
numChildren :子节点的数量

3.5 分别创建 2 个普通节点
[zk: localhost:2181(CONNECTED) 8] create /service "fuwu"

Created /service

[zk: localhost:2181(CONNECTED) 12] create /conf "peizhi"

Created /conf

3.6 获得节点的值
[zk: localhost:2181(CONNECTED) 14] get /service

fuwu

cZxid = 0x300000002

ctime = Fri Jul 02 00:04:59 CST 2021

mZxid = 0x300000002

mtime = Fri Jul 02 00:04:59 CST 2021

pZxid = 0x300000002

cversion = 0

dataVersion = 0

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 4

numChildren = 0

[zk: localhost:2181(CONNECTED) 15] get /conf

peizhi

cZxid = 0x300000003

ctime = Fri Jul 02 00:06:14 CST 2021

mZxid = 0x300000003

mtime = Fri Jul 02 00:06:14 CST 2021

pZxid = 0x300000003

cversion = 0

dataVersion = 0

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 6

numChildren = 0

3.7 创建短暂节点
[zk: localhost:2181(CONNECTED) 16] create -e /yuming "www.baidu.com"

Created /yuming

(1)在当前客户端是能查看到的

[zk: localhost:2181(CONNECTED) 18] ls /

[conf, zookeeper, service, yuming]

(2)退出当前客户端然后再重启客户端

[zk: localhost:2181(CONNECTED) 19] quit

(3)再次查看根目录下短暂节点已经删除

[zk: localhost:2181(CONNECTED) 0] ls /

[conf, zookeeper, service]

3.8 创建带序号的节点
(1)先创建一个普通的根节点/haojing/keji

[zk: localhost:2181(CONNECTED) 1] create /haojing "niubi"

Created /haojing

(2)创建带序号的节点

[zk: localhost:2181(CONNECTED) 4] create -s /haojing/keji "niubi"

Created /haojing/keji0000000000

[zk: localhost:2181(CONNECTED) 5] create -s /haojing/zhineng "niubi"

Created /haojing/zhineng0000000001

(3)查看带序号的节点

[zk: localhost:2181(CONNECTED) 6] ls /haojing

[keji0000000000, zhineng0000000001]

如果原来没有序号节点,序号从 0 开始依次递增。如果原节点下已有 2 个节点,则再排序时从 2 开始,以此类推

3.9 修改节点数据值
[zk: localhost:2181(CONNECTED) 10] set /conf "nginx"

3.10 节点的值变化监听
(1)在 zookeeper_1 主机上注册监听/conf节点数据变化

[zk: localhost:2181(CONNECTED) 2] get /conf watch

(2)在 zookeeper_2主机上修改/conf 节点的数据

[zk: localhost:2181(CONNECTED) 1] set /conf "tomcat"

(3)观察zookeeper_1主机收到数据变化的监听

WatchedEvent state:SyncConnected type:NodeDataChanged path:/conf

3.11 节点的子节点变化监听(路径变化)
(1)在 zookeeper_2 主机上注册监听/haojing 节点的子节点变化

[zk: localhost:2181(CONNECTED) 2] ls /haojing watch

[keji0000000000, zhineng0000000001]

(2)在zookeeper_2 主机/haojing 节点上创建子节点

[zk: localhost:2181(CONNECTED) 4] create /haojing/xinzhineng "niubi"

Created /haojing/xinzhineng

(3)观察zookeeper_2主机收到子节点变化的监听

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/haojing

3.12 删除节点
[zk: localhost:2181(CONNECTED) 7] delete /service

3.13 递归删除节点
[zk: localhost:2181(CONNECTED) 12] rmr /conf/java

3.14 查看节点状态
[zk: localhost:2181(CONNECTED) 14] stat /conf

cZxid = 0x300000003

ctime = Fri Jul 02 00:06:14 CST 2021

mZxid = 0x300000010

mtime = Fri Jul 02 00:25:36 CST 2021

pZxid = 0x300000014

cversion = 2

dataVersion = 2

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 6

numChildren = 0

第四章:Zookeeper高级
4.1 节点类型


4.2 监听器原理


4.3 选举机制
1.选举流程概述

目前有3台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:

服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking(选举状态)。
服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是LOOKING。
服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,所以服务器3成为领导者,服务器1,2成为小弟。
2.选举机制中的概念

(1)Serverid:服务器ID

比如有三台服务器,编号分别是1,2,3,编号越大在选择算法中的权重越大

(2)Zxid:数据ID

服务器中存放的最大数据ID,值越大说明数据越新,在选举算法中数据越新权重越大

(3)Epoch:逻辑时钟

或者叫投票的次数,同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加,然后与接收到的其它服务器返回的投票信息中的数值相比,根据不同的值做出不同的判断

(4)Server状态:选举状态

LOOKING,竞选状态
FOLLOWING,随从状态,同步leader状态,参与投票
OBSERVING,观察状态,同步leader状态,不参与投票
LEADING,领导者状态
3.在投票完成后,需要将投票信息发送给集群中的所有服务器,它包含如下内容:

服务器ID
数据ID
逻辑时钟
选举状态
成为 Leader 的条件: 1)选 epoch 最大的 2)若 epoch 相等,选 zxid 最大的 3)若 epoch 和 zxid 相等,选择 server_id 最大的(zoo.cfg中的myid)
4.4 数据一致性协议(ZAB协议)
配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读和写的服务,这点和redis是相同的,即对客户端来讲每个服务器都是平等的。大数据培训

Leader集群工作机制中的核心
1.事务请求的唯一调度和处理者,保证集群事务处理的顺序性
2.集群内部各个服务器的调度者(管理Follower、数据同步)
Follower集群工作机制中的跟随者
1.处理非事务请求,转发事务请求给Leader
2.参与事务请求Proposal投票
3.参与Leader选举投票
Observer观察者,3.30以上版本提供
1.和Follower功能相同,但不参与任何形式投票
2.处理非事务请求,转发事务请求给Leader
3.提高集群非事务处理能力
1.ZAB协议介绍和特点

ZooKeeper为高可用的一致性协调框架,自然也有着一致性算法的实现,使用的是ZAB协议作为数据一致性的算法, ZAB(ZooKeeper Atomic Broadcast ) 全称为:原子消息广播协议

特点:

(1)Leader负责处理写入请求

(2)广播通知所有Fllower节点

2.消息广播

ZAB 协议的消息广播过程使用的是一个原子广播协议,类似一个二阶段提交过程

广播流程简述:

①对于客户端发送的写请求,全部由 Leader 接收,Leader 将请求封装成一个事务 Proposal,将其发送给所有 Follwer

②然后,根据所有 Follwer 的反馈,如果超过半数成功响应,则执行 commit 操作

细节:

①Leader 在收到客户端请求之后,会将这个请求封装成一个事务,并给这个事务分配一个全局递增的唯一 ID,称为事务ID(ZXID),ZAB 协议需要保证事务的顺序,因此必须将每一个事务按照 ZXID 进行先后排序然后处理。

②在 Leader 和 Follwer 之间还有一个消息队列(FIFO信道),用来解耦他们之间的耦合,解除同步阻塞。

③zookeeper集群中为保证任何所有进程能够有序的顺序执行,只能是 Leader 服务器接受写请求,即使是 Follower 服务器接受到客户端的请求,也会转发到 Leader 服务器进行处理。

3.崩溃恢复

思考:

假设1:Leader 在复制数据给所有 Follwer 之后崩溃,怎么办?

假设2:Leader 在收到 Ack 并提交了自己,同时发送了部分 commit 出去之后崩溃怎么办?

针对这些问题,ZAB 定义了 2 个原则:

1、已经被leader提交的proposal确保最终被所有的follower提交2、确保那些只在leader被提出的proposal被丢弃 针对这个要求,如果让leader选举算法能够保证新选举出来的Leader服务器拥有集群中所有机器最高的ZXID事务proposal,就可以保证这个新选举出来的Leader一定具有所有已经提交的提案,也可以省去Leader服务器检查proposal的提交与丢弃的工作

实际上,Leader 服务器处理或丢弃事务都是依赖着 ZXID 的,那么这个 ZXID 如何生成呢?

答:在 ZAB 协议的事务编号 ZXID 设计中,ZXID 是一个 64 位的数字,其中低 32 位可以看作是一个简单的递增的计数器,针对客户端的每一个事务请求,Leader 都会产生一个新的事务 Proposal 并对该计数器进行 + 1 操作。

而高 32 位则代表了 Leader 服务器上取出本地日志中最大事务 Proposal 的 ZXID,并从该 ZXID 中解析出对应的 epoch 值,然后再对这个值加一

高 32 位代表了每代 Leader 的唯一性,低 32 代表了每代 Leader 中事务的唯一性。同时,也能让 Follwer 通过高 32 位识别不同的 Leader。简化了数据恢复流程

基于这样的策略:当 Follower 链接上 Leader 之后,Leader 服务器会根据自己服务器上最后被提交的 ZXID 和 Follower 上的 ZXID 进行比对,比对结果要么回滚,要么和 Leader 同步

总结:

ZAB 让整个 Zookeeper 集群在两个模式之间转换,消息广播和崩溃恢复,消息广播可以说是一个简化版本的 2PC,通过崩溃恢复解决了 2PC 的单点问题,通过队列解决了 2PC 的同步阻塞问题。

而支持崩溃恢复后数据准确性的就是数据同步了,数据同步基于事务的 ZXID 的唯一性来保证。通过 + 1 操作可以辨别事务的先后顺序。

第五章:日志清理
对3个master节点串行重启,每个间隔3分钟,每个节点做如下操作(注意使用hadoop用户)
1. 修改 zookeeper-current/conf/zoo.cfg
autopurge.purgeInterval=1
autopurge.snapRetainCount=20
2. 重启 zk
su - hadoop
/home/hadoop/zookeeper-current/bin/zkServer.sh stop
/home/hadoop/zookeeper-current/bin/zkServer.sh start

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值