hdfs 中元数据 fsimage,edits详解

前言

我们知道,namenode 作为 hdfs 的元数据管理节点,其将所有的元数据都存储在 fsimage 中,本文结合实际目录文件,了解 namenode 的元数据到底是什么

图片

fsimage 元数据存储在哪?

namenode 的 image 存储目录在 hdfs-site.xml 中进行配置,配置参数为

dfs.namenode.name.dir
默认值: file://${hadoop.tmp.dir}/dfs/name

其中 hadoop.tmp.dir 的配置在 core-site.xml 中进行配置,默认值为

/tmp/hadoop-${user.name}

也就是说如果你不就想配置,namenode 的默认目录为

/tmp/hadoop-${user.name}/dfs/name

而 seconarynamneode,用于做 checkpoint 合并 image 和 editslog,他的工作配置目录为

dfs.namenode.checkpoint.dir
默认值: file://${hadoop.tmp.dir}/dfs/namesecondary

这些对应的配置功能可以在 官方默认配置文档 中找到

元数据文件有哪些?

进入到 fsimage 目录下,通过 ls -l 命令查看,如下图所示

图片

可以看到,文件分为以下 6 类

  1. edits_0000xxxx-0000xxxx
    此类文件为已完结历史 edits 日志文件,这类文件的命名规则为 edits_19 位 txid,未满 19 位的 txid 用 0 补齐
  2. edits_inprogress_0000xxxx
    该文件为当前正在写入的 edits 日志文件,规则和 edits 类似,只是中间多了 ingrogress 表示正在写入
  3. fsimage_0000xxx
    该文件为镜像文件,命名规则为 fsimage_19 位 txid,其中 txid 表示该镜像合并到的最新 edits 日志。
    镜像文件一般为 2 个。
  4. fsiamge_000xxx.md5
    该文件为镜像文件对应的 md5 码,用于校验镜像文件是否一致。
  5. seen_txid
    该文件存储了最新的 txid,新的 edits 日志文件命名都在此 txid 上+1
  6. VERSION
    该文件存储的是 namenode 的一些版本信息

    元数据的文件内容长什么样?

日志文件 edits_0000xxxx-0000xxxx

直接通过 cat 或 vi 命令查看日志文件的话,会发现 edits 文件有一堆乱码

图片

想要查看 edits 文件,需要使用到 hdfs oev 命令,该命令为 hadoop官方提供的解析工具

常用的一个命令为

hdfs oev -i edits_0000000000000157832-0000000000000158267 -o test_edits.xml
# -i 为输入edits文件地址
# -o 为输出的xml地址

此时,我们再来看已经被解析为 xml 的 test_edits.xml 文件,就可以看到如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EDITS>
  <EDITS_VERSION>-66</EDITS_VERSION>
  <RECORD>
    <OPCODE>OP_START_LOG_SEGMENT</OPCODE>
    <DATA>
      <TXID>157832</TXID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_MKDIR</OPCODE>
    <DATA>
      <TXID>157833</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>42861</INODEID>
      <PATH>/tmp/hive/hdfs/76876549-32f3-4f95-90e4-54e8846432d4</PATH>
      <TIMESTAMP>1663027209019</TIMESTAMP>
      <PERMISSION_STATUS>
        <USERNAME>hdfs</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>448</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_MKDIR</OPCODE>
    <DATA>
      <TXID>157834</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>42862</INODEID>
      <PATH>/tmp/hive/hdfs/76876549-32f3-4f95-90e4-54e8846432d4/_tmp_space.db</PATH>
      <TIMESTAMP>1663027209046</TIMESTAMP>
      <PERMISSION_STATUS>
        <USERNAME>hdfs</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>448</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_DELETE</OPCODE>
    <DATA>
      <TXID>157835</TXID>
      <LENGTH>0</LENGTH>
      <PATH>/user/hive/warehouse/stock.db/finance_indicator</PATH>
      <TIMESTAMP>1663027213944</TIMESTAMP>
      <RPC_CLIENTID>fa9f4009-c253-4109-a73e-6dfae064020f</RPC_CLIENTID>
      <RPC_CALLID>14</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_MKDIR</OPCODE>
    <DATA>
      <TXID>157836</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>42863</INODEID>
      <PATH>/user/hive/warehouse/stock.db/finance_indicator</PATH>
      <TIMESTAMP>1663027213948</TIMESTAMP>
      <PERMISSION_STATUS>
        <USERNAME>hdfs</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>493</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_SET_ACL</OPCODE>
    <DATA>
      <TXID>157837</TXID>
      <SRC>/user/hive/warehouse/stock.db/finance_indicator</SRC>
      <ENTRY>
        <SCOPE>ACCESS</SCOPE>
        <TYPE>USER</TYPE>
        <PERM>rwx</PERM>
      </ENTRY>
      <ENTRY>
        <SCOPE>ACCESS</SCOPE>
        <TYPE>GROUP</TYPE>
        <PERM>r-x</PERM>
      </ENTRY>
      <ENTRY>
        <SCOPE>ACCESS</SCOPE>
        <TYPE>OTHER</TYPE>
        <PERM>r-x</PERM>
      </ENTRY>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_DELETE</OPCODE>
    <DATA>
      <TXID>157838</TXID>
      <LENGTH>0</LENGTH>
      <PATH>/user/hive/warehouse/stock.db/stock_price_none</PATH>
      <TIMESTAMP>1663027214022</TIMESTAMP>
      <RPC_CLIENTID>fa9f4009-c253-4109-a73e-6dfae064020f</RPC_CLIENTID>
      <RPC_CALLID>22</RPC_CALLID>
    </DATA>
  </RECORD>

