NN和SNN工作机制

1.NameNode启动
①第一次启动 NameNode 格式化后,创建 fsimage 和 edits 文件。如果不
是第一次启动,直接加载镜像文件和编辑日志到内存。
②客户端对元数据进行增删改的请求。
③NameNode 记录操作日志,更新滚动日志。
④NameNode 在内存中对数据进行增删改查。

2.SecondaryNameNode工作
①Secondary NameNode 询问 NameNode 是否需要 checkpoint。直接带回
NameNode 是否检查结果。
②Secondary NameNode 请求执行 checkpoint。
③NameNode 滚动正在写的 edits 日志。
④将滚动前的编辑日志和镜像文件拷贝到 Secondary NameNode。
⑤Secondary NameNode 加载编辑日志和镜像文件到内存,并合并。
⑥生成新的镜像文件 fsimage.chkpoint。
⑦拷贝 fsimage.chkpoint 到 NameNode。
⑧NameNode 将 fsimage.chkpoint 重新命名成 fsimage。

Fsimage 和 Edits 解析

1.概念:
NameNode 被格式化之后,将在
/opt/soft/hadoop260/data/tmp/dfs/name/current 目录中产生如下文件:

edits_0000000000000000000
fsimage_0000000000000000000.md5
seen_txid
VERSION

Fsimage 文件:HDFS 文件系统元数据的一个永久性的检查点,其中包含 HDFS
文件系统的所有目录和文件 idnode 的序列化信息。

Edits 文件:存放 HDFS 文件系统的所有更新操作的路径,文件系统客户端
执行的所有写操作首先会被记录到 edits 文件中。

seen_txid 文件:保存的是一个数字,就是最后一个 edits_的数字

步骤详解:每次 NameNode 启动的时候都会将 fsimage 文件读入内存,并从 00001 开始
到 seen_txid 中记录的数字依次执行每个 edits 里面的更新操作,保证内存中的
元数据信息是最新的、同步的,可以看成 NameNode 启动的时候就将 fsimage 和
edits 文件进行了合并。

2.使用 oiv 查看 fsimage 文件
①查看oiv命令

[hadoop@lyx2 current]$ hdfs oiv

②基本语法
hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径

③操作案例

[hadoop@lyx2 current]$ hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/soft/hadoop260/fsimage.xml
[hadoop@lyx2 current]$ cat /opt/install/hadoop/fsimage.xml

将显示的 xml 文件内容拷贝到 idea 中创建的 xml 文件中,并格式化。部分
显示结果如下。注意:id,name 等属性与自己环境一致

<inode>
<id>15387</id>
<type>DIRECTORY</type>
<name>user</name>
<mtime>1512722284477</mtime>
<permission>kgc:supergroup:rwxr-xr-x</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16387</id>
<type>DIRECTORY</type>
<name>hadoop</name>
<mtime>1512790549080</mtime>
<permission>hadoop:supergroup:rwxr-xr-x</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>15388</id>
<type>FILE</type>
<name>wc.input</name>
<replication>3</replication>
<mtime>1512722322219</mtime>
<atime>1512722321610</atime>
<perferredBlockSize>134217728</perferredBlockSize>
<permission>kgc:supergroup:rw-r--r--</permission>
<blocks>
<block>
<id>1073741825</id>
<genstamp>1001</genstamp>
<numBytes>59</numBytes>
</block>
</blocks>
</inode>

3.oev 查看 edits 文件
①基本语法
hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径
②操作案例

[hadoop@lyx2 current]$ hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/soft/hadoop260/edits.xml
[hadoop@lyx2 current]$ cat /opt/soft/hadoop260/edits.xml

将显示的 xml 文件内容拷贝到 idea 中创建的 xml 文件中,并格式化。显示
结果如下:

<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
<EDITS_VERSION>-63</EDITS_VERSION>
<RECORD>
<OPCODE>OP_START_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>129</TXID>
</DATA>
</RECORD>
<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.5</CLIENT_MACHINE>
<OVERWRITE>true</OVERWRITE>
<PERMISSION_STATUS>
<USERNAME>hadoop</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
<RPC_CLIENTID>908eafd4-9aec-4288-96f1-e8011d181561</RPC_CL
IENTID>
<RPC_CALLID>0</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>131</TXID>
<BLOCK_ID>1073741838</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>132</TXID>
<GENSTAMPV2>1016</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>133</TXID>
<PATH>/hello7.txt</PATH>
<BLOCK>
<BLOCK_ID>1073741838</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1016</GENSTAMP>
</BLOCK>
<RPC_CLIENTID></RPC_CLIENTID>
<RPC_CALLID>-2</RPC_CALLID>
</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>kgc</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
</EDITS>

4.checkpoint 时间设置
SecondaryNameNode 执行时机有两种控制方式,如下:
①通常情况下,SecondaryNameNode 每隔一小时执行一次。属性配置在
[hdfs-default.xml],可以自己在 hdfs-site.xml 中添加对应属性进行自定义配置。

