您的位置:首页 > 编程语言

Hadoop目前的HA(High Availability)机制分析和源代码研究

2013-02-26 20:58 597 查看
Hadoop的设计初衷是服务于off-line的数据存储和处理应用。随着这个产品的不断成熟和发展,对于支持on-line应用的需求越来越强烈。例如HBase已经被Facebook和淘宝用到了在线存储应用中。所以Hadoop的on-line化也是一个趋势。目前制约Hadoop作为on-line存储和处理的瓶颈主要是系统的availability。衡量一个分布式系统的主要指标有:reliability,
availability & scalability。Hadoop可以做到横向扩展,所以scalability非常好;而用户存在Hadoop里的数据几乎不会丢失,所以reliability也是非常不错的;目前的主要问题在availability,也就是用户向HDFS集群请求数据的时候集群是否能够保证100%提供服务,目前的主要问题体现在HDFS的SPOF(single point of failure),整个HDFS集群的启动/重启时间非常长,配置参数无法动态更改等。这些方面都是apache社区目前工作的重点,本文主要讨论HDFS
NameNode的SPOF问题相关的HA机制。
Hadoop目前的trunk中的代码已经merge了原来的ha-branch,所以现在的trunk中的代码已经实现了基本的HA机制的功能。Hadoop PMC的人表示将会在后面的版本中发布这个功能。下面这张图是目前的HDFS HA的实现逻辑。



Right now the HA branch supports HOT-Failover, except that it is manual failover. We are now moving into a phase to implement automatic failover.
Significant enhancements were completed to make HOT Failover work:

- Configuration changes for HA

- Notion of active and standby states were added to the Namenode

- Client-side redirection

- Standby processing editlogs form Active

- Dual block reports to Active and Standby.
这是Hadoop mailing list中关于目前HA现状的阐述。下面首先简单介绍下这5个方面是怎么实现的,后面从源代码的角度分析具体的实现细节。
(1) Configuration changes for HA
在配置文件中会增加关于HA配置的参数,具体参数配置可以参考CDH4
Beta 2 High Availability Guide,这里介绍一些比较重要的参数。
例如dfs.ha.namenodes.[nameservice ID]这个参数表示在[nameservice ID]这个nameservice下的两台NameNode(分别作为Active和Standby模式运行)的主机名。然后针对每一台NN配置其对应的dfs.namenode.rpc-address.[nameservice
ID].[name node ID]用来标示每一台NN。
由于目前的两台主机之间的HA机制是通过一个共享存储来存放editlog来实现的。所以需要配置参数dfs.namenode.shared.edits.dir表示共享存储的位置,一般是通过NFS挂载的形式,所以其实这个参数的值就是一个本地文件系统中的目录。
dfs.client.failover.proxy.provider.[nameservice ID]这个参数指定具体的failover proxy provider类,也就是在client端发现原来Active的NameNode变成了Standby模式时(在client发送RPC请求时返回了StandbyException时),该如何去连接当前Active的NameNode。目前的Hadoop里只有一个具体实现策略ConfiguredFailoverProxyProvider,实现方法就是如果client
failover时,下次把RPC发送给另外一个NameNode的proxy。
另外就是dfs.ha.fencing.methods参数,指定在Active NameNode切换到Standby模式时,确保切换成功或者进程被杀死。

(2) Notion of active and standby states were added to the Namenode
有两种模式的NameNode,分别是Active和Standby模式。Active模式的NameNode接受client的RPC请求并处理,同时写自己的Editlog和共享存储上的Editlog,接收DataNode的Block report, block location updates和heartbeat;Standby模式的NameNode同样会接到来自DataNode的Block
report, block location updates和heartbeat,同时会从共享存储的Editlog上读取并执行这些log操作,使得自己的NameNode中的元数据(Namespcae information + Block locations map)都是和Active NameNode中的元数据是同步的。所以说Standby模式的NameNode是一个热备(Hot Standby NameNode),一旦切换成Active模式,马上就可以提供NameNode服务。
(3) Client-side redirection
Client的通过RPC的Proxy与NameNode交互。在client端会有两个代理同时存在,分别代表与Active和Standby的NameNode的连接。由于Client端有Retry机制,当与Active NameNode正常通信的client proxy收到RPC返回的StandbyException时,说明这个Active
NameNode已经变成了Standby模式,所以触发dfs.client.failover.proxy.provider.[nameservice ID]这个参数指定的类来做failover,目前唯一的实现是ConfiguredFailoverProxyProvider,实现方法就是下次开始把RPC发向另外一个NameNode。此后的RPC都是发往另外一个NameNode,也就是NameNode发生了主从切换。

(4) Standby processing editlogs form Active
开启Standby模式后,Standby NameNode会通过EditLogTailerThread从共享存储中读取Active NameNode写到那里的Editlog,然后执行操作,从而保持自己的元数据是最新的,所以说是热备。
(5)Dual block reports to Active and Standby.
DataNode的Block report, block location updates和heartbeat等RPC操作会发向两个NameNode,从而使得两个NameNode的Block locations map都是最新的,这样可以做到切换主从后原来的从(新的主)不再需要block
report的时间。
可以看出client与NameNode之间的RPC是只向一个NameNode发送的(收到StandbyException后才会重试另外一个);而DataNode与NameNode之间的RPC在任何时候都是同时向两个NameNode发送的。
下一篇文章将从代码的角度来分析HDFS的HA机制。http://www.linuxidc.com/Linux/2012-09/70414p2.htm
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

前一篇文章分析了Hadoop High Availability的思路和主要功能,这篇文章中从代码的角度分析具体的实现。
(1)NameNode启动流程
对于HDFS HA机制来说,NameNode是核心,NameNode有Active和Standby两种状态。在NameNode的构造函数中,读取配置文件,如果配置文件配置了开启HA,那么NameNode进入STANDBY_STATE状态;反之则进入ACTIVE_STATE状态。

创建HA上下文,NameNodeHAContext类包含了NameNode的Active和Standby模式变换相关操作的函数实现。

然后就是初始化操作,包括配置参数,RPC server,metrics,加载Namespace,然后进入当前的haContext

(2)管理员执行HA管理命令流程
当两个NameNode都已经启动并进入Standby模式之后,就可以通过bin/hdfs脚本执行HDFS管理功能,执行如下命令:

就会调用DFSHAAdmin.java这个类来执行用户指定的功能,例如:

以-failover为例,就会调用HAAdmin.java类中的failover方法。

在这个函数中首先解析参数,然后会生成两个HAServiceTarget,分别表示发生主从切换的两个NameNode。由于这个DFSHAAdmin命令可以在任何一台可以连接到集群中的机器上运行,所以HAServiceTarget实际上是发生主从切换的两个NameNode的代理的封装。这个代理与两个NameNode通信的RPC协议时HAServiceProtocol。目前的Hadoop的RPC已经默认了Protocol
Buffer作为RPC的实现。
然后生成FailoverController对象,这个类就是用于控制主从切换的。然后执行这个类中的failover方法。

(3)NameNode端的HA状态切换执行的操作代码
以上是DFSHAAdmin的操作,那么当它把对应的RPC命令发送到NameNode时,NameNode端的逻辑是怎么处理的呢?新的机遇Protocol Buffer实现的RPC请求在NameNode端会调用NameNodeRpcServer.java类中的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: