本文介绍的是HDFS的一种HA方案。虽然有checkpoint node \backup node等,但是不能实现自动的failover.




1.在2.0.0版本以下,namenode是单个的,如果namenode宕机,就会导致整个集群不可用。QJM 是HA的一种实现方式,通过master/slave方式启动多个namenode。

2.结构
 
    一般情况下,两个namenode组成master/slave结构,这两个namenode再连接到一组JNs(JournalNodes).master把集群的修改记录写到大多数据的JNs上,slave从JNS上读取修改信息并合并到本地的命名空间中。当master namenode故障后,slave在合并完所有修改记录后切换为active 状态的namenode.
    为了尽快的实现灾难切换,slave还需要实时的从datanode上读取块的最新信息。因此所有的datanode都要同时连接到master/slave 的namenode上。
    任一时刻必须只有一个namenode 是active状态,不然datanode会读取到混乱的数据。JNS集群保证在任一时刻只有一个namenode能修改(JNS上的数据)

3.硬件
namenode:两台配置一样的物理机,一台master 一台slave
JNS    :奇数个机器集群(满足majority)。最多允许(N-1)/2个节点失效。

4.部署
 一)、配置
    和HDFS Federation类似,HA配置向后兼容,运行只有一个Namenode运行而无需做任何修改。新的配置中,要求集群中所有的Nodes都有相同的配置文件,而不是根据不同的Node设定不同的配置文件。

    和HDFS Federation一样,HA集群重用了“nameservice ID”来标识一个HDFS 实例(事实上它可能包含多个HA Namenods);此外,“NameNode ID”概念被添加到HA中,集群中每个Namenode都有一个不同的ID;为了能够让一个配置文件支持所有的Namenodes(适用与Federation环境),那么相关的配置参数都以“nameservice ID”或“Namenode ID”作为后缀。

   修改hdfs-site.xml,增加如下几个配置参数,其参数的顺序无关。
    1、dfs.nameservices:nameservice的逻辑名称。可以为任意可读字符串;如果在Federation中使用,那么还应该包含其他的nameservices,以","分割。
  1. <property>
  2. <name>dfs.nameservices</name>
  3. <value>hadoop-ha,hadoop-federation</value>
  4. </property>

复制代码

2、dfs.ha.namenodes.[nameservice ID]:

  1. <property>
  2. <name>dfs.ha.namenodes.hadoop-ha</name>
  3. <value>nn1,nn2</value>
  4. </property>

复制代码

3、dfs.namenode.rpc-address.[nameservice ID].[namenode ID]

  1. <property>
  2. <name>dfs.namenode.rpc-address.hadoop-ha.nn1</name>
  3. <value>machine1.example.com:8020</value>
  4. </property>
  5. <property>
  6. <name>dfs.namenode.rpc-address.hadoop-ha.nn2</name>
  7. <value>machine2.example.com:8020</value>
  8. </property>

复制代码

其中nameservice ID需要和1)匹配,namenode ID需要和2) 匹配。配置项的值为相应namenode的hostname以及通讯端口号(Client与namenode RPC通讯端口),它和non-ha模式下“dfs.namenode.rpc-address”作用一样。每个namenode ID都需要单独配置。

    你可以根据需要,配置“dfs.namenode.servicerpc-address”,格式和上述一致。(SNN,backup节点与Namenode通讯地址)

    4、dfs.namenode.http-address.[nameservice ID].[namenode ID]

  1. <property>
  2. <name>dfs.namenode.http-address.hadoop-ha.nn1</name>
  3. <value>machine1.example.com:50070</value>
  4. </property>
  5. <property>
  6. <name>dfs.namenode.http-address.hadoop-ha.nn2</name>
  7. <value>machine2.example.com:50070</value>
  8. </property>

复制代码

各个namenode的HTTP地址。它和non-ha下的"dfs.namenode.http-address"配置作用一样。

     5、dfs.namenode.shared.edits.dir:

  1. <property>
  2. <name>dfs.namenode.shared.edits.dir</name>
  3. <value>qjournal://node1.example.com:8485;node2.example.com:8485;node3.example.com:8485/hadoop-ha</value>
  4. </property>

复制代码

配置JNS组的url地址,Namenodes将会从JNS组中读写edits。这是一个共享存储区,Active Namenode写入,Standby Node读取,每个Namenodeservice必须配置足够多的JNS地址(>=3,多数派),每条的格式为:
    “qjournal://host1:port1;host2:port2;host3:port3/journalId”
    其中journalId需要和上述配置中的“nameserviceID”匹配。

  1. <property>
  2. <name>dfs.journalnode.rpc-address</name>
  3. <value>0.0.0.0:8485</value>
  4. </property>
  5. <property>
  6. <name>dfs.journalnode.http-address</name>
  7. <value>0.0.0.0:8480</value>
  8. </property>

复制代码

此外,我们还需要在相应的JournalNodes上增加上述配置。

    6、dfs.client.failover.proxy.provider.[nameservice ID]:
    HDFS Client链接Namenode所使用的类,Client可以通过此类来判定哪个Namenode为Alive,并与它保持通信。目前hadoop中唯一的实现类为"ConfiguaredFailoverProxyProvider"。

  1. <property>
  2. <name>dfs.client.failover.proxy.provider.hadoop-ha</name>
  3. <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
  4. </property>

复制代码

7、dfs.ha.fencing.methods:在failover期间用来隔离Active Namenode的脚本或者java 类列表。
    虽然JNS可以确保集群中只有一个Active Node写入edits,这对保护edits一致性很重要,但是在failover期间,有可能Acitive Node仍然存活,Client可能还与其保持连接提供旧的数据服务,我们可以通过此配置,指定shell脚本或者java程序,SSH到Active NameNode然后Kill Namenode进程。它有两种可选值(具体参见官方文档):
    1) sshfence:SSH登录到Active Namenode,并Kill此进程。首先当前机器能够使用SSH登录到远端,前提是已经授权(rsa)。
    2) shell:运行shell指令隔离Active Namenode。

  1. <property>
  2. <name>dfs.ha.fencing.methods</name>
  3. <value>shell(/path/to/my/script.sh arg1 arg2 ...)</value>
  4. </property>

复制代码

“()”之间为shell脚本的路径,以及参数列表。

    8、fs.defaultFS(core-site.xml):
    在non-ha下,这个参数值为namenode的地址:“hdfs://namenode:8020”;不过在HA架构下,将使用namenservice名称替代[回答了第三个问题]

  1. <property>
  2. <name>fs.defaultFS</name>
  3. <value>hdfs://hadoop-ha</value>
  4. </property>

复制代码

9、dfs.journalnode.edits.dir:
   指定journalNode存储edits文件的本地路径。

    最终,上述配置信息,需要在server和Client端同时配置才能有效的适应HA与failover特性。

    二)、部署
    上述配置调整完毕后,我们就可以启动journalNodes守护进程,默认的"sbin/start-dfs.sh"脚本会根据"dfs.namenode.shared.edits.dir"配置,在相应的Datanode上启动journalNodes。当然我们可以使用::"bin/hdfs start journalnode"分别在相应的机器上启动。
    一旦JournalNodes启动成功,它们将会从Namenode上同步metadata。
    1、如果你的HDFS集群是新建的,那么需要在每个Namenode上执行"hdfs namenode -format"指令。
    2、如果你的namenodes已经format了,或者是将non-ha转换成ha架构,你应该在将其中一个namenode上的metadata复制到另一台上(dfs.namenode.name.dir目录下的数据),然后在那个没有format的新加入的namenode上执行"hdfs namenode -bootstrapStandby"。运行这个指令需要确保JournalNodes中持有足够多的edits。
    3、如果你将一个non-ha的Namenode(比如backup,其已经formated)切换成HA,你需要首先运行"hdfs -initializeSharedEdits",这个指令将本地Namenode中的edits初始化Journalnodes。

    此后,你就可以启动HA Namenodes。可以通过配置指定的HTTP地址(dfs.namenode.https-address)来查看各个Namenode的状态,Active or Standby。

    三)、管理员指令
    HA集群启动后,我们可以通过一些指令来管理HDFS集群。“bin/hdfs haadmin -DFSHAAdmin”指令,其可选参数:
    1、-transitionToActive <namenode id>与-transitionToStandbyl <namenode id>:将指定的namenode ID切换为Active或者standby。这个指令并不会触发“fencing method”,所以不常用,我们通常使用"hdfs haadmin -failover"来切换Namenode状态。
    2、-failover [--forcefence] [--foreactive] <serviceId-fist> <serviceId-second>:在两个Namenode之间failover。这个指令会触发将first节点failover到second节点。如果first处于standby,那么只是简单的将second提升为Active。如果first为Active,那么将会友好的将其切换为standby,如果失败,那么fencing methods将会触发直到成功,此后second将会提升为Active。如果fencing method失败,那么second将不会被提升为Active。
    例如:"hdfs haadmin -DFSHAAdmin -failover nn1 nn2"
    3、-getServiceState <serviceId>:获取serviceId的状态,Active还是Standby。链接到指定的namenode上,并获取其当前的状态,打印出“standby”或者“active”。我可以在crontab中使用此命令,用来监测各个Namenode的状况。
    4、-checkHealth <serviceId>:检测指定的namenode的健康状况。

