NameNode
NameNode是HDFS(Hadoop分布式文件系统)的元数据管理进程,是整个HDFS的Master节点,管理HDFS命名空间、数据块映射的节点、副本策略等等。而这些数据是已文件的形式存在磁盘上的,他们分别是:fsimage和editslog。
-
fsimage:镜像,namenode元数据文件,存在磁盘;是NameNode内存元数据对应磁盘上的映射。
-
editslog:文件操作日志,也是存在磁盘,只有追加操作,效率很高。
fsImage 文件和 editslog 文件是通过 事务id(txid) 来互相关联的。在非HA集群部署情况下,这两个数据文件保存在dfs.namenode.name.dir设置的路径下;如果是HA集群的话,editslog由QuorumJournalNode进行管理,editslog文件保存在参数dfs.journalnode.edits.dir设置的路径下。
那么NameNode是如何使用这两个文件的呢?接下来我们从NameNode启动开始聊。
NameNode启动过程
当启动/重启HDFS时,NameNode会将editslog合并到fsimage中,并将其加载到内存里。
NameNode加载元数据是按fsimage_txid中“txid”最大的文件,和edits_inprogress_txid中包含inprogress的文件进行合并。inprogress代表editslog文件还未合并到fsimage中。
由于NameNode需要加载完元数据才能对外提供服务,而生产环境不可能去频繁的重启HDFS,如果editslog文件太大,就会导致合并需要很久的时间,也就是说NameNode启动需要很久的时间。那HDFS如何解决这个问题呢?下面我们看看HDFS如何利用SecondaryNameNode来解决这个问题。
SecondaryNameNode
刚开始学习HDFSS的朋友看到SecondaryNameNode很容易误解,误以为她是NameNode的一个热备、一个从节点。实际上并不是。
SecondaryNameNode是NameNode的一个副手,它可以根据用户的配置(dfs.namenode.checkpoint.preiod
(默认值是3600,即1小时)和dfs.namenode.checkpoint.txns
(默认值是1000000,即100完条事务)),定期的执行Checkpoint,帮NameNode合并元数据快照fsimage。
定期将fsimage和editslog进行合并,合并成最新的fsimage,一旦合并最新的fsimage,就立即上传给NameNode进行更新。
定期的合并编辑日志(editslog)和镜像文件(fsimage),提供最新的fsimage给NameNode。
在生产环境中hadoop集群是长期运行的,editslog会不断的增大,如果此时突然故障重启,将editslog信息更新至fsimage中,将会非常耗时,此时就需要SecondaryNameNode在系统运行过程中不断的将editslog信息更新至fsimage。
SecondaryNameNode更新fsimage的步骤如下:
-
SecondaryNameNode根据用户的配置(见文末附录)定期检查NameNode中的editslog。当检查到它满足checkpoint条件的时候,NameNode会生成一个新的editslog,同时停止当前editslog文件的操作,由新的editslog来接收新的请求。
-
SecondaryNameNode通过HTTP的方式,将editslog和fsimage文件复制到SecondaryNameNode所在节点机器。
-
SecondaryNameNode在本节点机器上将fsimage载入内存,将editslog里的事务合并入fsimage,并生成新的快照文件fsimage.ckpt_txid。
-
SecondaryNameNode向NameNode发送请求,将最新的快照文件fsimage.ckpt_txid发送给NameNode。
-
NameNode接收到新的快照文件后,经过一系列的检查确认后,将其重命名为fsimage_txid,即为最新的快照文件。并清除旧的editlog文件,将其更新为新的editlog文件。
所以NameNode收到读写请求的时候,只需修改内存中的元数据和Editslog文件。
这里思考一个问题,SecondaryNameNode并不是生产环境使用的进程,在生成环境中部署的是HA高可用模式,高可用模式下并不运行SecondaryNameNode,在这种情况下HDFS如何进行editslog和fsimage的合并呢?继续聊!
HA模式下合并editslog和fsimage
不废话,先说结论:HA模式下是通过Standby NameNode进程合并editslog和fsimage。
HA模式下,为了实现高可用,Standby NameNode节点也会保留一份备份的fsimage;Standby NameNode和Active NameNode都拥有最新的fsimage和editslog文件。
editslog文件会同时写入多个JournalNode节点的dfs.journalnode.edits.dir
路径下。当Active NameNode执行任何有关命名空间的修改,它需要将editslog持久化到一半以上的JournalNode上。一旦Active NameNode出现故障,Standby NameNode将会保证从JournalNode中读出了全部的editslog,然后切换为Active状态。
通常情况下Active NameNode和Standby NameNode节点上也同时部署为JournalNode节点,这两个节点上的editslog和fsimage始终保持最新,在failover时可以进行切换。
具体步骤如下:
-
客户端对NameNode的请求操作,editslog将会写入到JournalNode节点元数据目录下。
-
Standby NameNode根据配置进行判断,是否到达checkpoint条件(比如:是否距离上次合并过了1小时,或者事务条数是否达到100万条)。当达到checkpoint条件后,会生成一个新的editslog,同时停止当前editslog文件的操作,由新的editslog来接收新的请求。
-
Standby NameNode会获取JournalNode集群中的editslog文件和本地fsImage文件合并生成一个文件fsimage.ckpt_txid(此时的txid是与合并的editslog_txid的txid值相同),并生成一个MD5文件。
-
Standby NameNode向Active NameNode发起HTTP请求,通知fsimage已经合并成功,是否进行获取。(请求信息包含:Standbynamenode的地址以及新fsimage的txid)。Active NameNode获得请求后,会向Standby NameNode发起一个HTTP请求,获取新的fsimage,保存为“.ckpt_txid”后缀的文件(如:fsimage.ckpt_txid),并生成一个MD5文件。
-
将这个MD5文件与Standby NameNode的MD5文件进行比较,确保获取到正确的fsimage文件后,将fsimage.ckpt_txid文件改名为fsimage_txit,即为最新的fsimage文件。并将旧的fsimage删掉,同时清除旧的editslog。
附录
checkpoint配置参考:hdfs-site.xml(以下为默认配置)
# checkpoint间隔时间 单位:秒
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
<description>The number of seconds between two periodic checkpoints.
</description>
</property>
# editslog事务数量
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>The Secondary NameNode or CheckpointNode will create a checkpoint
of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless
of whether 'dfs.namenode.checkpoint.period' has expired.
</description>
</property>
# checkpoint检查时间间隔 单位:秒
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
<description></description>
</property>
总结,本篇文章我们把NameNode、SecondaryNameNode和HA模式下Active NameNode、Standby NameNode的Checkpoint机制介绍了一下。后续还有更多精彩篇章,欢迎大家持续关注!