• 欢迎关注微信公众号:九万里大数据
  • 请使用Ctrl+D收藏本站到书签栏
  • 手机也可访问本站 jwldata.com

HDFS的NameNode高可用架构和原理详解(NameNode HA)

大数据技术 九万里大数据 9个月前 (08-18) 634次浏览 0个评论 扫描二维码
文章目录[隐藏]

背景

在Hadoop 1.x的时候,NameNode存在单点故障问题。如果NameNode进程或者所在的机器有故障,会导致整个集群不可用,直到NameNode进程重启或者所在的机器恢复。在hadoop 2.x之后,增加了NameNode的HA机制。即在一个HDFS集群中运行两个NameNode节点,一个是Active状态的,一个是Standby状态的。当Active状态的NameNode挂掉后,Standby状态的NameNode会切换成Active状态。

NameNode的HA架构

HDFS NameNode的HA架构如下图所示:
HDFS的NameNode高可用架构和原理详解(NameNode HA)

涉及到几个主要角色如下:

  • Active NameNode: 与Standby NameNode形成互备,只有处于Active状态的NameNode节点才能对外提供读写服务。
  • Standby NameNode: 承接原来SecondaryNameNode的checkpoint功能。Standby NameNode从JN拉取edit log,合并到自己的fsimage上。在Active NameNode故障时,Standby会切换成Active状态。
  • JournalNode: 必须奇数个节点(3,5,7…),至少3个节点。当有N个JN时,可以允许(N-1)/2个NameNode发生故障。Active NameNode发送edit log到JN的绝大部分节点上。
  • ZKFailoverController: ZKFC作为独立的进程运行,对NameNode的主备切换进行总体控制。每个运行NameNode的机器上,都需要同时运行一个ZKFC。ZKFC定期监测它本机的NameNode的健康状态,会与Zookeeper之间维护一个session,当本机的NameNode是Active状态时,会把某个znode“加锁”(创建znode)。如果session过期,这个znode会被删除。当其他ZKFC看到这个znode不存在,会去请求“加锁”(创建znode),如果成功“加锁”,也就是所谓的赢得了选举(won the election),它所在机器上的NameNode成为了Active状态。当然,NameNode也支持不依赖Zookeeper的手动主备切换。
  • DataNode: 同时向Active NameNode和Standby NameNode上报数据块位置信息和心跳包。
  • Zookeeper: ZKFC和Zookeeper之间维护了一个session,如果NameNode挂掉了,会使session失效,进而导致Zookeeper上保存的lock znode被删除,而ZKFC就是通过这个znode来进行Active NameNode选举。

手动NameNode主备切换

进行一次手动NameNode主备切换,观察Zookeeper上znode的变化,印证一下上面讲的ZKFailoverController的原理。CDH上当前Active NameNode在ctkf02上,在Cloudera Manager上停止该Active NameNode,然后会发现ctkf01上的Standby NameNode切换成了Active状态。Zookeeper上znode的变化如下:

zookeeper-client
get /hadoop-ha/nameservice1/ActiveStandbyElectorLock

HDFS的NameNode高可用架构和原理详解(NameNode HA)

Quorum Journal Manager(QJM)

QJM集群由奇数个JournalNode节点组成。当Active NameNode中有事务提交,Active NameNode会将edit log发给JournalNode集群,JournalNode集群通过paxos协议保证数据一致性(即:超过一半以上的JournalNode节点确认),这个数据就提交到了共享存储。Standby NameNode定期从JournalNode读取edit log,合并到自己的fsimage上。

HDFS的NameNode高可用架构和原理详解(NameNode HA)

处于Standby状态的NameNode转换为Active状态的时候,有可能上一个Active NameNode发生了异常退出,那么 JournalNode集群中各个JournalNode上的edit log就可能会处于不一致的状态,所以首先要做的事情就是让 JournalNode集群中各个节点上的edit log恢复为一致。另外如前所述,当前处于Standby状态的NameNode的内存中的文件系统镜像有很大的可能是落后于旧的Active NameNode的,所以在JournalNode集群中各个节点上的edit log达成一致之后,接下来要做的事情就是从JournalNode集群上拉取补齐落后的edit log。只有在这两步完成之后,当前新的Active NameNode才能安全地对外提供服务。

Quorum Journal Manager(QJM)内部实现

