1 查看oiv命令

[root@node1 current]# hdfs oev --help
Usage: bin/hdfs oev [OPTIONS] -i INPUT_FILE -o OUTPUT_FILE
Offline edits viewer
Parse a Hadoop edits log file INPUT_FILE and save results
in OUTPUT_FILE.
Required command line arguments:
-i,--inputFile <arg> edits file to process, xml (case
insensitive) extension means XML format,
any other filename means binary format.
XML/Binary format input file is not allowed
to be processed by the same type processor.
-o,--outputFile <arg> Name of output file. If the specified
file exists, it will be overwritten,
format of the file is determined
by -p option

Optional command line arguments:
-p,--processor <arg> Select which type of processor to apply
against image file, currently supported
processors are: binary (native binary format
that Hadoop uses), xml (default, XML
format), stats (prints statistics about
edits file)

基本语法

hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径

3 案例实操

[root@node1 current]# ll|grep edits
-rw-r--r-- 1 root root 515 109 11:10 edits_0000000000000000001-0000000000000000008
-rw-r--r-- 1 root root 1048576 109 11:22 edits_0000000000000000009-0000000000000000038
-rw-r--r-- 1 root root 42 109 11:42 edits_0000000000000000039-0000000000000000040
-rw-r--r-- 1 root root 1048576 109 11:42 edits_0000000000000000041-0000000000000000041
-rw-r--r-- 1 root root 42 109 11:49 edits_0000000000000000042-0000000000000000043
-rw-r--r-- 1 root root 42 109 12:49 edits_0000000000000000044-0000000000000000045
-rw-r--r-- 1 root root 42 109 13:49 edits_0000000000000000046-0000000000000000047
-rw-r--r-- 1 root root 42 109 14:49 edits_0000000000000000048-0000000000000000049
-rw-r--r-- 1 root root 1048576 109 14:49 edits_inprogress_0000000000000000050
[root@node1 current]# hdfs oev -p XML -i edits_0000000000000000001-0000000000000000008 -o /opt/hadoop-3.1.3/editslog18.xml
[root@node1 current]# cat /opt/hadoop-3.1.3/editslog18.xml

显示结果如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EDITS>
<EDITS_VERSION>-64</EDITS_VERSION>
<RECORD>
<OPCODE>OP_START_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>1</TXID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_MKDIR</OPCODE>
<DATA>
<TXID>2</TXID>
<LENGTH>0</LENGTH>
<INODEID>16386</INODEID>
<PATH>/user</PATH>
<TIMESTAMP>1633748876031</TIMESTAMP>
<PERMISSION_STATUS>
<USERNAME>root</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>493</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_MKDIR</OPCODE>
<DATA>
<TXID>3</TXID>
<LENGTH>0</LENGTH>
<INODEID>16387</INODEID>
<PATH>/user/root</PATH>
<TIMESTAMP>1633748876034</TIMESTAMP>
<PERMISSION_STATUS>
<USERNAME>root</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>493</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD</OPCODE>
<DATA>
<TXID>4</TXID>
<LENGTH>0</LENGTH>
<INODEID>16388</INODEID>
<PATH>/user/root/hadoop-3.1.3.tar.gz._COPYING_</PATH>
<REPLICATION>2</REPLICATION>
<MTIME>1633749010986</MTIME>
<ATIME>1633749010986</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME>DFSClient_NONMAPREDUCE_1752542758_1</CLIENT_NAME>
<CLIENT_MACHINE>192.168.20.101</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>d021df05-6937-4fc7-9474-ffcbf27f0f14</RPC_CLIENTID>
<RPC_CALLID>3</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>5</TXID>
<BLOCK_ID>1073741825</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>6</TXID>
<GENSTAMPV2>1001</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>7</TXID>
<PATH>/user/root/hadoop-3.1.3.tar.gz._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_END_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>8</TXID>
</DATA>
</RECORD>
</EDITS>

当文件系统客户端进行了写操作(例如创建或移动了文件),这个事务首先在edits log中记录下来。NameNode在内存中有文件系统的元数据,当edits log记录结束后,就更新内存中的元数据。内存中的元数据用于响应客户端的读请求。

edits log在磁盘上表现为一定数量的文件。每个文件称为片段(Segment),前缀“edits”,后缀是其中包含的事务ID(transaction IDs)。每个写操作事务都仅仅打开一个文件(比如:edits_inprogress_00000000000010),写完后冲刷缓冲区并同步到磁盘,然后返回客户端success状态码。如果NameNode的元数据需要写到多个目录中,则对于每个写事务需要所有的写操作都完成,并冲刷缓冲区同步到磁盘才返回success状态码。这样就可以保证在发生宕机的时候没有事务数据丢失。

用户的操作是一个事务,每个操作NN都要先将操作记录到edits log中,如果给NN指定了多个目录,则在多个目录中都存在edits log文件,用户的操作要在多个目录中都写完成,才让NN同步数据到内存中。当NN在内存中也同步了数据,就返回客户端success。

每个fsimage文件都是系统元数据的一个完整的持久化检查点(checkpoint)(后缀表示镜像中的最后一个事务)。写操作不更新这个数据,因为镜像文件通常为GB数量级,写到磁盘很慢。如果NameNode宕机,可以将最新fsimage加载到内存,同时执行edits log对应于该fsimage之后的操作,就可以重建元数据的状态。而这正是每次启动NameNode的时候NameNode要做的工作。