五、自动Failover
    上述介绍了如何配置手动failover,在这种模式下,系统不会自动触发failover,即不会将Standby提升为Active,即使Active已经失效。接下来介绍如何实现自动failover。
    一)、组件
    Automatic Failover中,增加了2个新的组件:zookeeper集群,ZKFailoverController进程(简称为ZKFC)。
    Zookeeper是一个高可用的调度服务,可以保存一系列调度数据,当这些数据变更(notify)时可以通知Client,以及监控(montitor)Clients失效,自动failover的实现将依赖于Zookeeper的几个特性:
    1、Failure delection:失效检测,每个Namenode将会和zookeeper建立一个持久session,如果Namenode失效,那么次session将会过期失效,此后Zookeeper将会通知另一个Namenode,然后触发Failover。
    2、Active Namenode election:zookeeper提供了简单的机制来实现Acitve Node选举,如果当前Active失效,Standby将会获取一个特定的排他锁(lock),那么获取(持有)锁的Node接下来将会成为Active。

    ZKFailoverControllor(ZKFC)是一个zookeeper客户端,它主要用来监测和管理Namenodes的状态,每个Namenode机器上都会运行一个ZKFC程序,它的职责为:
    1、Health monitoring:ZKFC间歇性的使用health-check指令ping本地的Namenode,Namenode也会及时的反馈自己的health status。如果Namenode失效,或者unhealthy,或者无响应,那么ZKFS将会标记其为“unhealthy”。
    2、Zookeeper session manangement:当本地Nanenode运行良好时,ZKFC将会持有一个zookeeper session,如果本地Namenode为Active,它同时也持有一个“排他锁”(znode);这个lock在zookeeper中为“ephemeral” znode(临时节点),如果session过期,那么次lock所对应的znode也将被删除。(参见zookeeper特性)
    3、Zookeeper-based election:如果本地Namenode运行良好,并且ZKFS没有发现其他的的Namenode持有lock(比如Active失效后,释放了lock),它将尝试获取锁,如果获取成功,即“赢得了选举”,那么此后将会把本地Namenode标记为Active,然后触发Failover:首先,调用fencing method,然后提升本地Namenode 为Active。

    具体Failover过程和详细内容,请参见HDFS-2185

   二)、配置
    在Automatic Failover中,需要把一个重要的配置项添加到hdfs-site.xml中。

  1. <property>
  2. <name>dfs.ha.automatic-failover.enabled</name>
  3. <value>true</value>
  4. </property>

复制代码

此外还需要在core-site.xml中,增加如下配置:

  1. <property>
  2. <name>ha.zookeeper.quorum</name>
  3. <value>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181</value>
  4. </property>

复制代码