HDFS的NameNode高可用架构和原理详解(NameNode HA)

  • FSEditLog:这个类封装了对edit log的所有操作,是NameNode对edit log的所有操作的入口。
  • JournalSet:这个类封装了对本地磁盘和JournalNode集群上的edit log的操作,内部包含了两类 JournalManager,一类为FileJournalManager,用于实现对本地磁盘上edit log的操作。一类为QuorumJournalManager,用于实现对JournalNode集群上共享目录的edit log的操作。FSEditLog只会调用 JournalSet的相关方法,而不会直接使用FileJournalManager和QuorumJournalManager。
  • FileJournalManager:封装了对本地磁盘上的edit log文件的操作,不仅NameNode在向本地磁盘上写入edit log的时候使用FileJournalManager,JournalNode在向本地磁盘写入edit log的时候也复用了 FileJournalManager的代码和逻辑。
  • QuorumJournalManager:封装了对JournalNode集群上edit log的操作,它会根据JournalNode集群的URI创建负责与JournalNode集群通信的类AsyncLoggerSet,QuorumJournalManager通过AsyncLoggerSet来实现对JournalNode集群上edit log的写操作。对于读操作,QuorumJournalManager则是通过HTTP接口从JournalNode上的JournalNodeHttpServer读取edit log的数据。
  • AsyncLoggerSet:内部包含了与JournalNode集群进行通信的AsyncLogger列表,每一个AsyncLogger对应于一个JournalNode节点,另外AsyncLoggerSet也包含了用于等待大多数JournalNode返回结果的工具类方法给QuorumJournalManager使用。
  • AsyncLogger:具体的实现类是IPCLoggerChannel,IPCLoggerChannel在执行方法调用的时候,会把调用提交到一个单线程的线程池之中,由线程池线程来负责向对应的JournalNode的JournalNodeRpcServer发送RPC请求。
  • JournalNodeRpcServer:运行在JournalNode节点进程中的RPC服务,接收NameNode端的AsyncLogger的RPC请求。
  • JournalNodeHttpServer:运行在JournalNode节点进程中的Http服务,用于接收处于Standby状态的NameNode和其它JournalNode的同步edit log文件流的请求。

NameNode的切换流程

HDFS的NameNode高可用架构和原理详解(NameNode HA)

NameNode的切换流程分为以下几个步骤:

  • HealthMonitor初始化完成之后会启动内部的线程来定时调用对应NameNode的HAServiceProtocol RPC接口的方法,对NameNode的健康状态进行检测。
  • HealthMonitor如果检测到NameNode的健康状态发生变化,会回调ZKFailoverController注册的相应方法进行处理。
  • 如果ZKFailoverController判断需要进行主备切换,会首先使用ActiveStandbyElector来进行自动的主备选举。
  • ActiveStandbyElector与Zookeeper进行交互完成自动的主备选举。
  • ActiveStandbyElector在主备选举完成后,会回调ZKFailoverController的相应方法来通知当前的NameNode成为主NameNode或备NameNode。
  • ZKFailoverController调用对应NameNode的HAServiceProtocol RPC接口的方法将NameNode转换为Active状态或Standby状态。

Fence

当使用QJM方式时,只允许一个NameNode往JournalNode写edit log,这样可以避免出现脑裂现象。当发生NameNode主备切换时,为了防止出现老NameNode僵死但还在写JournalNode的情况,需要引入fence的概念。有两种fence方法,分别是shell和sshfence。shell的方法,是通过shell命令来对Active NameNode进行fence。而sshfence的方法,是通过SSH连接到Active NameNode,然后杀掉NameNode进程。用户也可以通过org.apache.hadoop.ha.NodeFencer来实现自己的fence方法。

ZKFC的设计

jira HDFS-2185记录了ZKFC的设计。
https://issues.apache.org/jira/browse/HDFS-2185
HDFS的NameNode高可用架构和原理详解(NameNode HA)

参考文档

欢迎关注我的微信公众号“九万里大数据”,原创技术文章第一时间推送。
欢迎访问原创技术博客网站 jwldata.com,排版更清晰,阅读更爽快。


HDFS的NameNode高可用架构和原理详解(NameNode HA)
 


本站文章,如未注明,均为原创 | 原创文章版权归九万里大数据所有,未经许可不得转载。
本文链接:HDFS的NameNode高可用架构和原理详解(NameNode HA)
喜欢 (1)

您必须 登录 才能发表评论!