从这张图中,可以知道,在NameNode启动的时候,会从fsimage中读取Hdfs的状态,
同时会合并fsimage与edits获得完整的元数据信息,并将新的Hdfs状态写入fsimage。
并使用一个空的edits文件开始正常操作。
但是在产品化的集群(如Ambari或ClouderManager)中NameNode是很少重启的,在我的工作场景中,重启基本就是挂了。
这也意味着当NameNode运行了很长时间后,edits文件会变得很大。
在这种情况下就会两个问题:
edits文件随着操作增加会变的很大,怎么去管理这个文件是一个又是一个问题。
NameNode的重启会花费很长时间,因为经过长时间运行,Hdfs会有很多改动(edits)要合并到fsimage文件上。
既然明白了痛点所在,那自然是需要对症下药,核心问题就是edits会越来越大,导致重启操作时间变长,只要解决这个问题就完事了。
我们只需要保证我们fsimage是最新的,而不是每次启动的时候才合并出完整的fsimage就可以了,也就是更新快照。
这就是是我们需要介绍的Secondary NameNode的工作。
Secondary NameNode 用于帮助NameNode管理元数据,从而使得NameNode可以快速、高效的工作。
简单的说Secondary NameNode的工作就是定期合并fsimage和edits日志,将edits日志文件大小控制在一个限度下。
因为内存需求和NameNode在一个数量级上,所以通常secondary NameNode 和 NameNode 运行在不同的机器上。
下面看看这个过程是怎么发生的
ps:图中有个虚线,就是在传输edits的时候会不会传输fsimage?这个在最后面会有相关说明
这些步骤简单的总结就是:
在Secondary NameNode端:
Secondary NameNode定期到NameNode更新edits
将更新到的edits与自身的fsimage或重新下载的fsimage合并获得完整的fsiamge.ckpt
将fsimage.ckpt发送给NameNode
在NameNode端:
在Secondary NameNode发出合并信号的时候,将更新日志写到一个新的new.edits中,停用旧的edits。
在Secondary NameNode将新的fsimage.ckpt发过来后,将旧的fsimage用新的fsimage.ckpt替换,同时将久的edits用new.edits替换。
那么合并的时机是什么?主要有两个参数可以配置:
fs.checkpoint.period:指定连续两次检查点的最大时间间隔, 默认值是1小时。
fs.checkpoint.size:定义了edits日志文件的最大值,一旦超过这个值会导致强制执行检查点(即使没到检查点的最大时间间隔)。默认值是64MB。
所以,Secondary NameNode 并不是第二个NameNode的意思,只是NameNode的一个助手。更准确的理解是它仅仅是NameNode的一个检查点(CheckPoint)。
同时,我们所说的HA,也就是高可用,也不是只Secondary NameNode,详细的会有专门的文章介绍。
有个坑在Secondary NameNode 执行合并的时候,有一个步骤3,通过http Get的方式从NameNode获取edits文件。
在这一步骤中,到底需不需要把NameNode中的fsimage也获取过来,目前我看了挺多资料,挺矛盾的。
在Hadoop权威指南中说明如下:
从这里看,应该是同是获得了fsimage与edits。
但是,在官网中有一个描述:
The secondary NameNode stores the latest checkpoint in a directory which is structured the same way as the primary NameNode’s directory.
So that the check pointed image is always ready to be read by the primary NameNode if necessary.
Secondary NameNode将最新的检查点存储在与主NameNode目录结构相同的目录中。
所以在NameNode需要的时候,会去读取检查点的镜像image。
并且在Secondary NameNode in Hadoop中关于Secondary NameNode有这样的一个描述:
NameNode当前目录的截图如下: