三:QJM HDFS高可用

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

http://hadoop.apache.org/docs/r2.6.3/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html

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.部署

以下从http://blog.csdn.net/stark_summer/article/details/44219095复制

一)、配置
    和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。

来源: http://blog.csdn.net/stark_summer/article/details/44219095

http://hadoop.apache.org/docs/r2.6.3/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.htmlhttp://hadoop.apache.org/docs/r2.6.3/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html

来自为知笔记(Wiz)

时间: 2024-08-03 20:50:26

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

高性能反向代理软件HAProxy(三)之高可用

一.实验目的 软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载实现.LVS是基于Linux操作系统实现的一种软负载,而HAProxy则是基于第三方应用实现的软负载.HAProxy相比LVS的使用要简单很多,但跟LVS一样,HAProxy自己并不能实现高可用,一旦HAProxy节点故障,将会影响整个站点.本文带来的是HAProxy基于KeepAlived实现Web高可用及动静分离. 二.实验环境介绍是准备 1.实验拓扑图 2.环境介绍 3.同步时间 [[emai

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

? ?本文是Spring Cloud专栏的第三篇文章,了解前两篇文章内容有助于更好的理解后面文章: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cloud第二篇 | 使用并认识Eureka注册中心 ? 一.Eureka注册中心高可用集群概述 1-1.传统架构 在微服务架构的这种分布式系统中,我们要充分考虑各个微服务组件的高可用性问题,不能有单点故障,由于注册中心Eureka本身也是一个服务,如果它只有一个节点,那么它有可能发生故障,这样我们

nginx学习(三)——nginx高可用方案nginx+keepalived

一.Nginx+tomcat实现集群 当我们网站并发量高的时候,一台tomcat无法承受大量并发,可以考虑Nginx+Tomcat集群来实现.咱们这就做一个集群演示. 步骤说明 1.我这里准备3台tomcat,端口分别是8081.8082.8083 针对同一个域名,每次用Nginx实现不同的转发,分别在每个tomcat的webapps目录下创建ROOT目录,并创建index.html,分别在html的body里标记1/2/3以示区分. 2.配置负载均衡upstream实现集群 upstream

mysql进阶(三)MHA高可用集群

简介: 1.MHA目前在MySQL高可用方面是一个相对成熟的解决方案,是MySQL高可用环境下故障切换和主从提升的高可用软件 2.MHA能在短时间内完成故障切换,并且在最大程度上保证数据的一致性,以达到真正意义上的高可用 3.MHA基于mysql协议,通过mysql主从或主主进行复制 4.MHA官网:https://code.google.com/p/mysql-master-ha/ 软件由两部分组成:MHA Manager(关理节点)和MHA Node(数据节点) 1.MHA Manager可

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

高可用模式 企业版 社区版 我们这里说一下成本比较低的主备模式,它主要依赖的是DRBD方式进行数据同步,需要2台ALL IN ONE的GitLab服务器,也就是通过上面安装方式把所有组件都安装在一起的2台机器. 什么是DRBD 它是分布式复制块设备,软件实现的无需共享可以在服务器之间镜像块设备的存储复制解决方案. 左侧为A节点,右侧为B节点 DRBD运行在内核里,它是一个内核模块.Linux2.6.33开始已经整合进内核.上图A为活动节点,B为被动节点.A收到数据发往内核的数据通路,DRBD在数

HADOOP docker(二):HDFS 高可用原理

1.环境简述2.QJM HA简述2.1为什么要做HDFS HA?2.2 HDFS HA的方式2.2 HSFS HA的结构2.3 机器要求3.部署HDFS HA3.1 详细配置3.2 部署HDFS HA4. HDFS HA的管理5.自动切换5.1 使用zookeeper实现HA原理5. 部署hdfs自动切换5.1 关闭集群5.2 添加HA配置5.3 在zookeeper中初始化HA状态5.4 开启集群5.5 使用zookeeper时的安全机制6.FAQ7.做了HA后HDFS的升级.回滚7.1 升级

DNS服务部署(三)之高可用主辅架构

1.架构拓扑图 2.环境描述 服务器名称 IP地址 主DNS服务器 192.168.1.107 辅助DNS服务器 192.168.1.108 注意:这里Linux版本是centos5.8. 3.主辅DNS服务器bind安装 [[email protected] ~]# yum -y install bind bind-chroot ypbind bind-utils caching-nameserver 注意:这里主DNS服务器我们前面已经部署了! 4.配置辅助DNS服务器 A.将主DNS服务器

Kubernetes(K8s)安装部署过程(三)--创建高可用etcd集群

这里的etcd集群复用我们测试的3个节点,3个node都要安装并启动,注意修改配置文件 1.TLS认证文件分发:etcd集群认证用,除了本机有,分发到其他node节点 scp ca.pem kubernetes-key.pem kubernetes.pem [email protected]10.10.90.106:/etc/kubernetes/ssl scp ca.pem kubernetes-key.pem kubernetes.pem [email protected]10.10.90.

配置NFS作为HDFS高可用的共享存储系统

所有命令或步骤: 首先,在各个节点上安装nfs服务 yum install -y nfs service rpcbind start service nfs start 编辑/etc/exports文件,添加下面一行 /mnt/share hadoop1(rw,no_root_squash,async) hadoop2(rw,no_root_squash,async) hadoop6(rw,no_root_squash,async) hadoop7(rw,no_root_squash,async