转自 http://www.linuxidc.com/Linux/2012-04/58182p3.htm
前言
保证HDFS高可用是Hadoop被推广以来很多技术人员一直关心的问题,通过搜索引擎搜索也可以得到很多的方案。恰逢HDFS Federation出炉,本文将一些涉及到有关NameNode、SecondaryNameNode、BackupNode的含义与区别,以及HDFS HA框架做一个总结。除此之外,文章的最后,将介绍Hadoop-0.23.0如何配置NameNode、SecondaryNameNode、以及BackupNode。
1、HDFS元数据服务器如何工作?
Namenode在第一次启动时刻之前,进行格式化,$bin/hdfs namenode -format -clusterid yourid 按照需求生成VERSION:例如我Hadoop0.23.0初探2中使用gb17作为namenode,在format之后会在dfs.hadoop.name.dir目录中生成如下的VERSION
$ cat /opt/jiangbing/hdfs23/current/VERSION
#Thu Dec 08 16:27:30 CST 2011
namespaceID=1787450988
clusterID=klose
cTime=0
storageType=NAME_NODE
blockpoolID=BP-950324238-10.10.102.17-1322483515854
layoutVersion=-38
可以看到比之前的Hadoop-0.21.0的HDFS中多了一个blockpoolID和clusteID,VERSION有点像NameNode的身份证。每次-format就代表NameNode出生了。
在-format同时,会生成fsimage_**和edits_**两个文件。使用$bin/hdfs namenode会按照正常的方式启动NameNode。
fsimage:元数据的snapshot
editsLog:元数据的操作
当NameNode启动时,会从镜像文件 fsimage 中读取HDFS的状态,并且把edits文件中记录的操作应用到fsimage,也就是合并到fsimage中去。合并后更新fsimage的HDFS状态,清空的edits文件来记录文件系统的变化。因此在NameNode启动过程中,namenode处于safe mode模式,只能提供读操作,不提供写操作,等启动完成会从safe mode模式退出。因此,NameNode在正常情况下不会合并edits到fsimage上,作checkpoint的。这会造成系统edits文件越来越大。这样当需要重启NameNode时,你会发现启动过程会非常长。
2、SecondaryNameNode不是NameNode热备
SNN主要是备份NN的文件信息,不备份数据块的信息。它从NN上获取fsimage和edits文件,将fsimage与edits日志合并成一个新的fsimage,再将新的fsimage上传给NN,这样使得 NN中的edits不会一直是递增的,可以使NN的重启过程变得轻松。
SNN的主要工作在 doCheckpoint()方法中,每隔一段时间会启动检查点一次,是由两个配置参数来控制的:
fs.checkpoint.period,指定连续两次检查点的最大时间间隔,默认值是1小时。
fs.checkpoint.size 定义了edits日志文件的最大值,一旦超过这个值会导致强制执行检查点(即使没到检查点的最大时间间隔)。默认值是 64MB。
3、BackupNode强调实时同步
这个结点的模式有点像mysql中的主从结点复制功能,NN可以实时的将日志传送给BN ,而SNN是每隔一段时间去NN下载fsimage和edits 文件,而BN是实时的得到操作日志,然后将操作合并到fsimage里。
在NN里提供了二个日志流接口: EditLogOutputStream 和 EditLogInputStream 。即当NN有日志时,不仅会写一份到本地edits的日志文件,同时会向BN的网络流中写一份,当流缓冲达到阀值时,将会写入到BN结点上, BN收到后就会进行合并操作,这样来完成低延迟的日志复制功能。
4、BN与SNN的区别
1)获取NN中元数据的方式不同。
NN会把fsimage和edits更新flush到BN的机器,实时性好。这样在NN宕机之后,BN拥有了基本一致的元数据。SNN是通过http server获取fsimage和edits的内容,因此,数据完成程度受到了fetch文件频率的影响。
2)对checkpoint结果的处理方式不同。
SNN会主动把checkpoint之后的fsimage发送给NN,而BN只在本地作checkpoint,存在本地的dfs.name.dir中,其实它就相当于一个NameNode的热备,只是DataNode还没有认识到它的存在,如果你是程序员的话,你应该知道怎么办。:-)
5、一些HDFS HA的方案
1)对于dfs.name.dir目录设置RAID。
2)设置多个dfs.name.dir目录,将其中的一个目录设置为其它节点通过NFS挂载到该机器的目录。这样会同时写两份同样的数据。这样绑定一个ZooKeeper来跟踪NameNode的状况,在主NameNode宕机之后,
StandbyNameNode切换成正常的NameNode,为了简单,standbyNameNode开始只需监听Zookeeper的事件即可,在出错之后,迅速正常启动一个NameNode。DataNode在链接失效之后,要从Zookeeper获得更新的NameNode的URL,这块需要一点编码。:-),如果一点都不动,我们就找不到工作了...下图是一个示意图。
3)另外是一些做法稍微复杂一些。请参阅:
http://www.cloudera.com/blog/2009/07/hadoop-ha-configuration/
http://hadoopblog.blogspot.com/2010/02/hadoop-namenode-high-availability.html
6、Hadoop-0.23.0 HDFS中SNN、BN的配置
1)SNN的配置,这个非常简单,修改所有机器下的conf/hdfs-site.xml文件:
${HDFS_CONF_DIR}/hdfs-site.xml
<configuration> <property> <name>dfs.namenode.name.dir</name> <value>file:///opt/jiangbing/hdfs23</value> </property> <property> <name>dfs.federation.nameservices</name> <value>ns1,ns2</value> </property> <property> <name>dfs.namenode.rpc-address.ns1</name> <value>gb17:9000</value> </property> <property> <name>dfs.namenode.http-address.ns1</name> <value>gb17:23001</value> </property> <property> <name>dfs.namenode.secondary.http-address.ns1</name> <value>gb17:23002</value> </property> <property> <name>dfs.namenode.rpc-address.ns2</name> <value>gb18:9000</value> </property> <property> <name>dfs.namenode.http-address.ns2</name> <value>gb18:23001</value> </property> <property> <name>dfs.namenode.secondary.http-address.ns2</name> <value>gb18:23002</value> </property> <property> <name>fs.checkpoint.period</name> <value>600</value> <description>The number of seconds between two periodic checkpoints. </description> </property><property> <name>fs.checkpoint.size</name> <value>67108864</value> <description>The size of the current edit log (in bytes) that triggers a periodic checkpoint even if the fs.checkpoint.period hasn‘t expired. </description></property> </configuration>
如果需要的话,还可以设置dfs.name.checkpoint.dir的路径,默认以hadoop.tmp.dir为目录建立对应的checkpoint目录。
其余配置与Hadoop0.23.0初探2阐述的内容相同,使用sbin/start-dfs.sh启动即可。
2)sbin/start-dfs.sh不会从配置文件中读取backupNode的信息,然后启动它。因此,在设置dfs的内容处,需要在一个节点单独的配置。请注意,设置backupNode时,它的配置文件conf/hdfs-site.xml有了一点差别,其实所有的节点的配置文件都设置成backupNode的节点的情况也没有问题,因为脚本不会独立地启动backupNode。
<configuration> <property> <name>dfs.namenode.name.dir</name> <value>file:///opt/jiangbing/hdfs23/backup</value> </property> <property> <name>dfs.federation.nameservice.id</name> <value>ns1</value> </property> <property> <name>dfs.namenode.backup.address.ns1</name> <value>gb22:50100</value> <description> The backup node server address and port. If the port is 0 then the server will start on a free port. </description> </property> <property> <name>dfs.namenode.backup.http-address.ns1</name> <value>gb22:50105</value> <description> The backup node http server address and port. If the port is 0 then the server will start on a free port. </description> </property> <property> <name>dfs.federation.nameservices</name> <value>ns1,ns2</value> </property> <property> <name>dfs.namenode.rpc-address.ns1</name> <value>gb17:9000</value> </property> <property> <name>dfs.namenode.http-address.ns1</name> <value>gb17:23001</value> </property> <property> <name>dfs.namenode.secondary.http-address.ns1</name> <value>gb18:23002</value> </property> <property> <name>dfs.namenode.rpc-address.ns2</name> <value>gb18:9000</value> </property> <property> <name>dfs.namenode.http-address.ns2</name> <value>gb18:23001</value> </property> <property> <name>fs.checkpoint.period</name> <value>60</value> <description>The number of seconds between two periodic checkpoints.</description> </property> <property> <name>fs.checkpoint.size</name> <value>67108864</value> <description>The size of the current edit log (in bytes) that triggers a periodic checkpoint even if the fs.checkpoint.period hasn‘t expired. </description> </property> <property> <name>dfs.namenode.secondary.http-address.ns2</name> <value>gb17:23002</value></property></configuration>
这里设置gb22作为ns1的namenode的backupNode,注意这里backupNode与NameNode共有NameNode.dir的目录,这也可以认为BackupNode就是NameNode的孪生兄弟,这是这个兄弟不负责外面的哪些事儿(DataNode的rpc链接)。
在gb22上启动backupNode,$bin/hdfs namenode -backup
通过$bin/hadoop fs -ls hdfs://gb22:50100 可以获得与$bin/hadoop fs -ls hdfs://gb17:9000
一样的内容,元数据内容在gb17,gb22完成了。这样在gb17宕机之后,只需停掉gb22 backupNode,重新配置一下ns1的位置,这样服务就可以继续了。其实这是一个不用任何代码开发的方案。但是需要暂停一下服务。对于这样的HA,你们可以接受吗?:-)