翻译自Facebook Hadoop架构师(Dhruba Borthakur)的一篇文章
[b]我们遇到的情况[/b]
Hadoop NameNode存在单点问题。这个问题会影响分布式平台24*7运行。先说说我们的情况吧。
我们的团队负责管理一个1200节点的集群(总大小12PB),目前是运行版本为Hadoop 0.20,transaction logs写入一个共享的NFS filer(注:NetApp NFS Filer)。
经常遇到需要中断服务的问题是给hadoop打补丁。 DataNode打补丁比较简单,不会造成服务中断,每次对其中的一部分DataNode部署新的代码、重启,就OK了。 问题是需要给NameNode部署新的代码时,NodeNode重启需要花费1个小时,这期间所有的Hadoop服务都不能运行。这是不可忍受的,所以我们就想着把NameNode有个备份。我们的解决方案可以保证在1分钟内切换完成。
当时HDFS BackupNode在Hadoop 0.20中还不能用,升级Hadoop 0.20也不是一个很好的选择。这个升级部署之前,需要花费大量时间做测试。
经过仔细的分析现状和可能的解决方案。我们设计了一个简单的解决方案:
a. 目前我们有两个NameNode 一个Primary NameNode和一个Standby Nodenode,我们不用担心split-brain-scenario(可以想想精神分裂) 和 IO-fencing(这个名词不太了解)。OP能保证Primary NameNode完全down后,Standby NameNode才能被切换。
b. 我们不想修改NameNode的任何代码,只想基于HDFS构建一个软件层来保证HA。我们需要一个deamon来切换Primary和Standby.
词语“Avatar”的意思是实体的变体,所以借用这个词,把NameNode的wrapper称为AvatarNode。AvatarNode完全继承NameNode,所以NameNode的优点它都完全具备。
[b]AvatarNode介绍[/b]
AvatarNode完全封装NameNode。AvatarNode运行有两种模式Primary Avatar或者standby Avatar. 如果启动运行在Primary Avatar模式,那么它就和当前NameNode功能完全一样,其实运行的代码就是NameNode的代码。运行Primary Avatar模式的AvatarNode机器,保存HDFS事务日志(editlog)到一个共享的NFS。在另外一台机器上,启动AvatarNode的另一个实例,运行在Standby Avatar模式。
Standby AvatarNode封装了NameNode和SecondaryNameNode。Standby AvatarNode持续的从共享的NFS filer中读取HDFS editlog,并持续的把这些事务推送到Standby AvatarNode中NameNode实例。Standby AvatarNode中的NameNode运行在SafeMode。原因是不能让它负责NameNode的工作,但是必须保持和NameNode同步的NameNode Metadata信息。
HDFS客户端访问NameNode通过一个虚拟IP(Virtual IP Address,注:这块其实可以用zookeeper来取代).当发生故障需要快速切换时,管理员会在机器M1上杀掉Primary AvatarNode进程,然后在机器M2上设置Standby AvatarNode作为Primary Avatar。Standby AvatarNode会保证把所有提交的事务都处理完,因为Standby AvatarNode会重新打开edit log,并处理完文件中所有的事务.这个假设是基于NFS-v3支持close-to-open cache coherency semantics。Standby AvatarNode把所有NFS filer上的事务处理完之后,退出SafeMode模式。管理员将M2的VIP换为M1,这样所有的HDFS客户端的请求会提交到M2的实例上。这个failover一般情况只需要几秒钟。
另外根本不需要单独一台SecondaryNameNode。 AvatarNode在Standby avatar模式时,可以履行SecondaryNameNode的职责。Standby AvatarNode持续的处理从Primary Avantar来的所有的事务,在处理事务日志的空闲间隙会唤醒SecondaryNameNode进程,创建并上传一个新的checkpoint,Copy到Primary AvatarNode, 接着再回来处理事务日志。
[b]
AvatarDataNode介绍[/b]
AvatarDataNode基于Hadoop 0.20中DataNode。AvatarDataNode需要发送block报告和block接受报告到两个AvatarNode。AvatarDataNode不使用VIP和AvatarNode连接。(HDFS客户端通过VIP连接AvatarNode)。另一个可选方 案是,Primary AvatarNode转发block reports到Standby AvatarNode。没有采用可选方案是因为这种方法需要添加复杂代码到Primary AvatarNode,Primary AvatarNode需要对block reports进行缓存和控制部分流
Hadoop DataNode已经具备发送blockReceived信息到NameNode功能,我们扩展了这个功能使得发送这个消息到两个节点(Primary and Standby AvatarNodes)。
[b]这个方案在切换过程中对于客户端的影响[/b]
HDFS客户端读取一个文件时,它会首先取得所有的文件块以及copy的位置并缓存起来,这样的话这个方案不会影响HDFS读操作。
当HDFS客户端写文件时failover发生会有什么后果呢?
Hadoop 0.20 NameNode的策略是当文件写完成,关闭后才会将新分配的块记录到metadata。这表明当failover发生的时候,正在写文件会在failover成功之后抛出IO exception错误,这个使用了Map/Reduce的容错能力,框架会重做任何失败的任务。这中解决方案在HBase中也不回出问题,因为Hbase在一个事务完成之后要有sync/hflush操作。由于map/reduce框架和Hbase的策略,使得failover事件也不会影响HDFS的写操作。
[b]其他的HA方案[/b]
大家说让我比较一下AvatarNode HA实现和Hadoop with DRBD and Linux HA.这两种方法都是需要主节点写事务日志到一个共享的硬件。不同点是,Standby AvatarNode是一个热备而DRBD-LinuxHA是一种冷备份。AvatarNode对于5亿文件的failover时间是1分钟,但是DRBD-LinuxHA可能需要一个小时。AvatarNode可以热备的原因就是它封装了一个NameNode的实例并且这个实例会从DataNode接受信息,这使得metadata的状态是最新的。
代码参见HDFS-976. (前提条件HDFS-966)
注:
1. Blog地址: [url]http://hadoopblog.blogspot.com/2010/02/hadoop-namenode-high-availability.html[/url]
2. 最新代码参见:
[url]https://github.com/facebook/hadoop-20-warehouse/tree/master/src/contrib/highavailability[/url]
3. Dhruba回答的部分问题
Dhruba关于NameNode启动过程所需要时间的一个参考:
our clyster has 2000 nodes. The fsimage is about 12 GB(70 million files and directories). The cluster has a total of around 90 milliosn blocks. It takes about 6 minutes to read and process the fsimage file. Then it takes another 35 minutes to process block reports from all datanodes.
AvatarNode和ZooKeeper整合(解决VIP问题)
We are in the process of open-sourcing the AvatarNode integration with zookeeper. We will post this patch as part of HDFS-976 very soon.
有关NFS延迟
I agree that NFS is not the fastest way to read/access that transaction log. However, it is not really NFS but rather the NFS implementation that could be an issue. We use a NetApp NFS Filer and the filer's uptime and latencies are hard to beat! Also, we depend on NFS close-to-open cache coherency semantics: http://nfs.sourceforge.net/