思考:NameNode 中的元数据是存储在哪里的?
首先,我们做个假设,如果存储在 NameNode 节点的磁盘中,因为经常需要进行随机访 问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在 内存中,一旦断电,元数据丢失,整个集群就无法工作了。因此产生在磁盘中备份元数据的 FsImage。
这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新 FsImage,就会导 致效率过低,但如果不更新,就会发生一致性问题,一旦 NameNode 节点断电,就会产生数 据丢失。因此,引入 Edits 文件(只进行追加操作,效率很高)。每当元数据有更新或者添 加元数据时,修改内存中的元数据并追加到 Edits 中。这样,一旦 NameNode 节点断电,可 以通过 FsImage 和 Edits 的合并,合成元数据。
但是,如果长时间添加数据到 Edits 中,会导致该文件数据过大,效率降低,而且一旦 断电,恢复元数据需要的时间过长。因此,需要定期进行 FsImage 和 Edits 的合并,如果这 个操作由 NameNode 节点完成,又会效率过低。因此,引入一个新的节点 SecondaryNamenode, 专门用于 FsImage 和 Edits 的合并。
1) 第一阶段: NameNode 启动
2) 第二阶段: Secondary NameNode 工作
NameNode被格式化之后, 将在/opt/module/hadoop-3.1.3/data/tmp/dfs/name/current目录中产生如下文件
fsimage_0000000000000000000
fsimage_0000000000000000000.md5
seen_txid
VERSION
1) oiv 查看 Fsimage 文件
(1) 查看 oiv 和 oev 命令
[atguigu@hadoop102 current]$ hdfs
oiv apply the offline fsimage viewer to an fsimage
oev apply the offline edits viewer to an edits file
(2) 基本语法
hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径
(3) 案例实操
[root@hadoop102 current]# hdfs oiv -p xml -i fsimage_0000000000000000567 -o /opt/software/fsimage.xml
2021-03-31 22:57:24,038 INFO offlineImageViewer.FSImageHandler: Loading 3 strings
将显示的 xml 文件内容拷贝到 Idea 中创建的 xml 文件中,并格式化。显示结果如下。
<?xml version="1.0"?>
<fsimage>
<version>
<layoutVersion>-64</layoutVersion>
<onDiskVersion>1</onDiskVersion>
<oivRevision>ba631c436b806728f8ec2f54ab1e289526c90579</oivRevision>
</version>
<NameSection>
<namespaceId>1197287034</namespaceId>
<genstampV1>1000</genstampV1>
<genstampV2>1060</genstampV2>
<genstampV1Limit>0</genstampV1Limit>
<lastAllocatedBlockId>1073741883</lastAllocatedBlockId>
<txid>567</txid>
</NameSection>
<ErasureCodingSection>
<erasureCodingPolicy>
<policyId>1</policyId>
<policyName>RS-6-3-1024k</policyName>
<cellSize>1048576</cellSize>
<policyState>DISABLED</policyState>
<ecSchema>
<codecName>rs</codecName>
<dataUnits>6</dataUnits>
<parityUnits>3</parityUnits>
</ecSchema>
</erasureCodingPolicy>
<erasureCodingPolicy>
<policyId>2</policyId>
<policyName>RS-3-2-1024k</policyName>
<cellSize>1048576</cellSize>
<policyState>DISABLED</policyState>
<ecSchema>
<codecName>rs</codecName>
<dataUnits>3</dataUnits>
<parityUnits>2</parityUnits>
</ecSchema>
</erasureCodingPolicy>
<erasureCodingPolicy>
<policyId>3</policyId>
<policyName>RS-LEGACY-6-3-1024k</policyName>
<cellSize>1048576</cellSize>
<policyState>DISABLED</policyState>
<ecSchema>
<codecName>rs-legacy</codecName>
<dataUnits>6</dataUnits>
<parityUnits>3</parityUnits>
</ecSchema>
</erasureCodingPolicy>
<erasureCodingPolicy>
<policyId>4</policyId>
<policyName>XOR-2-1-1024k</policyName>
<cellSize>1048576</cellSize>
<policyState>DISABLED</policyState>
<ecSchema>
<codecName>xor</codecName>
<dataUnits>2</dataUnits>
<parityUnits>1</parityUnits>
</ecSchema>
</erasureCodingPolicy>
<erasureCodingPolicy>
<policyId>5</policyId>
<policyName>RS-10-4-1024k</policyName>
<cellSize>1048576</cellSize>
<policyState>DISABLED</policyState>
<ecSchema>
<codecName>rs</codecName>
<dataUnits>10</dataUnits>
<parityUnits>4</parityUnits>
</ecSchema>
</erasureCodingPolicy>
</ErasureCodingSection>
<INodeSection>
<lastInodeId>16497</lastInodeId>
<numInodes>20</numInodes>
<inode>
<id>16385</id>
<type>DIRECTORY</type>
<name></name>
<mtime>1617067764056</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>9223372036854775807</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16386</id>
<type>DIRECTORY</type>
<name>wcinput</name>
<mtime>1616550737222</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16387</id>
<type>FILE</type>
<name>word.txt</name>
<replication>3</replication>
<mtime>1616550737215</mtime>
<atime>1616555991060</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<blocks>
<block>
<id>1073741825</id>
<genstamp>1001</genstamp>
<numBytes>35</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
<inode>
<id>16460</id>
<type>DIRECTORY</type>
<name>wcoutput</name>
<mtime>1616556023765</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16467</id>
<type>FILE</type>
<name>part-r-00000</name>
<replication>3</replication>
<mtime>1616556023510</mtime>
<atime>1616556023225</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<blocks>
<block>
<id>1073741870</id>
<genstamp>1046</genstamp>
<numBytes>38</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
<inode>
<id>16469</id>
<type>FILE</type>
<name>_SUCCESS</name>
<replication>3</replication>
<mtime>1616556023780</mtime>
<atime>1616556023765</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<storagePolicyId>0</storagePolicyId>
</inode>
<inode>
<id>16479</id>
<type>FILE</type>
<name>weiguo.txt</name>
<replication>3</replication>
<mtime>1616981795340</mtime>
<atime>1616981795117</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<blocks>
<block>
<id>1073741878</id>
<genstamp>1054</genstamp>
<numBytes>7</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
<inode>
<id>16480</id>
<type>FILE</type>
<name>wuguo.txt</name>
<replication>3</replication>
<mtime>1616981833812</mtime>
<atime>1616981833599</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<blocks>
<block>
<id>1073741879</id>
<genstamp>1055</genstamp>
<numBytes>6</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
<inode>
<id>16481</id>
<type>DIRECTORY</type>
<name>jinguo</name>
<mtime>1616982350985</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16482</id>
<type>FILE</type>
<name>shuguo.txt</name>
<replication>10</replication>
<mtime>1616982294238</mtime>
<atime>1616982294005</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<blocks>
<block>
<id>1073741880</id>
<genstamp>1057</genstamp>
<numBytes>14</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
<inode>
<id>16486</id>
<type>DIRECTORY</type>
<name>tmp</name>
<mtime>1617065175644</mtime>
<permission>root:supergroup:0770</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16487</id>
<type>DIRECTORY</type>
<name>hadoop-yarn</name>
<mtime>1617065175644</mtime>
<permission>root:supergroup:0770</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16488</id>
<type>DIRECTORY</type>
<name>staging</name>
<mtime>1617065175644</mtime>
<permission>root:supergroup:0770</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16489</id>
<type>DIRECTORY</type>
<name>history</name>
<mtime>1617065175703</mtime>
<permission>root:supergroup:0770</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16490</id>
<type>DIRECTORY</type>
<name>done</name>
<mtime>1617065175644</mtime>
<permission>root:supergroup:0770</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16491</id>
<type>DIRECTORY</type>
<name>done_intermediate</name>
<mtime>1617065175703</mtime>
<permission>root:supergroup:1777</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16494</id>
<type>DIRECTORY</type>
<name>xiyou</name>
<mtime>1617067768812</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16495</id>
<type>DIRECTORY</type>
<name>huaguoshan1</name>
<mtime>1617067764057</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16496</id>
<type>DIRECTORY</type>
<name>huaguoshan</name>
<mtime>1617067768812</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16497</id>
<type>FILE</type>
<name>huaguoshan.txt</name>
<replication>3</replication>
<mtime>1617067769002</mtime>
<atime>1617067768812</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<blocks>
<block>
<id>1073741883</id>
<genstamp>1060</genstamp>
<numBytes>9</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
</INodeSection>
<INodeReferenceSection></INodeReferenceSection>
<SnapshotSection>
<snapshotCounter>0</snapshotCounter>
<numSnapshots>0</numSnapshots>
</SnapshotSection>
<INodeDirectorySection>
<directory>
<parent>16385</parent>
<child>16481</child>
<child>16486</child>
<child>16386</child>
<child>16460</child>
<child>16494</child>
</directory>
<directory>
<parent>16386</parent>
<child>16387</child>
</directory>
<directory>
<parent>16460</parent>
<child>16469</child>
<child>16467</child>
</directory>
<directory>
<parent>16481</parent>
<child>16482</child>
<child>16479</child>
<child>16480</child>
</directory>
<directory>
<parent>16486</parent>
<child>16487</child>
</directory>
<directory>
<parent>16487</parent>
<child>16488</child>
</directory>
<directory>
<parent>16488</parent>
<child>16489</child>
</directory>
<directory>
<parent>16489</parent>
<child>16490</child>
<child>16491</child>
</directory>
<directory>
<parent>16494</parent>
<child>16496</child>
<child>16495</child>
</directory>
<directory>
<parent>16496</parent>
<child>16497</child>
</directory>
</INodeDirectorySection>
<FileUnderConstructionSection></FileUnderConstructionSection>
<SecretManagerSection>
<currentId>0</currentId>
<tokenSequenceNumber>0</tokenSequenceNumber>
<numDelegationKeys>0</numDelegationKeys>
<numTokens>0</numTokens>
</SecretManagerSection>
<CacheManagerSection>
<nextDirectiveId>1</nextDirectiveId>
<numDirectives>0</numDirectives>
<numPools>0</numPools>
</CacheManagerSection>
</fsimage>
思考:可以看出, Fsimage 中没有记录块所对应 DataNode,为什么?
在集群启动后,要求 DataNode 上报数据块信息,并间隔一段时间后再次上报。
2) oev 查看 Edits 文件
(1) 基本语法
hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径
(2) 案例实操
[root@hadoop102 current]# hdfs oev -p XML -i edits_0000000000000000566-0000000000000000567 -o /opt/software/edits.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EDITS>
<EDITS_VERSION>-64</EDITS_VERSION>
<RECORD>
<OPCODE>OP_START_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>566</TXID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_END_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>567</TXID>
</DATA>
</RECORD>
</EDITS>
思考: NameNode 如何确定下次开机启动的时候合并哪些 Edits?
1) 通常情况下, SecondaryNameNode 每隔一小时执行一次。
[hdfs-default.xml]
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600s</value>
</property>
2) 一分钟检查一次操作次数,当操作次数达到 1 百万时, SecondaryNameNode 执行一次。
<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>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60s</value>
<description>The SecondaryNameNode and CheckpointNode will poll the NameNode
every ‘dfs.namenode.checkpoint.check.period‘ seconds to query the number
of uncheckpointed transactions. Support multiple time unit suffix(case insensitive),
as described in dfs.heartbeat.interval.
</description>
</property>
原文:https://www.cnblogs.com/iamfatotaku/p/14606171.html