实现 Hadoop 高可用的方案

一、Hadoop 的高可用瓶颈
  NameNode 是 HDFS 的核心配置,HDFS又是 Hadoop 的核心组件,NameNode 在 Hadoop 集群中至关重要。
  NameNode 宕机,将导致集群不可用,如果 NameNode 数据丢失将导致整个集群的数据丢失,而 NameNode 的数据的更新又比较频繁,实现 NameNode 高可用势在必行。

二、Hadoop 的单点故障解决方案
(一)官方提供了两种解决方案

  HDFS with NFS(就是如果原来的 name 挂掉,就 mount 一台新的)。类似于NFS,共享存储,但是还是会出现nfs单点故障。

  HDFS with QJM(矛盾转移方案,nfs 实现的)。就是底层节点同时像两个NameNode同步数据。

(二)两种方案的异同比较
  第一种方案:NFS   第二种方案:QJM
  NM           NM
  ZK           ZK
  ZKFailoverController    ZKFailoverController (高可用软件)
  NFS          JournalNode(journalnode负责数据的实时同步)

(三)两种方案的讲解

  相同点
  它们都能实现热备,都是一个 Active NN 和一个 Standby NN。都使用 Zookeeper 和   ZKFC 来实现自动失效恢复。失效切换都使用 Fencin 配置的方法来 Active NN。

  不同点
  NFS 数据共享变更方案把数据存储在共享存储里,我们还要考虑 NFS 的高可用设计。
  QJM 不需要共享存储,但需要让每一个 DN 都知道两个 NN的 位置,并把块信息和心跳包发送给 Active 和 Standby 这两个 NN。

(四)建议选择的方案是 QJM
  QJM 是 Hadoop 给出的 HDFS 高可用HA方案:HDFS 通常有两个 NameNode 组成,一个处于 Active 状态,另一个处于 Standby 状态。Active NameNode 对外提供服务,比如处理来自客户端的 RPC 请求,而 Standby NameNode 则不对外提供服务,仅同步 Active NameNode 的状态,以便能够在它失败时进行切换。

三、QJM 方案的特点
(一) 它是典型的 HA 集群
  NameNode 会被配置在两台独立的机器上,在任何时候,一个 NameNode 处于活动状态,而另一个 NameNode 则处于备份状态。活动状态的 NameNode 会响应集群中所有的客户端,备份状态的 NameNode 只是作为一个副本,保证在必要的时候提供一个快速的转移。

(二)它实现了 NameNode 高可用架构
  为了让 Standby Node 与 Active Node 保持同步,这两个 Node 都与一组称为JNS的互相独立的进程保持通信(Journal Nodes)。当 Active Node 更新了namespace,它记录修改日志发送给 JNS 的多数派。Standby Node 将会从 JNS 中读取这些 edits,并持续关注它们对日志的变更。
  补充:NameNode 更新很频繁,为了保持主被数据的一致性,为了支持快速 Failover,Standby Node 持有集群中 blocks 的最新位置是非常必要的。为了达到这一目的,DataNodes 上需要同时配置这两个 Namenode 的地址,同时和它们都建立心跳连接,并把 block 位置发送给它们。
  补充:任何时刻,只能有一个 Active NameNode,否则会导致集群操作混乱,两个 NameNode 将会有两种不通的数据状态,可能会导致数据丢失或状态异常,这种情况通常成为 “split-brain”(俗称:脑裂,三节点通讯阻断,即集群中不通的 DataNode 看到了不同的 Active NameNodes)
  对于 JN S而言,任何时候只允许一个 NameNode 作为 writer:在 Failover 期间,原来的 Standby Node 将会接管 Active 的所有职能,并负责像 JNS 写入日志记录,这种机制阻止了其他 NameNode 处于 Active 状态的问题。

(三)此时 Hadhoop 的数据变更日志就被放在公共区域了
  jns 是多台主机创建的一个集群 fsedits ,数据的变更日志原来是放在 senamenode 里而如今就放在 jns 里面了。而 Standby Node 将日志变更应用在自己的namespace 中,当 Failover 发生时,Standby 将会在自己的 namespace 中,当 Failover 发生时,Standby 将会在提升自己为 Active 之前,确保能够从 JNS 中读取所有的 edits,即在 Failover 发生之前 Standy 持有的 namespace 与 Active 保持完全同步。