上述zookeeper集群为即备,尽可能选择相对平稳的zk集群。

    其中"dfs.ha.automatic-failover.enabled"可以为每个nameservice ID分别配置:dfs.ha.automatic-failover.enabled.[nameservice ID]。此外在core-site.xml中还可以配置Zookeeper Client的相关参数,比如sessionTimeout,这些配置项以"ha.zookeeper"开头,其中"dfs.ha."开头的部分配置项可以用来设定fencing method的相关控制。

    三)、初始化HA状态
    上述准备工作结束后,我们还需要在zookeeper中初始化HA的状态,通过执行“hdfs zkfc -formatZK”,此命令将会在zookeeker中创建一个znode,用来保存HA或failover的数据。

    四)、启动集群
    可以使用"start-dfs.sh"这个便捷的指令,它启动了hdfs所需要的所有守护进程,当然包括ZKFC。也可以使用"hadoop-daemon.sh start zkfc"手动启动ZKFC客户端。

    五)、检验Failover
    一旦Automatic Failover集群启动之后,我们需要检测Failover是否符合预期。首先,我们需要通过命令(getServiceState)或者在Namenode的Web UI上查看各个Namenode的状态,确认两个Namenode是否分别处于Active和Standby;此后,你可以手动关闭Active Namenode,比如使用kill -9 <pid num>,在确定Acitve Node失效后,再次检测原来的Standby是否已经提升为Active;不过因为zookeeper session过期判定需要达到sessionTimeout(可配置,ha.zookeeper.session-timeout),这个failover过程可能需要滞后数秒,默认为5秒。

    如果没有按照预期failover,那么你需要检测配置文件是否正确,zk服务是否正确。此外,我们还可以使用上述DFSHAAadmin指令多次尝试。

六、FAQ
    1、ZKFC和Namenodes守护进程的启动顺序是否重要?
    No,对于指定的Namenode,你可以在其之前或者之后启动ZKFC均可以,ZKFC只是调度Namenode的存活状态,如果不启动ZKFC,此Namenode将无法参与自动failover过程。
    2、是否需要额外的monitoring?
    你需要在Namenode机器上,添加额外的monitor用来监控ZKFC是否运行。在某些情况下,zookeeper集群的故障可能导致ZKFC意外中断,你需要适时的重启ZKFC。此外,还需要监控Zookeeper集群的运行状况,如果Zookeeper集群失效,那么HA集群将无法failover。
    3、如果Zookeeper失效,将会怎么样?
    如果zookeeper集群故障,那么Automatic Failover将不会触发,即使Namenode失效,这也意味着ZKFC无法正常运行。不过,如果Namenodes正常(即使有一个失效),那么HDFS系统将不会受到影响。因为HDFS Client并没有基于zookeeper做任何事情,当zookeeper集群仍需要尽快的恢复以避免当前Active失效而造成的“split-brain”等问题。
    4、是否可以在Namenodes之间指定优先级?
    NO,这是不能支持的。首先启动的Namenode将作为Active,我们只能认为控制Namenode启动的顺序来做到“优先级”。
    5、在Automatic Failover中,手动Failover怎么做?
    和普通的Failover一样,我们总是可以通过"hdfs haadmin -DFSHAAdmin -failover"来实现手动Failover。

    

