Zookeeper

一、入门

概述

Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目。

工作机制

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

特点

1)Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群。
2)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。
3)全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
4)更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行。
5)数据更新原子性,一次数据更新要么成功,要么失败。
6)实时性,在一定时间范围内,Client能读到最新数据。

数据结构


ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称作一个ZNode。
每一个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。

应用场景

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

1、统一命名服务

2、统一配置管理

3、统一集群管理

4、服务器节点动态上下线

5、软负载均衡

下载地址

https://zookeeper.apache.org/

二、Zookeeper安装

本地模式安装部署

1、安装前准备:
安装jdk;
拷贝Zookeeper安装包到Linux系统下;
解压到指定目录:tar -zxvf zookeeper-3.4 -C /opt/module/ ,可以修改目录名为zookeeper

2、配置修改:
将conf下的zoo_sample.cfg修改为zoo.cfg mv zoo_sample.cfg zoo.cfg
打开zoo.cfg,修改dataDir路径:dataDir = /opt/module/zookeeper/zkData
在/opt/module/zookeeper下创建zkData文件夹:mkdir zkData

3、启动Zookeeper:
bin/zkServer.sh start
查看进程是否启动:jps
查看状态: bin/zkServer.sh status
停止Zookeeper:bin/zkServer.sh stop

4、启动客户端:
bin/zkCli.sh 进入
进入后quit退出

配置参数解读

https://blog.csdn.net/lengzijian/article/details/9226867

三、内容原理

选举机制(面试重点)

1)半数机制(paxos协议):集群中半数以上机器存活,集群可用。所以适合安装奇数台服务器。

2)内部选举

在分布式系统中选主最直接的方法是直接选定集群的一个节点为leader,其它的节点为follower,这样引入的一个问题是如果leader节点挂掉,整个集群就挂掉了。需要有一种算法自动选主,如果leader节点挂掉,则从follower节点中选出一个主节点。

  1. 选举阶段 Leader election
    最大ZXID也就是节点本地的最新事务编号,包含epoch和计数两部分。epoch是纪元的意思,相当于Raft算法选主时候的term,标识当前leader周期,每次选举一个新的Leader服务器后,会生成一个新的epoch

所有节点处于Looking状态,各自依次发起投票,投票包含自己的服务器ID和最新事务ID(ZXID)。
如果发现别人的ZXID比自己大,也就是数据比自己新,那么就重新发起投票,投票给目前已知最大的ZXID所属节点。
每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票。如果存在这样的节点,该节点将会成为准Leader,状态变为Leading。其他节点的状态变为Following。

  1. 发现阶段 Discovery

为了防止某些意外情况,比如因网络原因在上一阶段产生多个Leader的情况。
Leader集思广益,接收所有Follower发来各自的最新epoch值。Leader从中选出最大的epoch,基于此值加1,生成新的epoch分发给各个Follower。
各个Follower收到全新的epoch后,返回ACK给Leader,带上各自最大的ZXID和历史事务日志。Leader选出最大的ZXID,并更新自身历史日志。

  1. 同步阶段 Synchronization
    Leader刚才收集得到的最新历史事务日志,同步给集群中所有的Follower。只有当半数Follower同步成功,这个准Leader才能成为正式的Leader。

节点类型

持久persistent:client 和 server 断开连接后,创建的节点不删除

短暂ephemeral:client 和 server 断开连接后,创建的节点自己删除

另外分 有序和无序。创建有序节点时,会自动将节点名增加序列号

$ create -s /test/no1 "no1"
Created /test/no10000000000

Stat结构体

data: ZNode存储的数据信息,每个节点数据最大不超过1MB

ACL(Access Control List): 记录访问权限,哪些人或哪些IP可访问本节点

child: 当前节点的子节点

