zookeeper 学习总结
一 、什么是zookeeper
Zookeeper 是一个分布式协调服务的开源框架。主要用来解决分布式集群中应用系统的一致性问题,例如怎样避免同时操作同一数据造成脏读的问题。
ZooKeeper 本质上是一个分布式的小文件存储系统。提供基于类似于文件系统的目录树方式的数据存储,并且可以对树中的节点进行有效管理。从而用来维护和监控你存储的数据的状态变化。通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。诸如:统一命名服务、分布式配置管理、分布式消息队列、分布式锁、分布式协调等功能。
zookeeper应用场景:
- 统一命名服务
- 统一配置管理
- 统一集群管理
- 服务器动态上下线
- 软负载均衡
二、ZooKeeper 特性
-
全局数据一致:集群中每个服务器保存一份相同的数据副本,client 无 论连接到哪个服务器,展示的数据都是一致的,这是最重要的特征;
-
可靠性:如果消息被其中一台服务器接受,那么将被所有的服务器接受。
-
顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息 a 在消息 b 前发布,则在所有Server 上消息 a 都将在消息 b 前被发布;偏序是指如果一个消息 b 在消息 a 后被同一个发送者发布,a 必
将排在 b 前面。
-
数据更新原子性:一次数据更新要么成功(半数以上节点成功),要么失败,不存在中间状态;
-
实时性:Zookeeper 保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。
注:最重要的性质是全局一致性,并且zookeeper中的一致性不是强一致性而是最终一致性。
三 、zookeeper架构
Leader:
Zookeeper 集群工作的核心
事务请求(写操作)的唯一调度和处理者,保证集群事务处理的顺序性; 集群内部各个服务器的调度者。对于 create,setData,delete 等有写操作的请求,则需要统一转发给 leader 处理,leader 需要决定编号、执行操作,这个过程称为一个事务。
Follower:
处理客户端非事务(读操作)请求,转发事务请求给 Leader参与集群 Leader 选举投票。此外,针对访问量比较大的 zookeeper 集群,还可新增观察者角色。
Observer:
观察者角色,观察 Zookeeper 集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给 Leader服务器进行处理。不会参与任何形式的投票只提供非事务服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力。
四、ZooKeeper 集群搭建
Zookeeper 集群搭建指的是 ZooKeeper 分布式模式安装。通常由 2n+1台 servers 组成。这是因为为了保证 Leader 选举(基于 Paxos 算法的实现)能过得到多数的支持,所以 ZooKeeper 集群的数量一般为奇数。Zookeeper 运行需要 java 环境,所以需要提前安装 jdk。对于安装leader+follower 模式的集群,大致过程如下:
- 配置主机名称到 IP 地址映射配置
- 修改 ZooKeeper 配置文件
- 远程复制分发安装文件
- 设置 myid
- 启动 ZooKeeper 集群
五、ZooKeeper 数据模型
ZooKeeper 的数据模型,在结构上和标准文件系统的非常相似,拥有一个层次的命名空间,都是采用树形层次结构,ZooKeeper 树中的每个节点被称为—Znode。和文件系统的目录树一样,ZooKeeper 树中的每个节点可以拥有子节点。但也有不同之处:
-
Znode 兼具文件和目录两种特点。既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分,并可以具有子 Znode。用户对 Znode 具有增、删、改、查等操作(权限允许的情况下)。
-
Znode 具有原子性操作,读操作将获取与节点相关的所有数据,写操作也将替换掉节点的所有数据。另外,每一个节点都拥有自己的 ACL(访问控制列表),这个列表规定了用户的权限,即限定了特定用户对目标节点可以执行的操作。
-
Znode 存储数据大小有限制。ZooKeeper 虽然可以关联一些数据,但并没有被设计为常规的数据库或者大数据存储,相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以 KB 为大小单位。ZooKeeper 的服务器和客户端都被设计为严格检查并限制每个 Znode 的数据大小至多 1M,当时常规使用中应该远小于此值。
-
Znode 通过路径引用,如同 Unix 中的文件路径。路径必须是绝对的,因此他 们必须由斜杠字符来开头。除此以外,他们必须是唯一的,也就是说每一个路径只有一个表示,因此这些路径不能改变。在 ZooKeeper 中,路径由Unicode 字符串组成,并且有一些限制。字符串"/zookeeper"用以保存管理信息,比如关键配额信息。
数据结构图
图中的每个节点称为一个 Znode。 每个 Znode 由 3 部分组成:
① stat:此为状态信息, 描述该 Znode 的版本, 权限等信息
② data:与该 Znode 关联的数据
③ children:该 Znode 下的子节点
六、Zookeeper 内部原理
节点类型
Znode 有两种,分别为临时节点和永久节点。
节点的类型在创建时即被确定,并且不能改变。
临时节点:客户端和服务器端断开连接后,创建的节点自己删除
永久节点:客户端和服务器端断开连接后,创建的节点不删除
监听器原理(重点)
选举机制
1)半数机制:集群中半数以上机器存活,集群可用。所以 Zookeeper 适合安装奇数台
服务器。
2)Zookeeper 虽然在配置文件中并没有指定 Master 和 Slave。但是,Zookeeper 工作时,
是有一个节点为 Leader,其他则为 Follower,Leader 是通过内部的选举机制临时产生的。
3)以一个简单的例子来说明整个选举的过程。
假设有五台服务器组成的 Zookeeper 集群,它们的 id 从 1-5,同时它们都是最新启动的,
也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来
看看会发生什么:
(1)服务器 1 启动,发起一次选举。服务器 1 投自己一票。此时服务器 1 票数一票,不够半数以上(3 票),选举无法完成,服务器 1 状态保持为 LOOKING;
(2)服务器 2 启动,再发起一次选举。服务器 1 和 2 分别投自己一票并交换选票信息: 此时服务器 1 发现服务器 2 的 ID 比自己目前投票推举的(服务器 1)大,更改选票为推举 服务器 2。此时服务器 1 票数 0 票,服务器 2 票数 2 票,没有半数以上结果,选举无法完成,服务器 1,2 状态保持 LOOKING
(3)服务器 3 启动,发起一次选举。此时服务器 1 和 2 都会更改选票为服务器 3。此次投票结果:服务器 1 为 0 票,服务器 2 为 0 票,服务器 3 为 3 票。此时服务器 3 的票数已经超过半数,服务器 3 当选 Leader。服务器 1,2 更改状态为 FOLLOWING,服务器 3 更改状态为 LEADING;
(4)服务器 4 启动,发起一次选举。此时服务器 1,2,3 已经不是 LOOKING 状态,不会更改选票信息。交换选票信息结果:服务器 3 为 3 票,服务器 4 为 1 票。此时服务器 4服从多数,更改选票信息为服务器 3,并更改状态为 FOLLOWING;
(5)服务器 5 启动,同 4 一样当小弟。
一些基本概念的说明:
服务器 ID:
比如有三台服务器,编号分别是 1,2,3。
编号越大在选择算法中的权重越大。
选举状态:
LOOKING,竞选状态。
FOLLOWING,随从状态,同步 leader 状态,参与投票。
OBSERVING,观察状态,同步 leader 状态,不参与投票。
LEADING,领导者状态。
数据 ID:
服务器中存放的最新数据 version。
值越大说明数据越新,在选举算法中数据越新权重越大。
逻辑时钟:
也叫投票的次数,同一轮投票过程中的逻辑时钟值是相同的。每投完一次票
这个数据就会增加,然后与接收到的其它服务器返回的投票信息中的数值相比,
根据不同的值做出不同的判断。
写数据流程
七、Zookeeper 实战
分布式安装部署
1 . 集群规划
在 三个节点上部署 Zookeeper。
2.解压安装
(1)解压 Zookeeper 安装包到/opt/module/目录下
[atguigu@hadoop102 software]$ tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
3.配置服务器编号
(1)在/opt/module/zookeeper-3.4.10/这个目录下创建 zkData
[atguigu@hadoop102 zookeeper-3.4.10]$ mkdir -p zkData
(2)在/opt/module/zookeeper-3.4.10/zkData 目录下创建一个 myid 的文件
[atguigu@hadoop102 zkData]$ touch myid
添加 myid 文件,注意一定要在 linux 里面创建,在 notepad++里面很可能乱码
(3)编辑 myid 文件
[atguigu@hadoop102 zkData]$ vi myid
在文件中添加与 server 对应的编号: 2
(4)拷贝配置好的 zookeeper 到其他机器上
[atguigu@hadoop102 zkData]$ xsync myid
并分别在 hadoop103、hadoop104 上修改 myid 文件中内容为 3、4
4.配置 zoo.cfg 文件
(1)重命名/opt/module/zookeeper-3.4.10/conf 这个目录下的 zoo_sample.cfg 为 zoo.cfg
[atguigu@hadoop102 conf]$ mv zoo_sample.cfg zoo.cfg
(2)打开 zoo.cfg 文件
[atguigu@hadoop102 conf]$ vim zoo.cfg
修改数据存储路径配置
dataDir=/opt/module/zookeeper-3.4.10/zkData
增加如下配置 :
#######################cluster##########################
server.2=192.168.43.110:2888:3888
server.3=192.168.43.222:2888:3888
server.4=192.168.43.228:2888:3888
(3)配置参数解读
server.A=B:C:D。
A 是一个数字,表示这个是第几号服务器;
集群模式下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据
就是 A 的值,Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比
较从而判断到底是哪个 server。
B 是这个服务器的地址;
C 是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口;
D 是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的
Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
5.集群操作
(1)分别启动 Zookeeper
[root@centos5 conf]# zzbin/zkServer.sh start
[root@centos6 apache-zookeeper-3.6.0-bin]# bin/zkServer.sh start
[root@localhost apache-zookeeper-3.6.0-bin]# bin/zkServer.sh start
(2)查看状态
[root@centos5 apache-zookeeper-3.6.0-bin]# bin/zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/moudle/apache-zookeeper-3.6.0-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader
[root@centos6 apache-zookeeper-3.6.0-bin]# bin/zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/moudle/apache-zookeeper-3.6.0-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
[root@localhost apache-zookeeper-3.6.0-bin]# bin/zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/moudle/apache-zookeeper-3.6.0-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower