一 HDFS HA架构图

二 HDFS HA组件

  • Active NameNode和Standby NameNode

在NameNode的HA方案中有两个不同状态的NameNode,分别为活跃态(Active)和备用状态(Standby),其中只有Active NameNode能对外提供服务,Standby NameNode会根据Active NameNode的状态变化,在必要时可切换成Active.

  • ZKFC

ZKFC即ZKFailoverController,是基于Zookeeper的故障转移控制器,它负责控制NameNode的主备切换,ZKFC会监测NameNode的健康状态,当发现Active NameNode出现异常时会通过Zookeeper进行一次新的选举,完成Active和Standby状态的切换

  • HealthMonitor

周期性调用NameNode的HAServiceProtocol RPC接口(monitorHealth 和 getServiceStatus),监控NameNode的健康状态并向ZKFC反馈

  • ActiveStandbyElector

接收ZKFC的选举请求,通过Zookeeper自动完成主备选举,选举完成后回调ZKFC的主备切换方法对NameNode进行Active和Standby状态的切换.

  • DataNode

NameNode包含了HDFS的元数据信息和数据块信息(blockmap),其中数据块信息通过DataNode主动向Active NameNode和Standby NameNode上报

  • 共享存储系统

共享存储系统负责存储HDFS的元数据(EditsLog),Active NameNode(写入)和 Standby NameNode(读取)通过共享存储系统实现元数据同步,在主备切换过程中,新的Active NameNode必须确保元数据同步完成才能对外提供服务

三 HDFS详细切换过程

1. HealthMonitor监控namenode节点和集群状态

ZKFailoverController 在初始化的时候会创建 HealthMonitor,HealthMonitor 在内部会启动一个线程来循环调用 NameNode 的 HAServiceProtocol RPC 接口的方法来检测 NameNode 的状态,并将状态的变化通过回调的方式来通知 ZKFailoverController。
HealthMonitor 主要检测 NameNode 的两类状态,分别是 HealthMonitor.State 和 HAServiceStatus。

1) HealthMonitor.State

HealthMonitor.State 是通过 HAServiceProtocol RPC 接口的 monitorHealth 方法来获取的,反映了 NameNode 节点的健康状况,主要是磁盘存储资源是否充足。HealthMonitor.State 包括下面几种状态:

  • INITIALIZING

HealthMonitor 在初始化过程中,还没有开始进行健康状况检测;

  • SERVICE_HEALTHY

NameNode 状态正常;

  • SERVICE_NOT_RESPONDING

调用 NameNode 的 monitorHealth 方法调用无响应或响应超时;

  • SERVICE_UNHEALTHY

NameNode 还在运行,但是 monitorHealth 方法返回状态不正常,磁盘存储资源不足;

  • HEALTH_MONITOR_FAILED

HealthMonitor 自己在运行过程中发生了异常,不能继续检测 NameNode 的健康状况,会导致 ZKFailoverController 进程退出;

HealthMonitor.State 在状态检测之中起主要的作用,在 HealthMonitor.State 发生变化的时候,HealthMonitor 会回调 ZKFailoverController 的相应方法来进行处理,具体处理见后文 ZKFailoverController 部分所述。

2)HAServiceStatus

HAServiceStatus 则是通过 HAServiceProtocol RPC 接口的 getServiceStatus 方法来获取的,主要反映的是 NameNode 的 HA 状态,包括:

  • INITIALIZING

NameNode 在初始化过程中

  • ACTIVE

当前 NameNode 为主 NameNode

  • STANDBY

当前 NameNode 为备 NameNode

  • STOPPING

当前 NameNode 已停止 
HAServiceStatus 在状态检测之中只是起辅助的作用,在 HAServiceStatus 发生变化时,HealthMonitor 也会回调 ZKFailoverController 的相应方法来进行处理。

2. ActiveStandbyElector 选举与注册监听

为了便于理解,查看HDFS在zookeeper集群创建的 znode信息

[zk: sht-sgmhadoopdn-:(CONNECTED) ] ls /hadoop-ha/mycluster
[ActiveBreadCrumb, ActiveStandbyElectorLock]
zk: sht-sgmhadoopdn-:(CONNECTED) ] get /hadoop-ha/mycluster/ActiveBreadCrumb myclusternn1sht-sgmhadoopnn- �>(�>
cZxid = 0x100000011
ctime = Thu Mar :: CST
mZxid = 0x100000014
mtime = Thu Mar :: CST
pZxid = 0x100000011
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
[zk: sht-sgmhadoopdn-:(CONNECTED) ] get /hadoop-ha/mycluster/ActiveStandbyElectorLock myclusternn1sht-sgmhadoopnn- �>(�>
cZxid = 0x100000013
ctime = Thu Mar :: CST
mZxid = 0x100000013
mtime = Thu Mar :: CST
pZxid = 0x100000013
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x169bfa59c6a0002
dataLength =
numChildren =

1)ActiveStandbyElector 选举

Namenode(包括 YARN ResourceManager) 的主备选举是通过 ActiveStandbyElector 来完成的,ActiveStandbyElector 主要是利用了 Zookeeper 的写一致性和临时节点机制,具体的主备选举实现如下:创建锁节点 如果 HealthMonitor 检测到对应的 NameNode 的状态正常,那么表示这个 NameNode 有资格参加 Zookeeper 的主备选举。如果目前还没有进行过主备选举的话,那么相应的 ActiveStandbyElector 就会发起一次主备选举,尝试在 Zookeeper 上创建一个路径为/hadoop-ha//ActiveStandbyElectorLock 的临时节点 (${dfs.nameservices} 为 Hadoop 的配置参数 dfs.nameservices 的值,下同),Zookeeper 的写一致性会保证最终只会有一个节点的ActiveStandbyElector 创建成功,那么创建成功的 ActiveStandbyElector 对应的 NameNode 就会成为主 NameNode,ActiveStandbyElector 会回调ZKFailoverController 的方法进一步将对应的 NameNode 切换为 Active 状态。而创建失败的 ActiveStandbyElector 对应的 NameNode 成为备 NameNode,ActiveStandbyElector 会回调 ZKFailoverController 的方法进一步将对应的 NameNode 切换为 Standby 状态。

2)ActiveStandbyElector 注册监听

不管创建/hadoop-ha//ActiveStandbyElectorLock 节点是否成功,ActiveStandbyElector 随后都会向 Zookeeper 注册一个 Watcher 来监听这个节点的状态变化事件,ActiveStandbyElector 主要关注这个节点的 NodeDeleted 事件。

自动触发主备选举 
如果 Active NameNode 对应的 HealthMonitor 检测到 NameNode 的状态异常时, ZKFailoverController 会主动删除当前在 Zookeeper 上建立的临时节点/hadoop-ha//ActiveStandbyElectorLock,这样处于 Standby 状态的 NameNode 的 ActiveStandbyElector 注册的监听器就会收到这个节点的 NodeDeleted 事件。收到这个事件之后,会马上再次进入到创建/hadoop-ha//ActiveStandbyElectorLock 节点的流程,如果创建成功,这个本来处于 Standby 状态的 NameNode 就选举为主 NameNode 并随后开始切换为 Active 状态。

当然,如果是 Active 状态的 NameNode 所在的机器整个宕掉的话,那么根据 Zookeeper 的临时节点特性,/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 节点会自动被删除,从而也会自动进行一次主备切换。

3. HDFS防止脑裂现象

Zookeeper 在工程实践的过程中经常会发生的一个现象就是 Zookeeper 客户端“假死”,所谓的“假死”是指如果 Zookeeper 客户端机器负载过高或者正在进行 JVM Full GC,那么可能会导致 Zookeeper 客户端到 Zookeeper 服务端的心跳不能正常发出,一旦这个时间持续较长,超过了配置的 Zookeeper Session Timeout 参数的话,Zookeeper 服务端就会认为客户端的 session 已经过期从而将客户端的 Session 关闭。“假死”有可能引起分布式系统常说的双主或脑裂 (brain-split) 现象。具体到本文所述的 NameNode,假设 NameNode1 当前为 Active 状态,NameNode2 当前为 Standby 状态。如果某一时刻 NameNode1 对应的 ZKFailoverController 进程发生了“假死”现象,那么 Zookeeper 服务端会认为 NameNode1 挂掉了,根据前面的主备切换逻辑,NameNode2 会替代 NameNode1 进入 Active 状态。但是此时 NameNode1 可能仍然处于 Active 状态正常运行,即使随后 NameNode1 对应的 ZKFailoverController 因为负载下降或者 Full GC 结束而恢复了正常,感知到自己和 Zookeeper 的 Session 已经关闭,但是由于网络的延迟以及 CPU 线程调度的不确定性,仍然有可能会在接下来的一段时间窗口内 NameNode1 认为自己还是处于 Active 状态。这样 NameNode1 和 NameNode2 都处于 Active 状态,都可以对外提供服务。这种情况对于 NameNode 这类对数据一致性要求非常高的系统来说是灾难性的,数据会发生错乱且无法恢复。Zookeeper 社区对这种问题的解决方法叫做 fencing,中文翻译为隔离,也就是想办法把旧的 Active NameNode 隔离起来,使它不能正常对外提供服务。

ActiveStandbyElector 为了实现 fencing,会在成功创建 Zookeeper 节点 hadoop-ha//ActiveStandbyElectorLock 从而成为 Active NameNode 之后,创建另外一个路径为/hadoop-ha//ActiveBreadCrumb 的持久节点,这个节点里面保存了这个 Active NameNode 的地址信息。Active NameNode 的 ActiveStandbyElector 在正常的状态下关闭 Zookeeper Session 的时候 (注意由于/hadoop-ha//ActiveStandbyElectorLock 是临时节点,也会随之删除),会一起删除节点/hadoop-ha//ActiveBreadCrumb。但是如果 ActiveStandbyElector 在异常的状态下 Zookeeper Session 关闭 (比如前述的 Zookeeper 假死),那么由于/hadoop-ha//ActiveBreadCrumb 是持久节点,会一直保留下来。后面当另一个 NameNode 选主成功之后,会注意到上一个 Active NameNode 遗留下来的这个节点,从而会回调 ZKFailoverController 的方法对旧的 Active NameNode 进行 fencing。

如果 ActiveStandbyElector 选主成功之后,发现了上一个 Active NameNode 遗留下来的/hadoop-ha//ActiveBreadCrumb 节点 ,那么 ActiveStandbyElector 会首先回调 ZKFailoverController 注册的 fenceOldActive 方法,尝试对旧的 Active NameNode 进行 fencing,在进行 fencing 的时候,会执行以下的操作:

首先尝试调用这个旧 Active NameNode 的 HAServiceProtocol RPC 接口的 transitionToStandby 方法,看能不能把它转换为 Standby 状态。 
如果 transitionToStandby 方法调用失败,那么就执行 Hadoop 配置文件之中预定义的隔离措施,Hadoop 目前主要提供两种隔离措施,通常会选择 sshfence: 
sshfence:通过 SSH 登录到目标机器上,执行命令 fuser 将对应的进程杀死; 
shellfence:执行一个用户自定义的 shell 脚本来将对应的进程隔离; 
只有在成功地执行完成 fencing 之后,选主成功的 ActiveStandbyElector 才会回调 ZKFailoverController 的 becomeActive 方法将对应的 NameNode 转换为 Active 状态,开始对外提供服务。

hadoop HA学习的更多相关文章

  1. Hadoop - HA学习笔记

    Hadoop HA概述 工作要点 通过双NameNode消除单点故障 元数据管理方式需要改变:内存中各自保存一份元数据:Edits 日志只有 Active 状态的NameNode节点可以做写操作:两个 ...

  2. Hadoop技术之Hadoop HA 机制学习

    欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:温球良 导语 最近分享过一次关于Hadoop技术主题的演讲,由于接触时间不长,很多技术细节认识不够,也没讲清楚,作为一个技术人员,本 ...

  3. Hadoop HA方案调研

    原文成文于去年(2012.7.30),已然过去了一年,很多信息也许已经过时,不保证正确,与Hadoop学习笔记系列一样仅为留做提醒. ----- 针对现有的所有Hadoop HA方案进行调研,以时间为 ...

  4. 全网最详细的Hadoop HA集群启动后,两个namenode都是active的解决办法(图文详解)

    不多说,直接上干货! 这个问题,跟 全网最详细的Hadoop HA集群启动后,两个namenode都是standby的解决办法(图文详解) 是大同小异. 欢迎大家,加入我的微信公众号:大数据躺过的坑  ...

  5. 全网最详细的Hadoop HA集群启动后,两个namenode都是standby的解决办法(图文详解)

    不多说,直接上干货! 解决办法 因为,如下,我的Hadoop HA集群. 1.首先在hdfs-site.xml中添加下面的参数,该参数的值默认为false: <property> < ...

  6. Hadoop入门学习路线

    走上大数据的自学之路....,Hadoop是走上大数据开发学习之路的第一个门槛. Hadoop,是Apache的一个开源项目,开发人员可以在不了解分布式底层细节,开发分布式程序,充分利用集群进行高速运 ...

  7. Hadoop HA集群 与 开发环境部署

    每一次 Hadoop 生态的更新都是如此令人激动 像是 hadoop3x 精简了内核,spark3 在调用 R 语言的 UDF 方面,速度提升了 40 倍 所以该文章肯定得配备上最新的生态 hadoo ...

  8. Hadoop HA(高可用) 详细安装步骤

    什么是HA? HA是High Availability的简写,即高可用,指当当前工作中的机器宕机后,会自动处理这个异常,并将工作无缝地转移到其他备用机器上去,以来保证服务的高可用.(简言之,有两台机器 ...

  9. 使用Nginx+Lua代理Hadoop HA

    一.Hadoop HA的Web页面访问 Hadoop开启HA后,会同时存在两个Master组件提供服务,其中正在使用的组件称为Active,另一个作为备份称为Standby,例如HDFS的NameNo ...

随机推荐

  1. 从后台拿到echarts的数据值,求出百分比

    从后台拿到数据是一个数组的格式 例: var arr = [6,4,0,0,0,0,0,0]; 后来得到新的需求,需要鼠标移入的时候提示数量和百分比,数量本身就可以拿到, 求百分比的时候:先拿到数组最 ...

  2. 深入浅出Java探针技术2---java字节码生成框架ASM、Javassist和byte buddy的使用

    目前Java字节码生成框架大致有ASM.Javassist和byte buddy三种 ASM框架介绍及使用 1.ASM介绍 ASM是一种Java字节码操控框架,能够以二进制形式修改已有的类或是生成类, ...

  3. SQLServer 2008以上误操作数据库恢复方法

    解决方法:       对于这类问题,主要是找回误操作之前的数据,在2008之前,有个很出名的工具Log Exploer,听说还挺好用的,这个网上大把教程,这里就不多说了.但是唯一遗憾的是,不支持20 ...

  4. react --- 搭建环境

    搭建react开发环境的准备工作 1. node.js 稳定版本 2. 安装cnpm,用cnpm代替npm 3. 用yarn替代npm yarn的安装:npm install -g yarn 搭建re ...

  5. Easy to Remember Color Guide for Non-Designers

    Notes: I'm not a designer. This is what i've self-learnt over the years because i couldn't afford go ...

  6. 后台启动mysql

    https://blog.csdn.net/codemacket/article/details/77719323

  7. springboot整合ActiveMQ,配置问题

    1.ActiveMQ的安装和相关配置修改 去官网下载安装包解压至文件夹 双击打开 打开浏览器输入 http://127.0.0.1:8161 到此activeMQ就安装好了 2.springboot工 ...

  8. 记flask连接容联云时提示172001,网络错误

    直接用sms.py发送没有问题,直接从写好的注册页面发送就不行.在网上查了不少方法,试过了依然没用,结果换了一个网络就好了,估计是部分网络无法正常发送..后来问了下是环境问题,开发环境不稳定

  9. linux查看用户登录时间以及命令历史

    1.查看当前登录用户信息 who命令: who缺省输出包括用户名.终端类型.登陆日期以及远程主机. who /var/log/wtmp 可以查看自从wtmp文件创建以来的每一次登陆情况 (1)-b:查 ...

  10. git1使用步骤初始化拉取修改提交推送

    Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令. 在执行完成 git init  ...