stat: 各种元数据,比如事务ID、版本号、时间戳、大小等

  • czxid- 引起这个 znode 创建的 zxid,创建节点的事务的 zxid
  • ctime - znode 被创建的毫秒数
  • mzxid - znode 最后更新的 zxid
  • mtime - znode 最后修改的毫秒数
  • pZxid-znode 最后更新的子节点 zxid
  • cversion - znode 子节点变化号,znode 子节点修改次数 7)dataversion - znode 数据变化号
  • aclVersion - znode 访问控制列表的变化号
  • ephemeralOwner- 如果是临时节点,这个是znode拥有者的 session id。如果不是临时节点则是 0
  • dataLength- znode 的数据长度
  • numChildren - znode 子节点数量

监听器原理(面试重点)

1、监听原理

2、常见监听:

1)监听节点数据的变化 get path [watch]
2) 监听子节点增减的变化 ls path [watch]

写数据流程

四、Zookeeper实战

分布式安装部署

1.集群规划

比如将在hadopp102、103、104三个节点上部署Zookeeper

2.解压安装

一台上解压安装Zookeeper,然后同步目录到另外两节点:xsync zookeeper

3.配置服务器编号

zookeeper的dataDir目录下创建一个myid文件,并编辑内容为2,添加与server对应的编号。

然后拷贝myid文件到其他机器上,编辑内容分别为34

4.配置zoo.cfg文件

dataDir可以改为目录下的如/opt/module/zookeeper/zkData;
添加配置:

####cluster####
server.2=hadoop102:2888:3888
server.3=hadoop102:2888:3888
server.4=hadoop102:2888:3888

server.A=B:C:D

A: 是一个数字,表示第几号服务器,与myid里的值对应;
B:这个服务器的ip地址;
C:这个服务器与集群中的Leader服务器交换信息的端口;
D:万一集群中Leader服务器挂了,需要一个端口来重新进行选举Leader,这个端口就是用来执行选举时服务器相互通信的端口。

5.启动集群

分别启动Zookeeper $ bin/zkServer.sh start

查看状态 $ bin/zkServer.sh status 半数以上启动状态才对

客户端命令行操作

1、启动客户端 $ bin/zkCli.sh

2、显示所有操作命令 help

3、查看当前节点(znode)中包含的内容 ls /

4、查看当前节点详细数据 ls2 /

5、分别创建2个普通节点

create /knode1 "knodeData1"
create /knode1/ksubnode1 "subnodeData1"

6、获取节点的值

get /knode1
get /knode1/ksubnode1

7、创建短暂节点

create -e /knode1/ksubnode2 "subnodeData2"
ls /knodeName1
// 然后退出再启动,即客户端断开链接
$ quit;
$ bin/zkCli.sh
// 此时 ls /knode1 发现ksubnode2没有了

8、创建带序号的节点

create -s /knode1/ksubnode3 "subnodeData3"
create -s /knode1/ksubnode3 "subnodeData3"
create -s /knode1/ksubnode3 "subnodeData3"
// 效果会是knode1下增ksubnode30000000002、ksubnode30000000003、ksubnode30000000004这种带编号节点

9、修改节点数据值

set /knode1/ksubnode1 "subnodeData1111"

10、节点的值变化监听

// 比如在104上注册监听/knode1节点数据变化
get /knode1 watch

// 在103上修改/knode1节点的数据
set /knode1 "xiugai"

// 104会收到数据变化的监听,注意注册一次只监听一次

11、节点的子节点变化监听(路径变化)

// 在104上注册监听/knode1节点的子节点变化
ls /knode1 watch

// 在103上/knode1节点上创建子节点
create /knode1/ksubnode4 "data4"

// 104会收到子节点变化的监听,注意注册一次只监听一次

12、删除节点

delete /knode1/ksubnode3

13、递归删除节点

rmr /knode1

14、查看节点状态

stat /knode1

API应用

1、创建链接Zookeeper服务的客户端
2、通过客户端创建节点

3、获取子节点并监控数据的变化

4、判断节点是否存在

服务器节点动态上下线


注:图中的服务器和客户端,对Zookeeper集群来说都是客户端

1、启动Zookeeper集群

2、服务器通过API向Zookeeper集群注册节点(临时的、带序号的节点),其实就是创建节点写内容为服务地址

3、客户端注册监听



五、企业面试题

原文地址:https://www.cnblogs.com/stringarray/p/13222539.html