可以看到,edits 日志是由一条一条 record 组成的,record 的 oprecode 一共有 53 种,具体可以查看 org.apache.hadoop.hdfs.server.namenode.FSEditLogOpCodes 这个枚举类,这里就不再展开了

具体的操作内容,则可以查看 org.apache.hadoop.hdfs.server.namenode.FSEditLogOp ,这个类里的静态子类封装了 edits 的各种操作抽象,xml 种对应的属性在里面都可以找到,这里也不再展开。

edits_inprogress_0000xxxx

文件内容同 日志文件edits_0000xxxx-0000xxxx

fsimage_0000xxx

直接通过 cat 或 vi 命令查看 image 镜像文件的话,会发现 image 文件有一堆乱码

图片

想要查看 image 文件,需要使用到 hdfs oiv 命令,该命令为 hadoop官方提供的镜像解析工具

常用的一个命令为

hdfs oiv -i fsimage_0000000000000161098 -o test_image.xml -p XML
# -i 为输入image文件地址
# -o 为输出的xml地址
# -p 表示使用什么格式进行处理

解析结束后,我们再来看已经被解析为 xml 的 test_image.xml 文件,就可以看到如下所示:

<?xml version="1.0"?>
<fsimage>
    <version>
        <layoutVersion>-66</layoutVersion>
        <onDiskVersion>1</onDiskVersion>
        <oivRevision>a3b9c37a397ad4188041dd80621bdeefc46885f2</oivRevision>
    </version>
    <NameSection>
        <namespaceId>1614349331</namespaceId>
        <genstampV1>1000</genstampV1>
        <genstampV2>13399</genstampV2>
        <genstampV1Limit>0</genstampV1Limit>
        <lastAllocatedBlockId>1073754220</lastAllocatedBlockId>
        <txid>161098</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>43596</lastInodeId>
        <numInodes>1572</numInodes>
        <inode>
            <id>16385</id>
            <type>DIRECTORY</type>
            <name></name>
            <mtime>1659683329779</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>9223372036854775807</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16386</id>
            <type>DIRECTORY</type>
            <name>tmp</name>
            <mtime>1659770965040</mtime>
            <permission>hdfs:supergroup:0733</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16387</id>
            <type>DIRECTORY</type>
            <name>hive</name>
            <mtime>1659772693233</mtime>
            <permission>hdfs:supergroup:0733</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16388</id>
            <type>DIRECTORY</type>
            <name>hdfs</name>
            <mtime>1663029189271</mtime>
            <permission>hdfs:supergroup:0700</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16391</id>
            <type>DIRECTORY</type>
            <name>hive</name>
            <mtime>1662261600810</mtime>
            <permission>hive:supergroup:0700</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16396</id>
            <type>DIRECTORY</type>
            <name>user</name>
            <mtime>1659683329779</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16397</id>
            <type>DIRECTORY</type>
            <name>hive</name>
            <mtime>1659683329779</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16398</id>
            <type>DIRECTORY</type>
            <name>warehouse</name>
            <mtime>1660102421896</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16399</id>
            <type>DIRECTORY</type>
            <name>stock.db</name>
            <mtime>1663029031404</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16405</id>
            <type>DIRECTORY</type>
            <name>stk_balance_sheet</name>
            <mtime>1661338700499</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16495</id>
            <type>DIRECTORY</type>
            <name>valuation__7c02ecf9_3e09_44c0_8121_7eb3e7c1d079</name>
            <mtime>1660718214011</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16646</id>
            <type>DIRECTORY</type>
            <name>valuation__4ef5e657_b1b9_4dfb_bb2f_d04e25a4902a</name>
            <mtime>1660718214009</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16650</id>
            <type>DIRECTORY</type>
            <name>valuation__940421e3_2ba0_4c20_b8d3_e01066c21156</name>
            <mtime>1660718214012</mtime>
            <permission>hdfs:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16678</id>
            <type>DIRECTORY</type>
            <name>46d8d97e-87df-4dff-baa4-c83024cfbce5</name>
            <mtime>1659770965946</mtime>
            <permission>hdfs:supergroup:0700</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16679</id>
            <type>DIRECTORY</type>
            <name>_tmp_space.db</name>
            <mtime>1659770910781</mtime>
            <permission>hdfs:supergroup:0700</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16743</id>
            <type>DIRECTORY</type>
            <name>hadoop-yarn</name>
            <mtime>1659770965040</mtime>
            <permission>hdfs:supergroup:0700</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>32524</id>
            <type>FILE</type>
            <name>job_1646050356665_0363.summary</name>
            <replication>1</replication>
            <mtime>1661397832374</mtime>
            <atime>1661397831960</atime>
            <preferredBlockSize>134217728</preferredBlockSize>
            <permission>hdfs:supergroup:0770</permission>
            <blocks>
                <block>
                    <id>1073747785</id>
                    <genstamp>6961</genstamp>
                    <numBytes>482</numBytes>
                </block>
            </blocks>
            <storagePolicyId>0</storagePolicyId>
        </inode>

可以看到,image 的 xml 有一下几个特征

  1. 总的被 fsimage 语句块包围
  2. 里面子的有
    1. version
    2. NameSection
    3. ErasureCodingSection
    4. INodeSection
      version 描述的一些版本信息
<version>
    <layoutVersion>-66</layoutVersion>
    <onDiskVersion>1</onDiskVersion>
    <oivRevision>a3b9c37a397ad4188041dd80621bdeefc46885f2</oivRevision>
</version>
  1. NameSection 描述的是命名空间的一些信息
<NameSection>
    <namespaceId>1614349331</namespaceId>
    <genstampV1>1000</genstampV1>
    <genstampV2>13399</genstampV2>
    <genstampV1Limit>0</genstampV1Limit>
    <lastAllocatedBlockId>1073754220</lastAllocatedBlockId>
    <txid>161098</txid>
</NameSection>
  1. ErasureCodingSection
<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>

ErasureCodingSection 由一个一个 erasureCodingPolicy 片段组成,如果了解 Erasure Code 技术的话,就会明白这是一种纠删码,具体可以查看此篇 纠删码Erasure Coding (分布式存储系统)
常见的纠删码技术有阵列纠删码(Array Code: RAID5、RAID6 等)、RS(Reed-Solomon)里德-所罗门类纠删码和 LDPC(LowDensity Parity Check Code)低密度奇偶校验纠删码。LDPC 码目前主要用于通信、视频和音频编码等领域。

看到 image 中的

<policyName>RS-3-2-1024k</policyName>
  1. 就能猜测,hdfs 中使用的是 RS(Reed-Solomon)里德-所罗门类纠删码,感兴趣的可以自行搜索扩展。
    INodeSection
<INodeSection>
     <lastInodeId>43596</lastInodeId>
     <numInodes>1572</numInodes>
     <inode>
         <id>16385</id>
         <type>DIRECTORY</type>
         <name></name>
         <mtime>1659683329779</mtime>
         <permission>hdfs:supergroup:0755</permission>
         <nsquota>9223372036854775807</nsquota>
         <dsquota>-1</dsquota>
     </inode>
     <inode>
         <id>32524</id>
         <type>FILE</type>
         <name>job_1646050356665_0363.summary</name>
         <replication>1</replication>
         <mtime>1661397832374</mtime>
         <atime>1661397831960</atime>
         <preferredBlockSize>134217728</preferredBlockSize>
         <permission>hdfs:supergroup:0770</permission>
         <blocks>
             <block>
                 <id>1073747785</id>
                 <genstamp>6961</genstamp>
                 <numBytes>482</numBytes>
             </block>
         </blocks>
         <storagePolicyId>0</storagePolicyId>
     </inode>

INodeSection 由一段一段 inode 组成,是 image 中内容最大部分,除了上述的几个片段,image 中剩下的内容全部都是 inode。

Node 类在 Namenode 中代表了一个树状结构即 Namespace,表示的是目录和文件的抽象。

<inode>
        <id>16386</id>
        <type>DIRECTORY</type>
        <name>tmp</name>
        <mtime>1659770965040</mtime>
        <permission>hdfs:supergroup:0733</permission>
        <nsquota>-1</nsquota>
        <dsquota>-1</dsquota>
    </inode>
  1. 以上述为例,表示的 tmp 目录的信息,具体可以 hadoop 的 org.apache.hadoop.hdfs.server.namenode.INode

    fsiamge_000xxx.md5

该文件为镜像文件对应的 md5 码,用于校验镜像文件是否一致。

图片

seen_txid

该文件存储了最新的 txid,新的 edits 日志文件命名都在此 txid 上+1

图片

可以看到 seen_txid 里的文字为 161099

而 edists_inprogress 的结尾也是 161099,保存的是最新的 txid 事务 id

VERSION

该文件存储的是 namenode 的一些版本信息

图片

原文

hdfs 中元数据 fsimage,edits详解

发表回复