ZooKeeper分布式协调框架
ZooKeeper分布式协调框架1. 为什么要用ZooKeeperZooKeeper简单易用,能够很好的解决分布式框架在运行中,出现的各种协调问题。比如集群master主备切换、节点的上下线感知等等2. 什么是ZooKeeper?ZooKeeper是一个分布式的,开放源码的,用于分布式应用程序的协调服务(service);是Google的Chubby的一个开源实现版3. ZooKeeper应用概览
ZooKeeper分布式协调框架
1. 为什么要用ZooKeeper
ZooKeeper简单易用,能够很好的解决分布式框架在运行中,出现的各种协调问题。比如集群master主备切换、节点的上下线感知等等
2. 什么是ZooKeeper?
ZooKeeper是一个分布式的,开放源码的,用于分布式应用程序的协调服务(service);是Google的Chubby的一个开源实现版
3. ZooKeeper应用概览
service
攘其外,安其内
简单:原语
paxos -> raft -> zab
-
回顾:HDFS HA方案
ZooKeeper中三个重要的逻辑:注册、监听事件、回调函数
- 举例类比:旅客住店流程
- NameNode + ZooKeeper
关键逻辑:注册、监听事件、回调函数
3.1 ZooKeeper之攘其外
ZooKeeper服务端有两种不同的运行模式。单机的称为"独立模式"(standalone mode);集群的称为“仲裁模式(quorum mode)”
-
主从架构:Master + Slave
-
客户端读
-
客户端写:类比存钱
-
leader在通知follower执行某条命令时,如何保障每个follower都收到,并执行呢?
队列结构
CAP:Consistency一致性;Availability可用性;Partition Tolerance分区容错;三选二
3.2 ZooKeeper之安其内
- 思考一下这个架构有什么问题?
- leader很重要?如果挂了怎么办?开始选举新的leader
- ZooKeeper服务器四种状态:
-
looking:服务器处于寻找Leader群首的状态
-
leading:服务器作为群首时的状态
-
following:服务器作为follower跟随者时的状态
-
observing:服务器作为观察者时的状态
leader选举分两种情况
集群初始启动时
集群运行中leader挂了时
- 集群启动时的Leader选举
-
以3台机器组成的ZooKeeper集群为例
-
原则:集群中过半数Server启动后,才能选举出Leader;
-
此处quorum数是多少?
-
每个server投票信息vote信息结构为(sid, zxid);
server1~3初始投票信息分别为:
server1 -> (1, 0)
server2 -> (2, 0)
server3 -> (3, 0) -
leader选举公式:
server1 (zxid1, sid1)
server2 (zxid2, sid2)
zxid大的server胜出;若zxid相等,再根据判断sid判断,sid大的胜出
-
流程:
-
ZK1和ZK2票投给自己;ZK1的投票为(1, 0),ZK2的投票为(2, 0),并各自将投票信息分发给其他机器。
-
处理投票。每个server将收到的投票和自己的投票对比;ZK1更新自己的投票为(2, 0),并将投票重新发送给ZK2。
-
统计投票。server统计投票信息,是否有半数server投同一个服务器为leader;
-
改变服务器状态。确定Leader后,各服务器更新自己的状态,Follower变为FOLLOWING;Leader变为LEADING。
-
当K3启动时,发现已有Leader,不再选举,直接从LOOKING改为FOLLOWING。
-
-
集群运行时新leader选举
3.3 难点|考点
-
什么是仲裁quorum?
-
为什么要仲裁?
-
quorum数如何选择? 集群节点数 / 2 + 1
-
网络分区、脑裂
-
网络分区:网络通信故障,集群被分成了2部分
-
脑裂:原leader处于一个分区;另外一个分区选举出新的leader -> 2个leader
raft算法动图地址:http://thesecretlivesofdata.com/raft/#replication
以下以raft为例;zab与raft相似(1、zab心跳从follower到leader;2、任期叫epoch)
-
- 仲裁模式下,服务器数量最好为奇数个。why?
4. ZooKeeper使用初体验(10分钟)
4.1 zkCli命令行
- 启动集群(每个节点运行此命令)
# 启动ZooKeeper集群;在ZooKeeper集群中的每个节点执行以下命令
${ZK_HOME}/bin/zkServer.sh start
# 停止ZooKeeper集群
${ZK_HOME}/bin/zkServer.sh stop
# 查看集群状态#
${ZK_HOME}/bin/zkServer.sh status
- 客户端连接zkServer
# 使用ZooKeeper自带的脚本,连接ZooKeeper的服务器
zkCli.sh -server node-01:2181,node-02:2181,node-03:2181
- 客户端发出读写请求
ls /
create /kkb kkb
get
set
delete
4.2 java API编程
IDE可以是eclipse,或IDEA;此处以IDEA演示
5.基本概念和操作(15分钟)
分布式通信有几种方式,1、直接通过网络连接的方式进行通信;2、通过共享存储的方式,来进行通信或数据的传输。
5.1 ZooKeeper数据结构
-
ZooKeeper所提供的服务主要是通过以下三个部分来实现的
ZooKeeper=简版文件系统(Znode)+原语+通知机制(Watcher)。
5.3 数据节点ZNode
5.3.1 什么是ZNode
ZNode 分为两类:持久节点、临时节点
5.3.2 持久节点
类比,文件夹
# 创建节点/zk_test,并设置数据my_data
create /zk_test my_data
# 显示的删除永久节点
delete /zk_test
5.3.3 临时节点
临时节点的生命周期跟客户端会话session绑定,一旦会话失效,临时节点被删除。
# client1上创建临时节点
create -e /tmp tmpdata
# client2上查看client1创建的临时节点
ls /
# client1断开连接
close
# client2上观察现象,发现临时节点被自动删除
ls /
5.3.4 有序节点
ZNode也可以设置为有序节点
为什么设计临时节点?
-
创建节点时,可添加一个特殊的属性:SEQUENTIAL。
-
一旦节点被标记上这个属性,那么在这个节点被创建时,ZooKeeper 就会自动在其节点后面追加上一个整型数字
-
这个整数是一个由父节点维护的自增数字。
-
提供了创建唯一名字的ZNode的方式
# 创建持久、有序节点 create -s /test01 test01-data # Created /test010000000009
5.4 Watcher监视与通知
5.4.1 为什么要有Watcher
问:客户端如何获取ZooKeeper服务器上的最新数据?
-
方式一轮询:ZooKeeper以远程服务的方式,被客户端访问;客户端以轮询的方式获得znode数据,效率会比较低(代价比较大)
-
方式二基于通知的机制:客户端在znode上注册一个Watcher监视器,当znode上数据出现变化,watcher监测到此变化,通知客户端
-
对比,那种好?
5.4.2 什么是Watcher?
客户端在服务器端,注册的事件监听器;
watcher用于监听znode上的某些事件,比如znode数据修改、节点增删等;当监听到事件后,watcher会触发通知客户端
5.4.3 如何设置Watcher
注意:Watcher是一个单次触发的操作
- 可以设置watcher的命令如下:
5.4.4 示例1
#ls path [watch]
#node-01 上执行
ls /zk_test watch
#node-02 上执行
create /zk_test/dir01 dir01-data
#观察node-01上变化
[zk: node-01:2181,node-02:2181,node-03:2181(CONNECTED) 87]
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/zk_test
图示:
-
client1上执行步骤1
-
client2上执行步骤2;
-
client1上观察现象3
5.4.5 示例2
#监控节点数据的变化;
#node2上
get /zk_test watch
#node3上
set /zk_test "junk01"
#观察node2上cli的输出,检测到变化
- 示例3:节点上下线监控
1)原理:
- 节点1(client1)创建临时节点
- 节点2(client2)在临时节点,注册监听器watcher
- 当client1与zk集群断开连接,临时节点会被删除
- watcher发送消息,通知client2,临时节点被删除的事件
2)用到的zk特性:
- Watcher+临时节点
3)好处:
- 通过这种方式,检测和被检测系统不需要直接关联(如client1与client2),而是通过ZK上的某个节点进行关联,大大减少了系统耦合。
4)实现:
-
client1操作
# 创建临时节点 create -e /zk_tmp tmp-data
-
client2操作
# 在/zk_tmp注册监听器 ls /zk_tmp watch
-
client1操作
# 模拟节点下线 close
-
观察client2
WATCHER:: WatchedEvent state:SyncConnected type:NodeDeleted path:/zk_tmp
5)图示:
client1:
client2:
5.5 会话(Session)
5.5.1 什么是会话
客户端与某一服务器建立TCP长连接,建立一个会话Session。
SessionTimeout
5.5.2 会话的特点
-
客户端打开一个Session中的请求以FIFO(先进先出)的顺序执行;
-
若打开两个Session,无法保证Session间,请求FIFO执行
5.5.3 会话的生命周期
5.6 请求
读写请求
5.7 事务zxid
增删改的操作,会形成一次事务。
ACID:原子性atomicity | 一致性consistency | 隔离性isolation | 持久性durability
每个事务有一个全局唯一的事务ID,用 ZXID 表示;
ZXID通常是一个64位的数字。由epoch+counter组成
6. ZooKeeper工作原理(5分钟)
ZooKeeper使用原子广播协议叫做Zab(ZooKeeper Automic Broadcast)协议
Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)
为了保证事务的顺序一致性,ZooKeeper采用了递增的事务id号(zxid)来标识事务,所有提议(proposal)都有zxid
6.1写操作流程图
- 在Client向Follwer发出一个写的请求
- Follwer把请求发送给Leader
- Leader接收到以后开始发起投票并通知Follwer进行投票
- Follwer把投票结果发送给Leader
- Leader将结果汇总后如果需要写入,则开始写入同时把写入操作通知给Follwer,然后commit
- Follwer把请求结果返回给Client
6.2 ZooKeeper状态同步
完成leader选举后,zk就进入ZooKeeper之间状态同步过程
- leader等待server连接;
- Follower连接leader,将最大的zxid发送给leader;
- Leader根据follower的zxid确定同步点;
- 完成同步后通知follower 已经成为uptodate状态;
- Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。
7. ZooKeeper典型应用案例(5分钟)
-
NameNode使用ZooKeeper实现高可用.
-
Yarn ResourceManager使用ZooKeeper实现高可用.
-
利用ZooKeeper对HBase集群做高可用配置
-
kafka使用ZooKeeper
-
保存消息消费信息比如offset.
-
用于检测崩溃
-
主题topic发现
-
保持主题的生产和消费状态
-
8.编程案例
8.1 原生curd
见代码
8.2 curator编程
对ZooKeeper的api做了封装,提供简单易用的api;它的风格是curator链式编程
参考《使用curator做zk编程》
拓展点
-
ZooKeeper常见应用场景
-
分布式锁
-
访问控制ACL
参考《访问控制ACL》
六、总结(10分钟)
更多推荐
所有评论(0)