<property>
 <name>dfs.namenode.checkpoint.period</name>
 <value>3600</value>
</property>

②一分钟检查一次操作次数,当操作次数达到 1 百万时,SecondaryNameNode
执行一次。可以自己在 hdfs-site.xml 中添加对应属性进行自定义配置。

<property>
 <name>dfs.namenode.checkpoint.txns</name>
 <value>1000000</value>
<description>操作动作次数</description>
</property>
<property>
 <name>dfs.namenode.checkpoint.check.period</name>
 <value>60</value>
<description> 1 分钟检查一次操作次数</description>
</property>

5.NameNode 故障处理
NameNode 故障后,可以采用如下两种方法恢复数据:
①将 SecondaryNameNode 中数据拷贝到 NameNode 存储数据的目录。
(1)kill -9 namenode 进程。
(2)删除 NameNode 存储的数据(/opt/soft/hadoop260/data/tmp/dfs/name)

[hadoop@lyx2 hadoop]$ rm -rf opt/soft/hadoop260/data/tmp/dfs/name/*

(3)拷贝 SecondaryNameNode 中数据到原 NameNode 存储数据目录。
如果是集群模式,集群环境中NameNode在hadoop102机器上,SecondaryNameNode在hadoop104
上。

[hadoop@lyx2 dfs]$ scp -r hadoop@lyx104:/opt/soft/hadoop260/data/tmp/dfs/namesecondary/* ./name/

(4)重新启动 namenode

[hadoop@lyx2 hadoop]$ sbin/hadoop-daemon.sh start namenode

②使用-importCheckpoint 选项启动 NameNode 守护进程,从而将
SecondaryNameNode 中数据拷贝到 NameNode 目录中
(1)修改 hdfs-site.xml

<property>
 <name>dfs.namenode.checkpoint.period</name>
 <value>120</value>
</property>
<property>
 <name>dfs.namenode.name.dir</name>
 <value>/opt/install/hadoop/data/tmp/dfs/name</value>
</property>

(2)kill -9 namenode 进程
(3)删除 NameNode 存储的数据(/opt/soft/hadoop260/data/tmp/dfs/name)

[hadoop@lyx2 hadoop]$ rm -rf opt/soft/hadoop260/data/tmp/dfs/name/*

(4)如果 SecondaryNameNode 不和 NameNode 在一个主机节点上,需要将
SecondaryNameNode 存储数据的目录拷贝到 NameNode 存储数据的平级目录,并
删除 in_use.lock 文件

[hadoop@lyx2 dfs]$ scp -r hadoop@lyx4:/opt/soft/hadoop260/data/tmp/dfs/namesecondary ./
[hadoop@lyx2 namesecondary]$ rm -rf in_use.lock

(5)导入检查点数据(等待一会 ctrl+c 结束掉)

[hadoop@lyx2 hadoop]$ bin/hdfs namenode -importCheckpoint

(6)启动 namenode

[hadoop@lyx2 hadoop]$ sbin/hadoop-daemon.sh start namenode

6.集群安全模式
①概念:
(1)NameNode 启动时,首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。一旦在内存中成功建立文件系统元数据的映像,则创建一个新的 fsimage 文件和一个空的编辑日志。此时,NameNode 开始监听DataNode 请求。但是此刻,NameNode安模式,即 NameNode 的文件系统对于客户端来说是只读的。
(2)系统中的数据块的位置并不是由 NameNode 维护的,而是以块列表的形式存储在 DataNode 中。在系统的正常操作期间,NameNode 在内存中保留所有块位置的映射信息。在安全模式下,各个 DataNode 会向 NameNode 发送最新的块列表信息,NameNode 了解到足够多的块位置信息之后,即可高效运行文件系统。
(3)如果满足“最小副本条件”,NameNode 会在 30 秒钟之后就退出安全模式。所谓的最小副本条件指的是在整个文件系统中 99.9%的块满最小副本级别(默认值:dfs.replication.min=1)。在启动一个刚刚格式化的 HDFS 集群时,因为系统中还没有任何块,所以 NameNode 不会进入安全模式。

②基本语法
集群处于安全模式,不能执行重要操作(写操作)。集群启动完成后,自动退出安全模式
(1)bin/hdfs dfsadmin -safemode get (查看安全模式状态)
(2)bin/hdfs dfsadmin -safemode enter (进入安全模式状态)
(3)bin/hdfs dfsadmin -safemode leave (离开安全模式状态)
(4)bin/hdfs dfsadmin -safemode wait (等待安全模式状态)

③如何设置自动离开安全模式
修改hdfs-site.xml文件来设置安全阈值,添加一段代码

<property>
		<name>dfs.safemode.threshold.pct</name>
 		 <value>0.999f</value>   //设置安全阈值=0.999f(数据块中满足replication设置值的数据块的数量在总数据块数量中所占比例超过一定值),让集群默认离开安全模式
</property>