Skip to content

3. 方案比较

WU Wei edited this page Oct 9, 2018 · 4 revisions

近年来,已经有越来越多的企业参与到Hadoop社区的发展中来,它们对HDFS的改造提出了不同的方案,有的是基于社区版HDFS源码进行改造,比如Cloudera的CDH版本和Facebook的AvatarNode,也有的是参照HDFS重写一套分布式文件系统,比如百度的HDFS2和腾讯的XFS,当然社区也推出了新的版本Hadoop 0.23。总的来看,与ADFS类似,Hadoop 0.23的Federation HDFS、百度的HDFS2和腾讯的XFS做了较为全面的改造,而Cloudera CDH4 beta1、Facebook的AvatarNode以及Hadoop 0.23 HA是为了解决特定问题——Namenode单点故障而做的。

首先,我们来介绍Hadoop 0.23中Federation HDFS的架构,如图表 5所示。从逻辑上看,Federation HDFS中命名空间和文件块管理还是由Namenode负责,Datanode负责文件块物理存储和访问,但是Federation HDFS允许在一个集群中运行多个Namenode,每个Namenode负责一个命名空间(可以是非HDFS的命名空间),每个命名空间拥有至少一个逻辑的BlockPool,命名空间和它所拥有的BlockPool统称为一个Namespace Volume。虽然这些命名空间从物理上看是共享集群中的Datanode,但是在每个Datanode上还是对每个命名空间的BlockPool进行了隔离的,而且Datanode需要向每个相关的Namenode进行汇报。采用Federation HDFS架构,集群失去了统一的命名空间管理,换来的是多个命名空间可自主升级的灵活性和降低集群整体不可用的风险。

Federation HDFS

图表 5 Federation HDFS

百度的HDFS2架构如图表 6所示,从上到下分大致划分为两个层次:Namespace Federation(原Namenode)和Object Manager Layer(原Datanode)。在Namespace Federation层,HDFS2不再包括文件属性和块管理功能,实现了轻量级命名空间管理,和社区版Federation HDFS类似,Namespace Federation也支持多种命名空间,包括层次化的和平坦的;在Object Management Layer中,它不仅负责块的物理存储和访问,还整合了文件属性和块管理功能,每个Datanode对该功能进行了垂直切分,各自管理一部分。客户端访问HDFS2时,通过Namespace找到该文件名对应的Datanode和文件标识,并根据这些信息访问指定的Datanode获取文件属性和它的块信息。但是,HDFS2现有版本还没有实现高可用解决方案。

HDFS2架构

图表 6 HDFS2架构

腾讯的XFS是由搜索部门采用C++开发的分布式文件系统,它也实现了元数据信息的分离,并且通过SDK包兼容HDFS,即让HDFS运行在XFS上。如图表 7所示,XFS中命名空间由Master进行管理,XFS的Master通过主从热备实现了高可用解决方案,由Zookeeper实现监控、选举和切换;文件标识和块管理由独立的MetaServer进行管理,它记录了文件属性、长度以及该文件拥有的块等信息;与Datanode类似,块物理存储和访问由NodeServer负责。客户端在访问XFS时,先通过文件名在Master上获取MetaServer标识和文件标识等信息,然后在指定的MetaServer上获得需要请求的文件信息或者块信息,如果要访问文件的块,则通过NodeServer获取块内容。

XFS架构

图表 7 XFS架构

与ADFS类似,上述各个方案和实现都是对现有HDFS进行全面改造的代表,总的来说,新增功能到目前为止主要体现在几个方面:1. 是否支持多命名空间,2. 是否支持高可用;3. 是否支持快速重启(元数据持久化);4.是否支持在线升级。图表 8对这几个方案进行了横向的比较:

ADFS与业界方案的比较

*1社区已提出高可用解决方案,代码已合并到主干中,但是并没有正式发布可用版本

*2 计划支持中

图表 8 ADFS与业界方案的比较

需要声明的是,这里的比较并不是想说明哪个方案好或者不好,每个方案都是跟它背后所需要达到的需求紧密联系在一起的,而且我们也是基于这些方案公开发布的资料来进行分析的,其时效性和正确性都有待商榷。

接下来,我们来分析一下业界普遍关注的HDFS Namenode高可用解决方案,这些方案的提出无非都是想解决Namenode设计上的单点故障。这些方案按照部署类型可划分为主从(Master-Slave)和集群(Cluster),其中主从根据状态的一致程度又细分为冷备、温备和热备,按照切换方式可划分为人工切换和自动切换,按照数据同步方式可划分为共享存储和复写。 图表 9列举了目前Hadoop HA方案,接下来我们对各种方案进行详细的介绍。

各种HA方案比较

图表 9 各种HA方案比较

由于ADFS将Namenode做了无状态处理,因此有两个模块需要做到高可用性——Stateless Namenode和State Manager。对于Stateless Namenode而言,它相当于业务逻辑处理的代理,通过集群方式部署能够很好地实现集群的水平扩展,如果某个Stateless Namenode发生故障,与它连接的Client和Datanode会检测到IOException异常并根据预先设定的策略重新选择集群中其他Stateless Namenode,切换时间在毫秒~秒级。State Manager通过自己的分布式框架和ZooKeeper实现了主从热备,Master接收Stateless Namenode的RPC请求,采用复写的方式将数据持久化到自己的innodb和Slave的innodb中。如果Slave出现了异常,Master会将Slave设置为NEED_RESTORE状态,Slave恢复以后Master会将对其进行全量备份,从而保证两者状态同步。

Facebook的AvatarNode是业界较早的Namenode HA方案,它是基于HDFS 0.20实现的,如图表 10所示。由于采用的是人工切换,所以实现相对简单。AvatarNode对Namenode进行了封装,处于工作状态的叫Primary Avatar,处于热备状态的叫Standby Avatar(封装了Namenode和SecondaryNameNode),两者通过NFS共享EditLog所在目录。在工作状态下,Primary Avatar中的Namenode实例接收Client的请求并进行处理,Datanode会向Primary和Standby两个同时发送blockReport和心跳,Standby Avatar不断地从共享的EditLog中持续写入的新事务,并推送给它的Namenode实例,此时Standby Avatar内部的Namenode处于安全模式状态,不对外提供服务,但是状态与Primary Avatar中的保持一致。一旦Primary发生故障,管理员进行Failover切换:首先将原来的Primary进程杀死(避免了“Split Brain”和“IO Fencing”问题),然后将原来的Standby设置为Primary,新的Primary会保证回放完成所有的EditLog事务,然后退出安全模式,对外接收服务请求。为了实现对客户端透明,AvatarNode主从采用相同的虚拟IP,切换时将新的Primary设置为该虚拟IP即可。整个流程可在秒~分钟级别完成。

Facebook的AvatarNode

图表 10 Facebook的AvatarNode

BackupNode是社区版Hadoop 0.21提供的一种高可用方案。它不仅实现了SecondaryNameNode的功能,还是实现了复写功能,即同时向Active Namenode和Standby Namenode写入EditLog,这样也避免了共享存储会遇到的“IO Fencing”问题。如果Standby意外宕机,Active Namenode会把EditLog备份到其他的地方。但是,BackupNode只能算主从温备,因为Datanode只会向Active Namenode汇报和保持心跳,一旦Active Namenode发生故障,需要人工切换到BackupNode上,并且需要在BackupNode上把BlocksMap状态完全构建起来,这样的切换时间在分钟~小时级别。

BackupNode架构

图表 11 BackupNode架构

Cloudera于2012年3月发布了CDH4B1(beta)版本,它的实现思路跟AvatarNode类似,目前也只支持人工切换,所不同的是,为了保证集群中只有一个Active Namenode,该版本显式的提供了Fencing机制。在进行人工切换时,它会先通过常规方式将Active Namenode关闭,如果失败便使用Fencing配置指定的方式强行关闭该进程,成功后才设定新的Active Namenode,否则返回失败信息。在CDH4B1为Fencing机制提供了两种方法:sshfence和shell,sshfence实现了通过SSH方式登录到目标机器上杀死Active Namenode进程,而shell方式可以调用管理员自己开发的脚本来实现Fencing。

Heartbeat+DRBD方式是通过Linux系统提供的工具来实现Hadoop Namenode的高可用性。该方案通过Heartbeat心跳监控,DRBD实现共享存储,每个服务器都需要配备双网卡,其中的一个网卡用于心跳网络。Client通过虚拟IP与Active Namenode进行通信,一旦系统检测到Active Namenode失去心跳(宕机或进程崩溃),则进行Failover切换,切换以后新的Active Namenode获得了原来Active Namenode的虚拟IP,来接收Client的服务请求。不过,新的Active Namenode需要重新恢复内存状态,切换时间较长。

在社区版HDFS的路线演进中,HA Branch是一个很重要的分支,目前HA Branch已经跟Hadoop 0.23的主干进行了合并。出于灵活性考虑,社区提出了多种高可用性方案,现在实现的是通过共享存储和Zookeeper来实现主从热备,如图表 12所示,不过通过BookKeeper来实现复写的方案被认为是长期看好的,当然这也需要BookKeeper团队的配合。BookKeeper是一个高性能的可靠的预写入日志系统,通过它可以实现EditLog在Active Namenode和Standby Namenode上的复写,从而取代它们之间的共享存储。社区版的方案推荐采用独立的FailoverController进程和Zookeeper来监控Active Namenode和Standby Namenode的状态和主从选举,也可以采用Linux HA和其他的Quorum服务来实现。

社区HDFS NN HA方案之一

图表 12 社区HDFS NN HA方案之一:通过共享存储和Zookeeper实现