4 ZooKeeper

What?

chubby的一个开源实现版
主从架构的分布式框架,对其他的分布式框架提供协调服务。

提供类似linux文件系统(有目录节点树)的简版文件系统来存储数据。
维护和监控存储数据的状态变化,通过监控到达基于数据的集群管理
主要用来解决分布式集群中应用系统的一致性问题

leader为主,follower为从
在这里插入图片描述

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的服务器:2181端口是zoo.cfg中clientPort指定的客户端与服务器通信的端口
zkCli.sh -server node01:2181,node02:2181,node03:2181
#客户端随机连接三个服务器中的一个
#客户端发出对zk集群的读写请求

基本概念和操作

分布式通信的方式
1 直接通过网络连接的方式进行通信
2 通过共享存储的方式,来进行通信或数据的传输(zk)

zk的数据结构

主要有三个部分实现

1 简版文件系统Znode:类似于文件系统的目录节点树方式的数据存储。
2 原语:可以简单理解成zk的基本命令
3 通知机制watcher:监听器

在这里插入图片描述

ZNode
四类持久节点临时节点
非有序节点createcreate -e
有序节点create -screate -s -e

持久节点

类比文件夹

# 创建节点/zk_test,并设置数据my_data
create /zk_test my_data
# 持久节点,只有显示的调用命令,才能删除永久节点
delete /zk_test

临时节点

生命周期跟客户端会话session绑定,一旦会话失效,临时节点被删除。

# client1上创建临时节点
create -e /tmp tmpdata
# client2上查看client1创建的临时节点
ls /
# client1断开连接
close
# client2上观察现象,发现临时节点被自动删除
ls /

有序节点

原因:防止多个不同的客户端在同一目录下,创建同名ZNode,由于重名,导致创建失败。
创建有序节点方法
1 命令行使用-s选项:create -s /kkb kkb
2 curator编程,可以增加一个特殊的属性:CreateMode.PERSISTENT_SEQUENTIAL
一旦被标记上这个属性,节点被创建时,zk会自动在其节点后面追加上一个整型数字。自增 唯一

会话(Session)

在这里插入图片描述
客户端要对zk集群进行读写操作,得先与某一zk服务器建立TCP长连接,此TCP长连接称为一个会话Session。每个会话有超时时间SessionTimeout。

会话特点
一个session内的任务FIFO顺序执行,会话间不能保证。
生命周期:未建立连接、正在连接、已连接、关闭连接

在这里插入图片描述

事务zxid

客户端的写请求,会对zk中的数据做出更改,如增删改的操作。
每次写请求会生成一次事务,有全局唯一的事务ID,用ZXID表示,全局自增。
ACID事务特点:

原子性 atomicity
一致性 consistency
隔离性 isolation
持久性 durability

watch监视器

客户端在znode上注册一个watcher监视器
当znode上数据出现变化,watcher检测到此变化,通知客户端。
在这里插入图片描述
好处:检测和被检测系统不需要直接关联,通过zk上某个节点进行关联,大大减少系统耦合。
三个逻辑:

注册:客户端向zk集群注册监听器
监听事件:监听器负责监听特定的事件
回调函数:当监听器听到事件的发生后,调用注册监听器时定义的回调函数。

hdfs 高可用(High Availiability,HA)解决方案

在这里插入图片描述
在这里插入图片描述

主要分为两部分:
· 1 元数据同步
· 2 主备切换

  • 元数据同步(以两个namenode为例子)

在同一个hdfs上,运行两个互为主备的namenode节点
主namenode节点(active状态)、备nn节点(standby状态)
只有active对外提供服务,standby根据active状态,进行切换。

journal node集群

1 在主备切换过程中,新的activw namenode 必须确保与原active namnode元数据同步完成,才能对外提供服务。
2 通过journalnode集群作为共享存储系统。
3 当客户端对hdfs做操作时,会在active namenode中edits.log文件中做日志记录,同时也会写入journalnode集群,负责存储hdfs新产生的元数据。
4 当有新数据写入集群后,standby namenode能监听此情况,将新数据同步过来active nn(写入)和standy nn(读取)实现元数据同步。
5 所有datanode会向两个主备namenode做block report。

  • 主备切换

ZKFC
每个nn节点上各有一个ZKFC进程
ZKFC即ZKFailoverController,作为独立进程存在,负责控制NameNode的主备切换。
ZKFC监控nn的健康情况,出现异常时,通过zk集群进行nn主备选举
ZKFC启动时,初始化HealthMonitor和ActiveStandbyElector服务
同时向这两个服务注册相应的回调方法
HealthMonitor定时调用NameNode的HAServiceProtocol RPC接口(monitorHealth和getServiceStatus),监控NameNode的健康状态,并向ZKFC反馈
ActiveStandbyElector接收ZKFC的选举请求,通过Zookeeper自动完成namenode主备选举,选举完成后回调ZKFC的主备切换方法对NameNode进行Active和Standby状态的切换

1 启动两个nn和ZKFC
2 两个ZKFC通过各自ActiveStandbyElector发起nn的主备选举,利用了Zookeeper的写一致性和临时节点机制。
3 主备选举:activestandbyElector会尝试在zk创建临时节点active standby electorlock,写的一致性保证最后只会有一个acitve standby elector创建成功。
4 active standby elector从zk获得选举结果
5 创建成功的回调zkfc的回调方法2,将对应的nn切换为active namenode状态,失败的回调方法切换成standby nn状态
6 不管成功与否,所有的active standby electorlock都会在临时节点上注册一个watcher监听器,来监听这个节点的状态变化事件。
7 如果active nn对应的healthMonitor检测到nn状态异常,通知对应ZKFC
8 ZKFC会 调用active Standby elector方法,删除zk上的lock,或者session直接断开
9 standby nn的active standby elector注册的watcher就会监听到此节点的nodeDeleted事件。
10 收到这个事件后,此active Standby Elector发起主备选举,成功创建临时节点Active Standby ElectorLock,,如果创建成功,被选举为Active nn

脑裂

分布式系统中双主现象
解决方法----隔离Fencing机制

ActiveStandbyElector成功创建ActiveElectorLock临时节点后,会创建另一个ActiveBreadCrumb持久节点
这个持久节点保存了active namenode的地址位置
当active nn在正常情况断开session时,会一并删除临时节点activeStandbyElectorLock和持久节点。
但是如果在异常情况下关闭session,持久化节点会保存下来(可能是由于通信不畅引起的,此时nn还处于active状态)
当另一个nn要由standy变为active时,会发现上一个active的nn遗留下来的activeBreadCrumb节点,然后回调ZKFailoverController的方式对旧的active nn进行fencing
首先zkfc会尝试调用旧的active nn的HAServiceProcol RPC接口的方法看看能否将其转换为standby
如果不能,执行hadoop自带的隔离措施
只有成功fencing后,选主成功的active standby elector才会回调ZKFC的becomeActie方法将对应的nn切换为active,开始对外提供服务。

zk的模式

使用了原子广播协议Zab(zk automic broadcast),保证分布式一致性。
有两种模式

1 恢复模式(选主):没有leader时,处于此模式
2 广播模式(同步):集群有了leader后,客户端向zk读写数据。
为了保证事务的顺序一致性,zk采用了递增的事务id号zxid来表识事务,所有提议proposal都有zxid,每次事务的提交必须符合quorum多数派

zookeeper集群架构图
在这里插入图片描述
主角色:leader
从角色:follower或者observer,统称为learner
对外

  • 读操作
    客户端先与某个zk服务器建立session
    然后直接从该zk服务器读取数据,并返回客户端即可
  • 写操作
    1 客户端向zk集群写入数据,如create /g;与一个 follower建立session连接
    2 follower将写请求转发给leader
    3 leader收到消息后发出proposal提案(create /g),每个follower先记录下
    4 超过半数quorum(包括leader自己)发送反馈,则leader提交commit提案,leader本地创建/kkb节点znode
    5 leader通知所有foolwer也commit提案,follower各自在本地创建/kkb
    6 follower相应client

对内

ZooKeeper服务器的四种状态
looking:服务器处于正在寻找leader的状态
leading:服务器作为群首的状态
following:服务器作为follower跟随者的状态
observising:服务器作为观察者时的状态

选举类型
全新集群leader选举
非全新集群leader选举

以3台机器组成的ZooKeeper集群为例
原则:集群中过半数(多数派quorum)Server启动后,才能选举出Leader;

- 此处quorum数是多少?3/2+1=2
- 即quorum=集群服务器数除以2,再加1
- 多数据派不需要所有的服务器都响应,proposal就能生效
-  且能提高集群的响应速度

理解leader选举前,先了解几个概念
选举过程中,每个server需发出投票;投票信息vote信息结构为(sid, zxid)全新集群,server1~3初始投票信息分别为:
​ server1 -> (1, 0)
​ ​server2 -> (2, 0)
​ server3 -> (3, 0)
- leader选举公式
​ server1 vote信息 (sid1,zxid1)
​ server2 vote信息 (sid2,zxid2)
①zxid大的server胜出;
②若zxid相等,再根据判断sid判断,sid大的胜出

  • 选举leader流程:

假设按照ZK1、ZK2、ZK3的依次启动
启动ZK1后,投票给自己,vote信息(1,0),没有过半数,选举不出leader
再启动ZK2;ZK1和ZK2票投给自己及其他服务器;ZK1的投票为(1, 0),ZK2的投票为(2, 0)
处理投票。每个server将收到的多个投票做处理
如ZK1上:ZK1投给自己的票(1,0)与ZK2传过来的票(2,0)比较;
利用leader选举公式,因为zxid都为0,相等;所以判断sid最大值;2>1;(2,0)胜出;ZK1更新自己的投票为(2, 0)
ZK2也是如此逻辑,ZK2更新自己的投票为(2,0)

再次发起投票
ZK1、ZK2上的投票都是(2,0)
发起投票后,ZK1上有一个自己的票(2,0)和一票来自ZK2的票(2,0),这两票都选ZK2为leader
ZK2上有一个自己的票(2,0)和一票来自ZK1的票(2,0),这两票都选ZK2为leader
统计投票。server统计投票信息,是否有半数server投同一个服务器为leader;
ZK2当选2票;多数
改变服务器状态。确定Leader后,各服务器更新自己的状态
更改ZK2状态从looking到leading,为Leader
更改ZK1状态从looking到following,为Follower
当K3启动时,发现已有Leader,不再选举,直接从LOOKING改为FOLLOWING

ZAB算法

raft算法动图地址
PAXOS算法 -> RAFT算法 -> ZAB算法

工作流程
  1. 在Client向Follwer发出一个写的请求
  2. Follwer把请求发送给Leader
  3. Leader接收到以后开始发起投票并通知Follwer进行投票
  4. Follwer把投票结果发送给Leader
  5. Leader将结果汇总,如果多数同意,则开始写入同时把写入操作通知给Follwer,然后commit
  6. Follwer把请求结果返回给Client
使用范围

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值