大数据开发初识NameNode(第六篇)

171 阅读7分钟

一、NameNode介绍

image-20220904220109986

1.1、HDFS支持主从结构
  • 主节点称为:NameNode,因为主节点上运行的有NameNode进程。NameNode支持多个,目前配置1个
  • 从节点称为:DataNode,因为从节点上运行的有DataNode进程,DataNode支持多个,目前配置2个
  • 还包含SecondaryNameNode
1.2、NameNode的介绍

NameNode是整个文件系统的管理节点。它主要维护整个文件系统的文件目录树,文件/目录的信息每个文件对应的数据块列表,并且还负责接收用户的操作请求

  • 文件目录的信息:表示文件/目录的一些基本信息,所有者、属组、修改时间、文件大小等
  • 每个文件对应的数据块列表:如果一个文件太大,那么在集群中存储会对文件进行切割,这个时候就类似于会给文件分成一块一块的,存储在不同机器上面,所以HDFS还要记录一下一个文件到底分了多少块,每一块都在什么地方存储着
  • 接收用户操作请求:其实我们在命令行使用HDFS操作的时候,是需要先和namenode通信才能开始去操作数据的
1.3、展示文件被切割的例子
  1. 上传文件

    将大文件上传到hdfs中

    hdfs dfs -put hadoop-3.3.4.tar.gz /

    image-20220904204635366

  2. 浏览器查看

    浏览器查看http://192.168.234.100:9870/explorer.html#/

    image-20220904204709985

    image-20220904204740232

二、NameNode的fsimage(元数据镜像文件)

root/software/hadoop-3.3.4/share/hadoop/hdfs/hadoop-hdfs-3.2.0.jar#hdfs-default.xml

这个文件中包含了HDFS相关的所有 默认参数,咱们在配置集群的时候会修改一个hdfs-site.xml文件,hdfs-site.xml文件属于hdfs default.xml的一个扩展,它可以覆盖掉hdfs-default.xml中同名的参数。

那我们来看一下这个文件中的dfs.namenode.name.dir属性

image-20220904211348107

hadoop.tmp.dir这个属性的值默认在core-default.xml文件中。也就是我们前面配置的core-site.xml

image-20220904211652218

查看dfs.namenode的目录

image-20220904211723875

image-20220904213317623

里面有edits文件 和fsimage文件

fsimage文件有两个文件名相同的,有一个后缀是md5(md5是一种加密算法),这个其实主要是为了做 md5校验的,为了保证文件传输的过程中不出问题,相同内容的md5是一样的,所以后期如果我把这个 fsimage和对应的fsimage.md5发给你 然后你根据md5对fsimage的内容进行加密,获取一个值 和 fsimage.md5中的内容进行比较,如果一样,说明你接收到的文件就是完整的。

在这里可以把fsimage 拆开,fs 是文件系统 filesystem image是镜像。就是给文件照了一个像,把文件的当前信息记录下来

我们可以看一下这个文件,这个文件需要使用特殊的命令进行查看

-i 输入文件 -o 输出文件

hdfs oiv -p XML -i fsimage_0000000000000000026

<?xml version="1.0"?>
<fsimage>
    <version>
        <layoutVersion>-66</layoutVersion>
        <onDiskVersion>1</onDiskVersion>
        <oivRevision>a585a73c3e02ac62350c136643a5e7f6095a3dbb</oivRevision>
    </version>
    <NameSection>
        <namespaceId>1903438570</namespaceId>
        <genstampV1>1000</genstampV1>
        <genstampV2>1002</genstampV2>
        <genstampV1Limit>0</genstampV1Limit>
        <lastAllocatedBlockId>1073741826</lastAllocatedBlockId>
        <txid>26</txid>
    </NameSection>
    2022-09-04 21:46:42,140 INFO offlineImageViewer.FSImageHandler: Loading 5 strings
2022-09-04 21:46:42,198 INFO namenode.FSDirectory: GLOBAL serial map: bits=29 maxEntries=536870911
2022-09-04 21:46:42,198 INFO namenode.FSDirectory: USER serial map: bits=24 maxEntries=16777215
2022-09-04 21:46:42,198 INFO namenode.FSDirectory: GROUP serial map: bits=24 maxEntries=16777215
2022-09-04 21:46:42,198 INFO namenode.FSDirectory: XATTR serial map: bits=24 maxEntries=16777215
    <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>16387</lastInodeId>
        <numInodes>2</numInodes>
        <inode>
            <id>16385</id>
            <type>DIRECTORY</type>
            <name></name>
            <mtime>1662266412207</mtime>
            <permission>root:supergroup:0755</permission>
            <nsquota>9223372036854775807</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16386</id>
            <type>FILE</type>
            <name>README.txt</name>
            <replication>1</replication>
            <mtime>1662213050131</mtime>
            <atime>1662213049421</atime>
            <preferredBlockSize>134217728</preferredBlockSize>
            <permission>root:supergroup:0644</permission>
            <blocks>
                <block>
                    <id>1073741825</id>
                    <genstamp>1001</genstamp>
                    <numBytes>175</numBytes>
                </block>
            </blocks>
            <storagePolicyId>0</storagePolicyId>
        </inode>
    </INodeSection>
    <INodeReferenceSection></INodeReferenceSection>
    <SnapshotSection>
        <snapshotCounter>0</snapshotCounter>
        <numSnapshots>0</numSnapshots>
    </SnapshotSection>
    <INodeDirectorySection>
        <directory>
            <parent>16385</parent>
            <child>16386</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>

这个xml最外层是一个fsimage标签,看里面的inode标签,这个inode表示是hdfs中的每一个目录或者文件信息

 <inode>
   <id>16386</id>唯一编号
   <type>FILE</type>文件类型
   <name>README.txt</name>
   <replication>1</replication>文件的副本数量
   <mtime>1662213050131</mtime>修改时间
   <atime>1662213049421</atime>访问时间
   <preferredBlockSize>134217728</preferredBlockSize>推荐每一个数据块的大小
   <permission>root:supergroup:0644</permission>权限信息
   <blocks>包含多少数据块【文件被切成数据块】内部的id表示是块id,genstamp是一个唯一编号,numBytes表示当前数据块的实际大小,
storagePolicyId表示是数据的存储策略
   <block>
   <id>1073741825</id>
   <genstamp>1001</genstamp>
   <numBytes>175</numBytes>
   </block>
   </blocks>
   <storagePolicyId>0</storagePolicyId>
 </inode>

这个文件中其实就维护了整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表,所以说fsimage中存放了hdfs最核心的数据。

三、NameNode的edits文件(操作日志文件)

hdfs oev -i edits_0000000000000000004-0000000000000000011 -o 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>4</TXID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ADD</OPCODE>执行上传操作
    <DATA>
      <TXID>5</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>16386</INODEID>
      <PATH>/README.txt._COPYING_</PATH>正在上传
      <REPLICATION>1</REPLICATION>
      <MTIME>1662213049421</MTIME>
      <ATIME>1662213049421</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME>DFSClient_NONMAPREDUCE_1482737051_1</CLIENT_NAME>
      <CLIENT_MACHINE>192.168.234.100</CLIENT_MACHINE>
      <OVERWRITE>true</OVERWRITE>
      <PERMISSION_STATUS>
        <USERNAME>root</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
      <ERASURE_CODING_POLICY_ID>0</ERASURE_CODING_POLICY_ID>
      <RPC_CLIENTID>a6a5bc08-56ee-4673-af02-5031c34c741f</RPC_CLIENTID>
      <RPC_CALLID>3</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>申请block块id
    <DATA>
      <TXID>6</TXID>
      <BLOCK_ID>1073741825</BLOCK_ID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_SET_GENSTAMP_V2</OPCODE>设置GENSTAMP
    <DATA>
      <TXID>7</TXID>
      <GENSTAMPV2>1001</GENSTAMPV2>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ADD_BLOCK</OPCODE>添加block块
    <DATA>
      <TXID>8</TXID>
      <PATH>/README.txt._COPYING_</PATH>
      <BLOCK>
        <BLOCK_ID>1073741825</BLOCK_ID>
        <NUM_BYTES>0</NUM_BYTES>
        <GENSTAMP>1001</GENSTAMP>
      </BLOCK>
      <RPC_CLIENTID/>
      <RPC_CALLID>-2</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_CLOSE</OPCODE>关闭上传操作
    <DATA>
      <TXID>9</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>0</INODEID>
      <PATH>/README.txt._COPYING_</PATH>
      <REPLICATION>1</REPLICATION>
      <MTIME>1662213050131</MTIME>
      <ATIME>1662213049421</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME/>
      <CLIENT_MACHINE/>
      <OVERWRITE>false</OVERWRITE>
      <BLOCK>
        <BLOCK_ID>1073741825</BLOCK_ID>
        <NUM_BYTES>175</NUM_BYTES>
        <GENSTAMP>1001</GENSTAMP>
      </BLOCK>
      <PERMISSION_STATUS>
        <USERNAME>root</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_RENAME_OLD</OPCODE>
    <DATA>
      <TXID>10</TXID>
      <LENGTH>0</LENGTH>
      <SRC>/README.txt._COPYING_</SRC>
      <DST>/README.txt</DST>
      <TIMESTAMP>1662213050142</TIMESTAMP>
      <RPC_CLIENTID>a6a5bc08-56ee-4673-af02-5031c34c741f</RPC_CLIENTID>
      <RPC_CALLID>9</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_END_LOG_SEGMENT</OPCODE>
    <DATA>
      <TXID>11</TXID>
    </DATA>
  </RECORD>
</EDITS>

这里面的每一个record都有一个事务id,txid,事务id是连续的,其实一个put操作会在edits文件中产生很多的record,对应的就是很多步骤,这些步骤对我们是屏蔽的。

根据我们刚才的分析,我们所有对hdfs的增删改操作都会在edits文件中留下信息,那么fsimage文件中的内容是从哪来的?

其实是这样的,edits文件会定期合并到fsimage文件中。

注意,这个其实是框架去做的,在合并的时候会对edits中的内容进行转换,生成新的内容,其实edits中保存的内容是不是太细了,单单一个上传操作就分为了好几步,其实上传成功之后,我们 只需要保存文件具体存储的block信息就行了把,所以在合并的时候其实是对edits中的内容进行了精简。

他们具体合并的代码我们不用太过关注,但是我们要知道是那个进程去做的这个事情,其实就是我们之前提到的secondarynamenode 这个进程就是负责定期的把edits中的内容合并到fsimage中。他只做一件事,这是一个单独的进程,在实际工作中部署的时候,也需要部署到一个单独的节点上面

四、NameNode的seen_txid文件(序号文件)

它代表namenode里面edits_*文件的尾数。namenode重启的时候,会按照seen_txid的顺序,顺序从头跑edits_0000000000000000001~seen_txid数字的文件。如果根据对应的seen_txid无法加载到对应的文件,namenode进程将不会完成启动以保护数据的一致性 image-20220904222400504

五、NameNode的version文件(版本文件信息)

它保存了集群的版本信息

image-20220904222833039