三:QJM HDFS高可用的更多相关文章

  1. Hadoop框架:HDFS高可用环境配置

    本文源码:GitHub·点这里 || GitEE·点这里 一.HDFS高可用 1.基础描述 在单点或者少数节点故障的情况下,集群还可以正常的提供服务,HDFS高可用机制可以通过配置Active/Sta ...

  2. centos实现三个节点高可用

    centos实现三个节点高可用 使用的资源为keepalived和nginx 高可用主机IP地址 192.168.136.131 192.168.136.133 192.168.136.134 ngi ...

  3. HDFS 高可用分布式环境搭建

    HDFS 高可用分布式环境搭建 作者:Grey 原文地址: 博客园:HDFS 高可用分布式环境搭建 CSDN:HDFS 高可用分布式环境搭建 首先,一定要先完成分布式环境搭建 并验证成功 然后在 no ...

  4. HDFS高可用实现细节

    NameNode 高可用整体架构概述 在 Hadoop 1.0 时代,Hadoop 的两大核心组件 HDFS NameNode 和 JobTracker 都存在着单点问题,这其中以 NameNode ...

  5. Spring Cloud第三篇 | 搭建高可用Eureka注册中心

    ​ ​本文是Spring Cloud专栏的第三篇文章,了解前两篇文章内容有助于更好的理解后面文章: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring ...

  6. Redis学习三:Redis高可用之哨兵模式

    申明 本文章首发自本人公众号:壹枝花算不算浪漫,如若转载请标明来源! 感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫 22.jpg 前言 Redis 的 Sentinel 系统用于管理多个 Redi ...

  7. 版本管理工具Git(三)Gitlab高可用

    高可用模式 企业版 社区版 我们这里说一下成本比较低的主备模式,它主要依赖的是DRBD方式进行数据同步,需要2台ALL IN ONE的GitLab服务器,也就是通过上面安装方式把所有组件都安装在一起的 ...

  8. HADOOP docker(三):HDFS高可用实验

      前言1.机器环境2.配置HA2.1 修改hdfs-site.xml2.2 设置core-site.xml3.配置手动HA3.1 关闭YARN.HDFS3.2 启动HDFS HA4.配置自动HA4. ...

  9. hadoop hdfs 高可用

    单点故障: 如果某一个节点或服务出了问题,导致服务不可用 单点故障解决方式: 1.给容易出故障的地方安排备份 2.一主一备,要求同一时刻只能有一个对外提供服务 3.当active挂掉之后,standb ...

随机推荐

  1. 自己封装了的AlertController

    一直觉得使用系统这个东西写起来特别麻烦,每次都要写一大推东西,还是重复的,今天抽了点时间自己重新封装了一下,解决了自己的强迫症...,不多说,直接上代码了. 1.自己定义了一个名为XBZ的UIAler ...

  2. Paths with -a does not make sense.

    最近开始使用为windows的系统,进行git操作的时候出现了一个小问题. 使用命令: E:\IdeaProjects\mmall>git commit -am 'first commit in ...

  3. kali linux 安装 Mysql Can't read from messagefile 报错解决方案

    1.下载安装包 下载地点:https://dev.mysql.com/downloads/mysql/ 或者 wget http://dev.mysql.com/get/Downloads/MySQL ...

  4. 【模板】缩点(tarjan,DAG上DP)

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  5. MySQL Group Replication 搭建[Multi-Primary Mode]

    1. 环境准备 CentOS7.3 percona-server-5.7.18-14 两台服务器ip地址和主机名 10.0.68.206 yhjr-osd-mysql01-uat 10.0.68.20 ...

  6. spring-quartz 定时器 给targetMethod传递参数

    今天在做一个项目的时候,要给一个定时器任务的执行方法传递参数,在网上找了一下资料,可以使用arguments参数:   <bean id="subsidyJobDetail" ...

  7. vue实现多级弹窗

    webpack + vue 实现 弹窗功能 对于刚入门webpack + vue 不久的新人来说,这技术,确实有些不太友好,相比较于直接操纵dom元素的jQuery,直接操纵数据的 vue 在webp ...

  8. FireDAC的SQLite初探

    // uses FireDAC.VCLUI.Wait  之后, 可不用添加 TFDGUIxWaitCursor TFDConnection          // 数据连接 TFDQuery      ...

  9. 详解 Python3 正则表达式(一)

    本文翻译自:https://docs.python.org/3.4/howto/regex.html 博主对此做了一些批注和修改 ^_^ 正则表达式介绍 正则表达式(Regular expressio ...

  10. netfilter 学习摘要

    netfilter 子系入口在L3,完成后把数据包发往L4 netfilter 主要功能: 数据包选择(iptables) 数据包过滤 网络地址转换(NAT) 数据包操纵(在路由选择之前或之后修改数据 ...