Hadoop NameNode单点问题解决方案之一 AvatarNode

我们遇到的情况

HadoopNameNode存在单点问题。这个问题会影响分布式平台24*7运行。先说说我们的情况吧。

我们的团队负责管理一个1200节点的集群(总大小12PB),目前是运行版本为Hadoop0.20,transactionlogs写入一个共享的NFSfiler(注:NetAppNFSFiler)。

经常遇到需要中断服务的问题是给hadoop打补丁。DataNode打补丁比较简单,不会造成服务中断,每次对其中的一部分DataNode部署新的代码、重启,就OK了。问题是需要给NameNode部署新的代码时,NodeNode重启需要花费1个小时,这期间所有的Hadoop服务都不能运行。这是不可忍受的,所以我们就想着把NameNode有个备份。我们的解决方案可以保证在1分钟内切换完成。

当时HDFSBackupNode在Hadoop0.20中还不能用,升级Hadoop0.20也不是一个很好的选择。这个升级部署之前,需要花费大量时间做测试。

经过仔细的分析现状和可能的解决方案。我们设计了一个简单的解决方案:

a.目前我们有两个NameNode一个PrimaryNameNode和一个StandbyNodenode,我们不用担心split-brain-scenario(可以想想精神分裂)和IO-fencing(这个名词不太了解)。OP能保证PrimaryNameNode完全down后,StandbyNameNode才能被切换。

b.我们不想修改NameNode的任何代码,只想基于HDFS构建一个软件层来保证HA。我们需要一个deamon来切换Primary和Standby.

词语“Avatar”的意思是实体的变体,所以借用这个词,把NameNode的wrapper称为AvatarNode。AvatarNode完全继承NameNode,所以NameNode的优点它都完全具备。

AvatarNode介绍

AvatarNode完全封装NameNode。AvatarNode运行有两种模式PrimaryAvatar或者standbyAvatar.如果启动运行在PrimaryAvatar模式,那么它就和当前NameNode功能完全一样,其实运行的代码就是NameNode的代码。运行PrimaryAvatar模式的AvatarNode机器,保存HDFS事务日志(editlog)到一个共享的NFS。在另外一台机器上,启动AvatarNode的另一个实例,运行在StandbyAvatar模式。

StandbyAvatarNode封装了NameNode和SecondaryNameNode。StandbyAvatarNode持续的从共享的NFSfiler中读取HDFSeditlog,并持续的把这些事务推送到StandbyAvatarNode中NameNode实例。StandbyAvatarNode中的NameNode运行在SafeMode。原因是不能让它负责NameNode的工作,但是必须保持和NameNode同步的NameNodeMetadata信息。

HDFS客户端访问NameNode通过一个虚拟IP(VirtualIPAddress,注:这块其实可以用zookeeper来取代).当发生故障需要快速切换时,管理员会在机器M1上杀掉PrimaryAvatarNode进程,然后在机器M2上设置StandbyAvatarNode作为PrimaryAvatar。StandbyAvatarNode会保证把所有提交的事务都处理完,因为StandbyAvatarNode会重新打开editlog,并处理完文件中所有的事务.这个假设是基于NFS-v3支持close-to-opencachecoherencysemantics。StandbyAvatarNode把所有NFSfiler上的事务处理完之后,退出SafeMode模式。管理员将M2的VIP换为M1,这样所有的HDFS客户端的请求会提交到M2的实例上。这个failover一般情况只需要几秒钟。

另外根本不需要单独一台SecondaryNameNode。AvatarNode在Standbyavatar模式时,可以履行SecondaryNameNode的职责。StandbyAvatarNode持续的处理从PrimaryAvantar来的所有的事务,在处理事务日志的空闲间隙会唤醒SecondaryNameNode进程,创建并上传一个新的checkpoint,Copy到PrimaryAvatarNode,接着再回来处理事务日志。

AvatarDataNode介绍

AvatarDataNode基于Hadoop0.20中DataNode。AvatarDataNode需要发送block报告和block接受报告到两个AvatarNode。AvatarDataNode不使用VIP和AvatarNode连接。(HDFS客户端通过VIP连接AvatarNode)。另一个可选方案是,PrimaryAvatarNode转发blockreports到StandbyAvatarNode。没有采用可选方案是因为这种方法需要添加复杂代码到PrimaryAvatarNode,PrimaryAvatarNode需要对blockreports进行缓存和控制部分流

HadoopDataNode已经具备发送blockReceived信息到NameNode功能,我们扩展了这个功能使得发送这个消息到两个节点(PrimaryandStandbyAvatarNodes)。

这个方案在切换过程中对于客户端的影响

HDFS客户端读取一个文件时,它会首先取得所有的文件块以及copy的位置并缓存起来,这样的话这个方案不会影响HDFS读操作。

当HDFS客户端写文件时failover发生会有什么后果呢?

Hadoop0.20NameNode的策略是当文件写完成,关闭后才会将新分配的块记录到metadata。这表明当failover发生的时候,正在写文件会在failover成功之后抛出IOexception错误,这个使用了Map/Reduce的容错能力,框架会重做任何失败的任务。这中解决方案在HBase中也不回出问题,因为Hbase在一个事务完成之后要有sync/hflush操作。由于map/reduce框架和Hbase的策略,使得failover事件也不会影响HDFS的写操作。

其他的HA方案

大家说让我比较一下AvatarNodeHA实现和HadoopwithDRBDandLinuxHA.这两种方法都是需要主节点写事务日志到一个共享的硬件。不同点是,StandbyAvatarNode是一个热备而DRBD-LinuxHA是一种冷备份。AvatarNode对于5亿文件的failover时间是1分钟,但是DRBD-LinuxHA可能需要一个小时。AvatarNode可以热备的原因就是它封装了一个NameNode的实例并且这个实例会从DataNode接受信息,这使得metadata的状态是最新的

相关推荐