文章目录
- 1.为什么需要2NN
- 2.FsImage和Edits文件
- 3.NameNode与2NN如何工作
在HDFS的组成中,最重要的两个核心进程分别为NameNode和DataNode,NameNode负责存储元数据信息,而DataNode则用于存放数据,而另一个进程被称为2NN(Secondary NameNode),它的作用在于辅助NameNode做日志合并,防止元数据丢失。
1.为什么需要2NN
首先要了解NameNode的工作机制,NameNode作为整个HDFS集群的管理者,会保存所有DataNode数据元信息,这些元数据如果只存储在内存中的话,数据的读写将会较低效,所以为了提升读写效率,NameNode会将这些元数据存储在内存中,通过对内存的读写来优化读写效率,一个数据块Block会占据150KB的元数据空间(这也是为什么HDFS不推荐存储大量小文件的原因,因为Block过多,会导致NameNode内存溢出)。
NameNode的元数据组成为:{文件名,副本数,BlockId}。通过这个三元组即可找到对应的数据块存储在DataNode的哪个位置。
如果NameNode仅仅使用内存来存储元数据的话,那么当服务器重启时内存信息都会丢失,所以必须还进行落盘持久化,NameNode把内存中的元数据进行持久化并落入磁盘中的备份数据被称为FsImage。
2.FsImage和Edits文件
FsImage是NameNode内存元数据进行序列化后的备份数据,它包含了所有HDFS系统中的所有目录文件以及文件idode信息,而Edits文件则是用于增量记录更新操作路径,当客户端进行写操作时,首先会记录下Edits文件,FsImage和Edits文件可以通过oiv和oev命令反序列化成xml格式进行查看:
FsImage文件:
<inode>
<id>16386</id>
<type>DIRECTORY</type>
<name>user</name>
<mtime>1512722284477</mtime>
<permission>xxx:supergroup:rwxr-xr-x</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16387</id>
<type>DIRECTORY</type>
<name>atguigu</name>
<mtime>1512790549080</mtime>
<permission>xxx:supergroup:rwxr-xr-x</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16389</id>
<type>FILE</type>
<name>wc.input</name>
<replication>3</replication>
<mtime>1512722322219</mtime>
<atime>1512722321610</atime>
<perferredBlockSize>134217728</perferredBlockSize>
<permission>xxx:supergroup:rw-r--r--</permission>
<blocks>
<block>
<id>1073741825</id>
<genstamp>1001</genstamp>
<numBytes>59</numBytes>
</block>
</blocks>
</inode >
Edits文件:
<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
<EDITS_VERSION>-63</EDITS_VERSION>
<RECORD>
<OPCODE>OP_ADD</OPCODE>
<DATA>
<TXID>130</TXID>
<LENGTH>0</LENGTH>
<INODEID>16407</INODEID>
<PATH>/hello7.txt</PATH>
<REPLICATION>2</REPLICATION>
<MTIME>1512943607866</MTIME>
<ATIME>1512943607866</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME>DFSClient_NONMAPREDUCE_-1544295051_1</CLIENT_NAME>
<CLIENT_MACHINE>192.168.1.10</CLIENT_MACHINE>
<OVERWRITE>true</OVERWRITE>
<PERMISSION_STATUS>
<USERNAME>xxx</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
<RPC_CLIENTID>908eafd4-9aec-4288-96f1-e8011d181561</RPC_CLIENTID>
<RPC_CALLID>0</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>131</TXID>
<BLOCK_ID>1073741839</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_CLOSE</OPCODE>
<DATA>
<TXID>134</TXID>
<LENGTH>0</LENGTH>
<INODEID>0</INODEID>
<PATH>/hello7.txt</PATH>
<REPLICATION>2</REPLICATION>
<MTIME>1512943608761</MTIME>
<ATIME>1512943607866</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME></CLIENT_NAME>
<CLIENT_MACHINE></CLIENT_MACHINE>
<OVERWRITE>false</OVERWRITE>
<BLOCK>
<BLOCK_ID>1073741839</BLOCK_ID>
<NUM_BYTES>25</NUM_BYTES>
<GENSTAMP>1016</GENSTAMP>
</BLOCK>
<PERMISSION_STATUS>
<USERNAME>xxx</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
</EDITS >
所以NameNode通过增量追加Edits操作记录合并写入FsImage的方式进行元数据的备份:
3.NameNode与2NN如何工作
通过FsImage和Edits的备份机制,就可以解决NameNode内存元数据丢失的问题了,那为什么还需要2NN呢?
Edits文件需要和FsImage合并,但是谁来合并这份数据呢?如果是NameNode自身来合并数据的话,会耗费时间,并且为了保证数据尽量不丢失,需要进行定时的合并。
所以2NN的作用就是进行辅助NameNode定期去合并Edits和FsImage文件,以使得系统挂掉时能够少丢数据,当NameNode再次启动,直接读取少量的本地尚未合并的Edits信息和已经由2NN同步完成的FsImage文件加载到内存中,就完成宕机重启数据恢复的过程: