date: 2020-11-17title: Hadoop之Fsimage和Edits解析 #标题
tags: hadoop #标签
categories: Hadoop # 分类
在hadoop中,我们知道secondary namenode是来协助namenode干活的,但具体是干什么活的,可能还不知道,其实和两个词有关:Fsimage和Edits。
Fsimage和Edits的概念
首先我们得知道为什么会有fsimage和edits这两个东西,主要原因是Namenode中的元数据是存储在Namenode节点的内存中,因为经常需要进行随机访问,还有响应客户的请求,必然效率过低,因此,元数据需要放在内存中,但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了,因此产生了在磁盘中备份元数据的FsImage——文件系统镜像。
这样又会带来新的问题,当在内存中的元数据更新时,如同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦NameNode节点断电,就会产生数据丢失。因此,引入Edits文件(最进行之操作,效率较高),每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。
但是,如果长时间添加数据到Edits中,会导致该文件过大,效率降低,而且一旦断电,恢复元数据需要的时间很长,因此,需要定期进行FSImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低,因此,引入一个新的节点SecondaryNameNode,专用于FsImage和Edits的合并。
具体工作流程如下(自行理解吧):
NameNode被格式化后,将在${HADOOP_HOME}/data/tmp/dfs/name/current
目录下产生如下文件:
- fsimage_0000000000000000000
- fsimage_0000000000000000000.md5
- seen_txid
- VERSION
当secondarnamenode进行过一次合并后,secondarnamenode上也会有部分fsimage和edits文件,如下:
Fsimage文件
HDFS文件系统元数据的一个永久性检查点,其中包含HDFS文件系统的所有目录和文件idnode的序列化信息。
Edits文件
保存了HDFS文件系统的所有根棍操作的路径,文件系统客户端执行的所有写操作首先会被记录到Edits文件中。
seen_txid文件
保存的是一个数据,就是当前正在写入的edits文件末尾的数字,如其值是136
,那么此时正在写入的edits文件名则是edits_inprogress_0000000000000000136
。
每次NameNode启动的时候,都会将Fsimage文件读入内存,加载Edits里面的更新操作,保证内存中的元数据信息都是最新的、同步的,可以看成NameNode启动的时候,将Fsimage和edits文件进行了一次合并。
查看edits和fsimage文件内容
hdfs命令提供了两个选项(oiv和oev)来分别查看edits和fsimage的文件内容,命令如下:
# 以下都是导出xml格式,-i指定查看哪个源文件,-o指定输出到哪个文件,其余为固定字段。
# 查看edits文件内容
$ hdfs oev -p XML -i edits_inprogress_0000000000000000136 -o edits.xml
# 查看fsimage文件内容
$ hdfs oiv -p XML -i fsimage_0000000000000000135 -o fsimage.xml
checkpoint触发条件
在开头的图中,我们可以看到chenckpoint触发条件默认有两个,一是定时时间到;二是edits中的数据满了,这两个触发条件满足其中之一,secondary才会去合并namenode上的edit和fsimage文件,通常情况下,secondaryNamenode每隔一小时或者操作次数达到1百万时(每分钟会查看一次操作次数),secondaryname会进行一次合并。
$ vim etc/hadoop/hdfs-site.xml # 编辑此文件(下面都是默认值,一般无需改动)
<configuration> # 写入以下内容
<!--指定多长时间进行一次合并,默认为3600s(1小时)-->
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
<!--指定多少次操作后进行一次合并,默认是一百万次-->
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
</property>
<!--指定多长时间检查下操作次数,默认是60s-->
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
</property>
···