1.NameNode分析
namenode节点主要包含fsimage、edits、seen_txid、VERSION文件;
1.1 fsimage主要存储文件最新的快照数据(元信息以及文件存储的目录树),如下为查看fsimage内容的命令以及对应的内容样例:
bash /home/hadoop3.3.1/hadoop-3.3.1/bin/hdfs oiv -p XML -i fsimage_0000000000000000016 -o /home/fsimage16.xml
<inode><id>16389</id><type>FILE</type><name>hadoop-3.3.1.tar.gz</name><replication>2</replication><mtime>1639018837819</mtime><atime>1639018793827</atime><preferredBlockSize>134217728</preferredBlockSize><permission>root:supergroup:0644</permission><blocks>
<block><id>1073741827</id><genstamp>1003</genstamp><numBytes>134217728</numBytes></block>
<block><id>1073741828</id><genstamp>1004</genstamp><numBytes>134217728</numBytes></block>
<block><id>1073741829</id><genstamp>1005</genstamp><numBytes>134217728</numBytes></block>
<block><id>1073741830</id><genstamp>1006</genstamp><numBytes>134217728</numBytes></block>
<block><id>1073741831</id><genstamp>1007</genstamp><numBytes>68316367</numBytes></block>
</blocks>
<storagePolicyId>0</storagePolicyId></inode>
1.2 edits文件主要存储的是文件操作的详细步骤(实时过程数据)(edits的文件会定期的同步到fsimage中–通过secondaryNameNode来同步,这也是secondaryNameNode的唯一作用),如下为查看edits内容的命令以及对应的内容样例:
bash /home/hadoop3.3.1/hadoop-3.3.1/bin/hdfs oev -i edits_inprogress_0000000000000000044 -o /home/edits.xml
<RECORD>
<OPCODE>OP_ADD</OPCODE>
<DATA>
<TXID>24</TXID>
<LENGTH>0</LENGTH>
<INODEID>16389</INODEID>
<PATH>/hadoop-3.3.1.tar.gz._COPYING_</PATH>
<REPLICATION>2</REPLICATION>
<MTIME>1639018793827</MTIME>
<ATIME>1639018793827</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME>DFSClient_NONMAPREDUCE_-816749945_1</CLIENT_NAME>
<CLIENT_MACHINE>192.168.136.103</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>eac04cbe-68b6-41d2-aabc-f41b781cff4b</RPC_CLIENTID>
<RPC_CALLID>3</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>25</TXID>
<BLOCK_ID>1073741827</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>26</TXID>
<GENSTAMPV2>1003</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>27</TXID>
<PATH>/hadoop-3.3.1.tar.gz._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741827</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1003</GENSTAMP>
</BLOCK>
<RPC_CLIENTID/>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>28</TXID>
<BLOCK_ID>1073741828</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>29</TXID>
<GENSTAMPV2>1004</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>30</TXID>
<PATH>/hadoop-3.3.1.tar.gz._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741827</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1003</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741828</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1004</GENSTAMP>
</BLOCK>
<RPC_CLIENTID/>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>31</TXID>
<BLOCK_ID>1073741829</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>32</TXID>
<GENSTAMPV2>1005</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>33</TXID>
<PATH>/hadoop-3.3.1.tar.gz._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741828</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1004</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741829</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1005</GENSTAMP>
</BLOCK>
<RPC_CLIENTID/>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>34</TXID>
<BLOCK_ID>1073741830</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>35</TXID>
<GENSTAMPV2>1006</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>36</TXID>
<PATH>/hadoop-3.3.1.tar.gz._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741829</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1005</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741830</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1006</GENSTAMP>
</BLOCK>
<RPC_CLIENTID/>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>37</TXID>
<BLOCK_ID>1073741831</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>38</TXID>
<GENSTAMPV2>1007</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>39</TXID>
<PATH>/hadoop-3.3.1.tar.gz._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741830</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1006</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741831</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1007</GENSTAMP>
</BLOCK>
<RPC_CLIENTID/>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_CLOSE</OPCODE>
<DATA>
<TXID>40</TXID>
<LENGTH>0</LENGTH>
<INODEID>0</INODEID>
<PATH>/hadoop-3.3.1.tar.gz._COPYING_</PATH>
<REPLICATION>2</REPLICATION>
<MTIME>1639018837819</MTIME>
<ATIME>1639018793827</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME/>
<CLIENT_MACHINE/>
<OVERWRITE>false</OVERWRITE>
<BLOCK>
<BLOCK_ID>1073741827</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1003</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741828</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1004</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741829</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1005</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741830</BLOCK_ID>
<NUM_BYTES>134217728</NUM_BYTES>
<GENSTAMP>1006</GENSTAMP>
</BLOCK>
<BLOCK>
<BLOCK_ID>1073741831</BLOCK_ID>
<NUM_BYTES>68316367</NUM_BYTES>
<GENSTAMP>1007</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>41</TXID>
<LENGTH>0</LENGTH>
<SRC>/hadoop-3.3.1.tar.gz._COPYING_</SRC>
<DST>/hadoop-3.3.1.tar.gz</DST>
<TIMESTAMP>1639018837823</TIMESTAMP>
<RPC_CLIENTID>eac04cbe-68b6-41d2-aabc-f41b781cff4b</RPC_CLIENTID>
<RPC_CALLID>13</RPC_CALLID>
</DATA>
</RECORD>
1.3 seen_txid
存放当前最新的事务id,以此保证数据的完整性;
1.4 VERSION
存放当前namenode的版本信息
namespaceID=1091064552
clusterID=CID-1a520042-fc3d-428d-adf5-66b77af173f0
cTime=1638946985019
storageType=NAME_NODE
blockpoolID=BP-223224798-192.168.136.103-1638946985019
layoutVersion=-66
2.SecondaryNameNode分析
主要负责定期把edits文件中的内容合并到fsimage中(checkpoint);
如果namenode为HA模式,则没有SecondaryNameNode进程,具体的合并工作由standby namenode负责,也就是SecondaryNameNode不是必须的进程;
3.NameNode总结
总体来说,NameNode保存了两部分数据:
1.file与block的关系,对应的关系信息存储在fsimage和edits文件中,当NameNode启动的时候会把文件中的元数据信息加载到内存中;
2.datanode与block的关系,对应的关系主要在集群启动的时候保存在内存中,当DataNode启动时会把当前节点上的Block信息和节点信息上报给NameNode;
block块存放在哪些datanode上,只有datanode自己知道,当集群启动的时候,datanode会扫描自己节点上面的所有block块信息,然后把节点和这个节点上的所有block块信息告诉给namenode。这个关系是每次重启集群都会动态加载的【这个其实就是集群为什么数据越多,启动越慢的原因】;
附:
1.注意了,刚才我们说了NameNode启动的时候会把文件中的元数据信息加载到内存中,然后每一个文件的元数据信息会占用150字节的内存空间,这个是恒定的,和文件大小没有关系,咱们前面在介绍HDFS的时候说过,HDFS不适合存储小文件,其实主要原因就在这里,不管是大文件还是小文件,一个文件的元数据信息在NameNode中都会占用150字节,NameNode节点的内存是有限的,所以它的存储能力也是有限的,如果我们存储了一堆都是几KB的小文件,最后发现NameNode的内存占满了,确实存储了很多文件,但是文件的总体大小却很小,这样就失去了HDFS存在的价值;