NameNode的ZKFC机制
转自: http://hackershell.cn/?p=821
NameNode的HA可以个人认为简单分为共享editLog机制和ZKFC对NameNode状态的控制
在此之前,我先提几个问题:
一般导致NameNode切换的原因
ZKFC的作用是什么?如何判断一个NN是否健康
NameNode HA是如何实现的?
NameNode因为断电导致不能切换的原理,怎样进行恢复
一般导致NameNode切换的原因
随着集群规模的变大和任务量变多,NameNode的压力会越来越大,一些默认参数已经不能满足集群的日常需求,除此之外,异常的Job在短时间内创建和删除大量文件,引起NN节点频繁更新内存的数据结构从而导致RPC的处理时间变长,CallQueue里面的RpcCall堆积,甚至严重的情况下打满CallQueue,导致NameNode响应变慢,甚至无响应,ZKFC的HealthMonitor监控自己的NN异常时,则会断开与ZooKeeper的链接,从而释放锁,另外一个NN上的ZKFC进行抢锁进行Standby到Active状态的切换。这是一般引起的切换的流程。
当然,如果你是手动去切换这也是可以的,当Active主机出现异常时,有时候则需要在必要的时间内进行切换。
ZKFC的作用是什么?如何判断一个NN是否健康
在正常的情况下,ZKFC的HealthMonitor主要是监控NameNode主机上的磁盘还是否可用(空间),我们都知道,NameNode负责维护集群上的元数据信息,当磁盘不可用的时候,NN就该进行切换了。
/**
* Return true if disk space is available on at least one of the configured
* redundant volumes, and all of the configured required volumes.
*
* @return True if the configured amount of disk space is available on at
* least one redundant volume and all of the required volumes, false
* otherwise.
*/
public boolean hasAvailableDiskSpace() {
return NameNodeResourcePolicy.areResourcesAvailable(volumes.values(),
minimumRedundantVolumes);
}
注: minimumRedundantVolumes
获取值的方法如下:
minimumRedundantVolumes = conf.getInt(
DFSConfigKeys.DFS_NAMENODE_CHECKED_VOLUMES_MINIMUM_KEY,
DFSConfigKeys.DFS_NAMENODE_CHECKED_VOLUMES_MINIMUM_DEFAULT);
其中,
DFS_NAMENODE_CHECKED_VOLUMES_MINIMUM_KEY = "dfs.namenode.resource.checked.volumes.minimum";
DFS_NAMENODE_CHECKED_VOLUMES_MINIMUM_DEFAULT = 1;
volumes
获取自 配置项dfs.namenode.shared.edits.dir的值
除了可用状态(SERVICE_HEALTHY)之外,还有SERVICE_UNHEALTHY(磁盘空间不可用),SERVICE_NOT_RESPONDING(其他的一些情况)状态,在这两个状态中,它都认为NN是不健康的。
NameNode HA是如何实现的?
我们前面说到,ZKFC是如何判断NN是否健康,接下来当NN处于非健康状态时,NameNode是如何进行切换的呢?
在ZKFailoverController这个类中,实行了两个重要的Callbacks函数,一个叫ElectorCallbacks,另一个叫HealthCallbacks,顾名思义就是选举和健康检查用的回调函数,其中还有两个重要的组成部分elector(ActiveStandbyElector),healthMonitor(HealthMonitor),总体的就如上图所示。
ElectorCallbacks:
/**
* Callbacks from elector
*/
class ElectorCallbacks implements ActiveStandbyElectorCallback {
@Override
public void becomeActive() throws ServiceFailedException {
ZKFailoverController.this.becomeActive();
}
@Override
public void becomeStandby() {
ZKFailoverController.this.becomeStandby();
}
...
}
HealthCallbacks:
/**
* Callbacks from HealthMonitor
*/
class HealthCallbacks implements HealthMonitor.Callback {
@Override
public void enteredState(HealthMonitor.State newState) {
setLastHealthState(newState);
recheckElectability();
}
}
对于HealthMonitor来说,在ZKFC进程启动的时候,就已经将HealthCallbacks注册进去了,HealthMonitor都会定期的检查NameNode是否健康,我们可以通过监控ha.health-monitor.check-interval.ms去设置监控的间隔时间和通过参数ha.health-monitor.rpc-timeout.ms设置timeout时间,当集群变大的时候,需要适当的设置改值,让ZKFC的HealthMonitor没那么“敏感”。
ZKFC通过RPC调用监控NN进程,当出现异常时,则进入不同的处理逻辑,以下是简化的代码:
private void doHealthChecks() throws InterruptedException {
while (shouldRun) {
try {
status = proxy.getServiceStatus();
proxy.monitorHealth();
healthy = true;
} catch (HealthCheckFailedException e) {
...
enterState(State.SERVICE_UNHEALTHY);
} catch (Throwable t) {
...
enterState(State.SERVICE_NOT_RESPONDING);
Thread.sleep(sleepAfterDisconnectMillis);
return;
}
...
}
回调函数就是这么起作用啦,那么回调函数做了什么呢?总的来说,如果NN健康(SERVICE_HEALTHY)就加入选举,如果不健康就退出选举(SERVICE_UNHEALTHY,SERVICE_NOT_RESPONDING)
case SERVICE_UNHEALTHY:
case SERVICE_NOT_RESPONDING:
LOG.info("Quitting master election for " + localTarget +
" and marking that fencing is necessary");
elector.quitElection(true);
break;
说到退出选举就关系到elector(ActiveStandbyElector)了,true代表如果NN从Actice变为Standby出现异常是要去fence的,这就是为啥NN会挂掉的原因之一
如何退出选举?就是close zkClient的链接,让ZooKeeper上面的维持的选举锁消失
void terminateConnection() {
if (zkClient == null) {
return;
}
LOG.debug("Terminating ZK connection for " + this);
ZooKeeper tempZk = zkClient;
...
try {
tempZk.close();
} catch(InterruptedException e) {
LOG.warn(e);
}
...
}
对于ActiveStandbyElector来说,他有个WatcherWithClientRef类专门用来监听ZooKeeper上的的znode的事件变化,当事件变化时,就会调用ActiveStandbyElector的processWatchEvent的方法
watcher = new WatcherWithClientRef();
ZooKeeper zk = new ZooKeeper(zkHostPort, zkSessionTimeout, watcher);
和
/**
* Watcher implementation which keeps a reference around to the
* original ZK connection, and passes it back along with any
* events.
*/
private final class WatcherWithClientRef implements Watcher {
...
@Override
public void process(WatchedEvent event) {
hasReceivedEvent.countDown();
try {
hasSetZooKeeper.await(zkSessionTimeout, TimeUnit.MILLISECONDS);
ActiveStandbyElector.this.processWatchEvent(
zk, event);
} catch (Throwable t) {
fatalError(
"Failed to process watcher event " + event + ": " +
StringUtils.stringifyException(t));
}
}
...
}
在ActiveStandbyElector的processWatchEvent方法中,处理来自不同事件的逻辑,重新加入选举或者继续监控znode的变化,当另外一个ZKFC监控到事件变化得时候,就去抢锁,抢锁实质上就是创建znode的过程,而且创建的是CreateMode.EPHEMERAL类型的,所以,当HealthMonitor监控到NN不健康时,就会断开连接,节点就会消失,watcher就会监控到NodeDeleted事件,进行创建节点。
switch (eventType) {
case NodeDeleted:
if (state == State.ACTIVE) {
enterNeutralMode();
}
joinElectionInternal();
break;
case NodeDataChanged:
monitorActiveStatus();
break;
又因为ActiveStandbyElector实现了StatCallback接口,当节点创建成功时,就会回调processResult方法看是否创建成功,如果创建成功则去检查zkBreadCrumbPath是否存在之前的Active节点,如果存在,则调用RPC让其变为Standby,看能否转变成功,否则则SSH过去fence掉NN进程。,保持Active节点只有一个,并且恢复正常服务
NameNode因为断电导致不能切换的原理,怎样进行恢复
ActiveNN断电,网络异常,负载过高或者机器出现异常无法连接,Standby NN无法转化为Active,使得HA集群无法对外服务,原因是Active NN节点在断电和不能服务的情况下,zknode上保存着ActiveBreadCrumb, ActiveStandbyElectorLock两个Active NN的信息,ActiveStandbyElectorLock由于Active NN出现异常断开,Standby NN去抢锁的时候就会去检查ActiveBreadCrumb是否有上一次的Active NN节点,如果有,就会就会尝试让Active NN变为Standby NN,自己转化为Active NN,但是由于调用出现异常,所以会采用ssh的方式去Fence之前的Active NN,因为机器始终连接不上,所以无法确保old active NN变为Standby NN,自己也无法变为Active NN,所以还是保持Standby状态,避免出现脑裂问题。
解决方案是确定Active关机的情况下重新hdfs zkfc -formatZK就可以了。
总 结
NN GC或者在压力大的情况下可以调整GC算法和增加NameNode节点的线程数,加快NN对请求的处理速度,也可以分离节点的端口dfs.namenode.rpc-address.ns1.nn2和dfs.namenode.servicerpc-address.ns1.nn2分离client和datanode节点等服务类型的请求,进行分担压力,也可以适当的调整ZKFC的监控timeout的时间等等
NameNode的ZKFC机制的更多相关文章
- [Hadoop]Hadoop章3 NameNode的ZKFC机制
基本概念 首先我们要明确ZKFC 是什么,有什么作用: zkfc是什么? ZooKeeperFailoverController 它是什么?是Hadoop中通过ZK实现FC功能的一个实用工具. 主要作 ...
- Hadoop NameNode的ZKFC机制
博客原文:hackershell 之前在准备中级课程PPT,整理了下HA的基本内容,并且感谢松哥为我们提供了HA不会切的问题,以至于之后刚好出现的NameNode宕机,能够快速解决. NameNode ...
- namenode和datanode机制
转自:https://www.cnblogs.com/DarrenChan/p/6416043.html?utm_source=itdadao&utm_medium=referral 首先我们 ...
- Hadoop- NameNode和Secondary NameNode元数据管理机制
元数据的存储机制 A.内存中有一份完整的元数据(内存meta data) B.磁盘有一个“准完整”的元数据镜像(fsimage)文件(在namenode的工作目录中) C.用于衔接内存metadata ...
- Hadoop的namenode的管理机制,工作机制和datanode的工作原理
HDFS前言: 1) 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: 2)在大数据系统中作用: 为各类分布式运算框架(如:mapr ...
- hdfs文件上传机制与namenode元数据管理机制
1.hdfs文件上传机制 文件上传过程: 1.客户端想NameNode申请上传文件, 2.NameNode返回此次上传的分配DataNode情况给客户端 3.客户端开始依向dataName上传对应 ...
- hdfs namenode/datanode工作机制
一. namenode工作机制 1. 客户端上传文件时,namenode先检查有没有同名的文件,如果有,则直接返回错误信息.如果没有,则根据要上传文件的大小以及block的大小,算出需要分成几个blo ...
- HDFS中NameNode管理元数据机制
NameNode职责 响应客户端请求 维护目录树 管理元数据(查询,修改) HDFS元数据存储 内存中有一份完整的元数据(特定数据结构) 磁盘有一个“准完整”的元数据的镜像文件 当客户端对HDFS中的 ...
- Hadoop(五)—— HDFS NameNode、DataNode工作机制
一.NN与2NN工作机制 NameNode(NN) 1.当HDFS启动时,会加载日志(edits)和镜像文件(fsImage)到内存中. 2-4.当元数据的增删改查请求进来时,NameNode会先将操 ...
随机推荐
- ASP.NET Web API实践系列11,如何设计出优秀的API
本篇摘自:InfoQ的微信公众号 在设计API的时候考虑的问题包括:API所使用的传输协议.支持的消息格式.接口的控制.名称.关联.次序,等等.我们很难始终作出正确的决策,很可能是在多次犯错之后,并从 ...
- java根据模板导出PDF详细教程
原文:https://blog.csdn.net/pengyufight/article/details/75305128 题记:由于业务的需要,需要根据模板定制pdf文档,经测试根据模板导出word ...
- 组织安全性SQL
BEGIN mo_global.set_policy_context ('S', '&组织ID'); END; SELECT * FROM hr_organization_units_v; ...
- 给js创建的一个input数组绑定click事件
<html> <body> <input type="button" name="input[]" value="按钮1 ...
- Selenium:Hello,World!
背景 伟鹏同学在学习自动化测试了,开发人员也有必要学习一下,有如下好处: 可以开发一些小工具. 可以熟悉一下自动化测试开发技术. 代码 using System; using Microsoft.Vi ...
- Linux学习16-CentOS安装gitlab环境
前言 在学习Gitlab的环境搭建之前,首先需要了解Git,Gitlab,GitHub他们三者之间的关系 Git 它是一个源代码版本控制系统,可让您在本地跟踪更改并从远程资源推送或提取更改. GitH ...
- 较老版本 AFNetworking 使用心得
较老版本的 AFNetworking 下载链接 http://pan.baidu.com/s/14Cxga 将压缩包中的文件夹拖入xcode工程项目中并引入如下的框架 简单的 JOSN 解析例子 ...
- Android NDK:Aborting..Stop的处理方法
在eclipse中配置cocos2d-x的android环境时,遇到这样的错误提示 网上搜索了一下,说是在NDK_MODULE_PATH环境变量下未找到所需要的Android.mk文件,后来仔细研究了 ...
- Java(C#)基础差异-语法
1.long类型 Java long类型,若赋值大于int型的最大值,或小于int型的最小值,则需要在数字后加L或者l,表示该数值为长整数,如long num=2147483650L. 举例如下: p ...
- 使用Log4j将程序日志实时写入Kafka(转)
原文链接:使用Log4j将程序日志实时写入Kafka 很多应用程序使用Log4j记录日志,如何使用Kafka实时的收集与存储这些Log4j产生的日志呢?一种方案是使用其他组件(比如Flume,或者自己 ...