HDFS支持主从结构,主节点称为NameNode,从节点称为DateNode,DataNode支持多个节点。HDFS还包含一个SecondaryNameNode进程,表面意思是一个辅助主节点(备用主节点)
伪分布式单节点JPS进程:
网络部署结构图:
NameNode是整个文件系统的管理节点,它主要维护着整个文件系统的文件目录树、文件/目录的信息和每个文件对应的数据块列表,并且还负责接收用户的操作请求。
NameNode主要包含一下文件:fsimage、edits、seen_txid、VERSION,这些文件的所在路径是由hdfs-default.xml的dfs.namenode.name.dir属性控制,hdfs-site.xml文件属于hdfs-default.xml的一个扩展,它会优先覆盖default中同名参数的信息
<property> <name>dfs.namenode.name.dir</name> <value>file://${hadoop.tmp.dir}/dfs/name</value> <description>Determines where on the local filesystem the DFS name node should store the name table(fsimage). If this is a comma-delimited list of directories then the name table is replicated in all of the directories, for redundancy. </description> </property>
而hadoop.tmp.dir 这个参数是在 ${HADOOP_HOME}/etc/hadoop/core-site.xml中设置的,如下:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop_report</value> </property> </configuration>
进入file://${hadoop.tmp.dir}/dfs/name 路径下,(其中"file://"表示的是本地路径下),当集群启动状态下,当前目录下会有in_use.lock 文件,该文件用于校验namenode是否重复启动。如果没有当前文件,namenode才能正常启动,启动成功后就会上锁,停止服务的时候,当前锁就会去掉,即删除文件
同级别目录下还有个current目录,当前目录就是拥有存在fsimage、edits、seen_txid、VERSION等文件的
1.fsimage
fsimage 可以拆分成fs和image,意思是文件系统镜像,用于存储某一时刻NameNode内存中的元数据信息,fsimage文件有两个文件名相同的文件,其中一个文件名结尾是md5,这个文件主要是用来做md5校验的,为了检查和保证文件传输过程中数据不会有问题,如果后期我们将其中一个版本的fsimage文件通过相同的MD5进行加密获取一个值,获取后的值与fsimage.md5比对一致,即能够证明接收到的文件是完整的。原本的fsimage文件是没法看的,这里hdfs提供转xml方法的,如下:
hdfs oiv -p XML -i fsimage_0000000000000000012 -o fsimage12.xml
转换后的xml文件属于格式化的数据,方便我们查看元数据信息,部分结果如下:
<!-- 部分标签含义解析: id 唯一的序号信息 type 文件类型 name 文件名称 replication 副本数量 mtime 文件修改时间 atime 文件访问时间 perferredBlockSize 推荐块大小 permission 权限信息 blocks 文件被切成的数据块数 block 块的描述信息 --> <?xml version="1.0"?> <fsimage><version><layoutVersion>-65</layoutVersion><onDiskVersion>1</onDiskVersion><oivRevision>e97acb3bd8f3befd27418996fa5d4b50bf2e17bf</oivRevision></version> <NameSection><namespaceId>1333881292</namespaceId><genstampV1>1000</genstampV1><genstampV2>1001</genstampV2><genstampV1Limit>0</genstampV1Limit><lastAllocatedBlockId>1073741825</lastAllocatedBlockId><txid>12</txid></NameSection> <ErasureCodingSection> <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> <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>1</policyId><policyName>RS-6-3-1024k</policyName><cellSize>1048576</cellSize><policyState>ENABLED</policyState><ecSchema> <codecName>rs</codecName><dataUnits>6</dataUnits><parityUnits>3</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> </ErasureCodingSection> <INodeSection><lastInodeId>16386</lastInodeId><numInodes>2</numInodes><inode><id>16385</id><type>DIRECTORY</type><name></name><mtime>1615442989865</mtime><permission>root:supergroup:0755</permission><nsquota>9223372036854775807</nsquota><dsquota>-1</dsquota></inode> <inode><id>16386</id><type>FILE</type><name>anaconda-ks.cfg</name><replication>1</replication><mtime>1615442989855</mtime><atime>1615442989165</atime><preferredBlockSize>134217728</preferredBlockSize><permission>root:supergroup:0644</permission><blocks><block><id>1073741825</id><genstamp>1001</genstamp><numBytes>1243</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>
2.edits
HDFS文件系统的元数据信息是靠fsimage 和 edits 文件共同配合维护的,简单的理解就是持久化的信息会存储在fsimage文件中(术语称为集群状态快照),正在编辑的元数据信息就会维护在edits中。edits文件会定期合并至fsimage文件中。执行合并操作的进程就是SecondaryNameNode负责的。
同样的HDFS也提供了方法格式化edits文件用于查看信息
hdfs oev -i edits_0000000000000000005-0000000000000000012 -o edits12.xml
3.seen_txid
current中还有一个seen_txid文件,当第一次在HDFS格式化集群的时候seen_txid 为0,它记录的是namenode里面的edits_*文件最大的尾数,如上述edits最大尾数为12,现在seen_txid文件里面就应该记录13(最大尾数 + 1),当edits文件最大尾数+1不等于seen_txid的时候, NameNode进程将不会完成启动以保护数据一致性。
4.VERSION
保存了集群的版本信息,所以集群在第一次格式化后,不建议多次格式化,如想重新格式化集群就需要将整个current目录删除。