一、NameNode介绍
1.1、HDFS支持主从结构
- 主节点称为:NameNode,因为主节点上运行的有NameNode进程。NameNode支持多个,目前配置1个
- 从节点称为:DataNode,因为从节点上运行的有DataNode进程,DataNode支持多个,目前配置2个
- 还包含SecondaryNameNode
1.2、NameNode的介绍
NameNode是整个文件系统的管理节点。它主要维护整个文件系统的文件目录树,文件/目录的信息和每个文件对应的数据块列表,并且还负责接收用户的操作请求
- 文件目录的信息:表示文件/目录的一些基本信息,所有者、属组、修改时间、文件大小等
- 每个文件对应的数据块列表:如果一个文件太大,那么在集群中存储会对文件进行切割,这个时候就类似于会给文件分成一块一块的,存储在不同机器上面,所以HDFS还要记录一下一个文件到底分了多少块,每一块都在什么地方存储着
- 接收用户操作请求:其实我们在命令行使用HDFS操作的时候,是需要先和namenode通信才能开始去操作数据的
1.3、展示文件被切割的例子
-
上传文件
将大文件上传到hdfs中
hdfs dfs -put hadoop-3.3.4.tar.gz /
-
浏览器查看
浏览器查看http://192.168.234.100:9870/explorer.html#/
二、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属性
hadoop.tmp.dir这个属性的值默认在core-default.xml文件中。也就是我们前面配置的core-site.xml
查看dfs.namenode的目录
里面有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进程将不会完成启动以保护数据的一致性
五、NameNode的version文件(版本文件信息)
它保存了集群的版本信息