Hadoop-HDFS的NameNode和SecondaryNameNode介绍及原理
2021/7/1 9:21:18
本文主要是介绍Hadoop-HDFS的NameNode和SecondaryNameNode介绍及原理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
NameNode和SecondaryNameNode
NN和2NN的工作机制
NameNode 中的元数据是存储:
首先,我们做个假设,如果存储在 NameNode 节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了。因此产生在磁盘中备份元数据的FsImage。
这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新 FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦 NameNode 节点断电,就会产生数据丢失。因此,引入 Edits 文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到 Edits 中。这样,一旦 NameNode 节点断电,可以通过 FsImage 和 Edits 的合并,合成元数据。
但是,如果长时间添加数据到 Edits 中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行 FsImage 和 Edits 的合并,如果这个操作由 NameNode 节点完成,又会效率过低。因此,引入一个新的节点 SecondaryNamenode,专门用于 FsImage 和 Edits 的合并。
NN和2NN的工作机制如下:
- 第一阶段: NameNode 启动
(1)第一次启动 NameNode 格式化后,创建 Fsimage 和 Edits 文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求。
(3)NameNode 记录操作日志,更新滚动日志(先更新日志,再进行内存数据的修改)。
(4)NameNode 在内存中对数据进行增删改。
即最新edits+最新fsimage=内存中的数据
- 第二阶段:Secondary NameNode 工作
(1)Secondary NameNode 询问 NameNode 是否需要 CheckPoint,即进行Edits和fsImage的合并(执行检查点的条件:定时时间到了,默认1小时;或Edits中数据满了,默认1百万条)。直接带回 NameNode是否检查结果。
(2)Secondary NameNode 请求执行 CheckPoint。
(3)NameNode 滚动正在写的 Edits 日志。
(4)将滚动前的编辑日志和镜像文件拷贝到 Secondary NameNode。
(5)Secondary NameNode 加载编辑日志和镜像文件到内存,并合并。
(6)生成新的镜像文件 fsimage.chkpoint。
(7)拷贝 fsimage.chkpoint 到 NameNode。
(8)NameNode 将 fsimage.chkpoint 重新命名成 fsimage。
详解如下:
Fsimage:NameNode 内存中元数据序列化后形成的文件。
Edits:记录客户端更新元数据信息的每一步操作(可通过 Edits 运算出元数据)。
NameNode 启动时,先滚动 Edits 并生成一个空的 edits.inprogress,然后加载 Edits 和 Fsimage到内存中,此时 NameNode 内存就持有最新的元数据信息。Client 开始对 NameNode 发送元数据的增删改的请求,这些请求的操作首先会被记录到 edits.inprogress 中(查询元数据的操作不会被记录在 Edits 中,因为查询操作不会更改元数据信息),如果此时 NameNode挂掉,重启后会从 Edits 中读取元数据的信息。然后,NameNode 会在内存中执行元数据的增删改的操作。
由于 Edits 中记录的操作会越来越多, Edits 文件会越来越大,导致 NameNode 在启动加载Edits 时会很慢,所以需要对 Edits 和 Fsimage 进行合并(所谓合并,就是将 Edits 和 Fsimage加 载 到 内 存 中 , 照 着 Edits 中 的 操 作 一 步 步 执 行 , 最 终 形 成 新 的 Fsimage ) 。SecondaryNameNode 的作用就是帮助 NameNode 进行 Edits 和 Fsimage 的合并工作。
SecondaryNameNode 首先会询问 NameNode 是否需要 CheckPoint(触发 CheckPoint 需要满足两个条件中的任意一个,定时时间到和 Edits 中数据写满了)。直接带回 NameNode是否检查结果。SecondaryNameNode 执行 CheckPoint 操作,首先会让 NameNode 滚动 Edits并生成一个空的 edits.inprogress,滚动 Edits 的目的是给 Edits 打个标记,以后所有新的操作都写入 edits.inprogress,其他未合并的 Edits 和 Fsimage 会拷贝到 SecondaryNameNode的本地,然后将拷贝的 Edits 和 Fsimage 加载到内存中进行合并,生成 fsimage.chkpoint,然后将 fsimage.chkpoint 拷贝给 NameNode,重命名为 Fsimage 后替换掉原来的 Fsimage。NameNode 在启动时就只需要加载之前未合并的 Edits 和 Fsimage 即可,因为合并过的Edits 中的元数据信息已经被记录在 Fsimage中。
Fsimage和Edits解析
NN的文件存放路径在:data/tmp/dfs/name/current
2NN的在:data/tmp/dfs/namesecondary/current
NN的目录下存放内容如下:
2NN的如下:
不同之处在于NN多了edits_inprogress文件表示当前记录客户端操作的文件以及seen_txid表示当前edits文件号
直接读取edits操作日志文件和fsimage镜像文件是乱码的,可以通过以下命令进行查看
### 转换fsimage文件,-p表示转换成什么格式,-i表示要查看的文件名 hdfs oiv -p XML -i fsimage文件 -o 转换之后的文件名 ### 转换edits文件 hdfs oev -p XML -i edits文件 -o 转换之后的文件名
为了更好的查看两个文件的内容,将集群初始化。
初始化集群时,要先将集群关闭,然后删除data和logs目录,再到namenode服务器执行初始化nn的操作;最后开启集群。
初始化情况下默认是没有edits文件的,只有编号为0的fsimage文件,待集群启动之后才会生成edits文件。
创建一个目录/sanguo/wei,然后上传一个文件caocao到该目录下。
最新的fsiamge内容如下,并没有看到与创建目录和上传文件有关信息,说明此时还没有进行edits和fsimage的合并
<?xml version="1.0"?> <fsimage> <NameSection> <genstampV1>1000</genstampV1> <genstampV2>1000</genstampV2> <genstampV1Limit>0</genstampV1Limit> <lastAllocatedBlockId>1073741824</lastAllocatedBlockId> <txid>0</txid> </NameSection> <INodeSection> <lastInodeId>16385</lastInodeId> <inode> <id>16385</id> <type>DIRECTORY</type> <name></name> <mtime>0</mtime> <permission>bd:supergroup:rwxr-xr-x</permission> <nsquota>9223372036854775807</nsquota> <dsquota>-1</dsquota> </inode> </INodeSection> <INodeReferenceSection></INodeReferenceSection> <SnapshotSection> <snapshotCounter>0</snapshotCounter> </SnapshotSection> <INodeDirectorySection></INodeDirectorySection> <FileUnderConstructionSection></FileUnderConstructionSection> <SnapshotDiffSection> <diff> <inodeid>16385</inodeid> </diff> </SnapshotDiffSection> <SecretManagerSection> <currentId>0</currentId> <tokenSequenceNumber>0</tokenSequenceNumber> </SecretManagerSection> <CacheManagerSection> <nextDirectiveId>1</nextDirectiveId> </CacheManagerSection> </fsimage>
可以看出,Fsimage 中没有记录块所对应 DataNode,因为在集群启动后,要求 DataNode 上报数据块信息,并间隔一段时间后再次上报。防止静态记录的方式因为DN挂掉之后导致意外的问题,因此需要DN定时动态上报数据块信息。
最新的edits文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <EDITS> <EDITS_VERSION>-63</EDITS_VERSION> <RECORD> <!-- 日志开始 --> <OPCODE>OP_START_LOG_SEGMENT</OPCODE> <DATA> <TXID>3</TXID> </DATA> </RECORD> <RECORD> <!-- 创建/sanguo目录 --> <OPCODE>OP_MKDIR</OPCODE> <DATA> <TXID>4</TXID> <LENGTH>0</LENGTH> <INODEID>16386</INODEID> <PATH>/sanguo</PATH> <TIMESTAMP>1625023339562</TIMESTAMP> <PERMISSION_STATUS> <USERNAME>bd</USERNAME> <GROUPNAME>supergroup</GROUPNAME> <MODE>493</MODE> </PERMISSION_STATUS> </DATA> </RECORD> <RECORD> <!-- 创建/sanguo/wei目录 --> <OPCODE>OP_MKDIR</OPCODE> <DATA> <TXID>5</TXID> <LENGTH>0</LENGTH> <INODEID>16387</INODEID> <PATH>/sanguo/wei</PATH> <TIMESTAMP>1625023339571</TIMESTAMP> <PERMISSION_STATUS> <USERNAME>bd</USERNAME> <GROUPNAME>supergroup</GROUPNAME> <MODE>493</MODE> </PERMISSION_STATUS> </DATA> </RECORD> <RECORD> <!-- 上传文件,此时名称还是xxx.COPYING --> <OPCODE>OP_ADD</OPCODE> <DATA> <TXID>6</TXID> <LENGTH>0</LENGTH> <INODEID>16388</INODEID> <PATH>/sanguo/wei/caocao._COPYING_</PATH> <REPLICATION>3</REPLICATION> <MTIME>1625023365316</MTIME> <ATIME>1625023365316</ATIME> <BLOCKSIZE>134217728</BLOCKSIZE> <CLIENT_NAME>DFSClient_NONMAPREDUCE_-245424670_1</CLIENT_NAME> <CLIENT_MACHINE>10.10.10.113</CLIENT_MACHINE> <OVERWRITE>true</OVERWRITE> <PERMISSION_STATUS> <USERNAME>bd</USERNAME> <GROUPNAME>supergroup</GROUPNAME> <MODE>420</MODE> </PERMISSION_STATUS> <RPC_CLIENTID>f1e13e50-bcba-45fc-b6b1-3d56321921af</RPC_CLIENTID> <RPC_CALLID>3</RPC_CALLID> </DATA> </RECORD> <RECORD> <!-- 分配块id --> <OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE> <DATA> <TXID>7</TXID> <BLOCK_ID>1073741825</BLOCK_ID> </DATA> </RECORD> <RECORD> <!-- 生成时间戳 --> <OPCODE>OP_SET_GENSTAMP_V2</OPCODE> <DATA> <TXID>8</TXID> <GENSTAMPV2>1001</GENSTAMPV2> </DATA> </RECORD> <RECORD> <!-- 添加块信息 --> <OPCODE>OP_ADD_BLOCK</OPCODE> <DATA> <TXID>9</TXID> <PATH>/sanguo/wei/caocao._COPYING_</PATH> <BLOCK> <BLOCK_ID>1073741825</BLOCK_ID> <NUM_BYTES>0</NUM_BYTES> <GENSTAMP>1001</GENSTAMP> </BLOCK> <RPC_CLIENTID></RPC_CLIENTID> <RPC_CALLID>-2</RPC_CALLID> </DATA> </RECORD> <RECORD> <!-- 操作结束 --> <OPCODE>OP_CLOSE</OPCODE> <DATA> <TXID>10</TXID> <LENGTH>0</LENGTH> <INODEID>0</INODEID> <PATH>/sanguo/wei/caocao._COPYING_</PATH> <REPLICATION>3</REPLICATION> <MTIME>1625023366262</MTIME> <ATIME>1625023365316</ATIME> <BLOCKSIZE>134217728</BLOCKSIZE> <CLIENT_NAME></CLIENT_NAME> <CLIENT_MACHINE></CLIENT_MACHINE> <OVERWRITE>false</OVERWRITE> <BLOCK> <BLOCK_ID>1073741825</BLOCK_ID> <NUM_BYTES>15</NUM_BYTES> <GENSTAMP>1001</GENSTAMP> </BLOCK> <PERMISSION_STATUS> <USERNAME>bd</USERNAME> <GROUPNAME>supergroup</GROUPNAME> <MODE>420</MODE> </PERMISSION_STATUS> </DATA> </RECORD> <RECORD> <!-- 重命名COPYING文件 --> <OPCODE>OP_RENAME_OLD</OPCODE> <DATA> <TXID>11</TXID> <LENGTH>0</LENGTH> <SRC>/sanguo/wei/caocao._COPYING_</SRC> <DST>/sanguo/wei/caocao</DST> <TIMESTAMP>1625023366270</TIMESTAMP> <RPC_CLIENTID>f1e13e50-bcba-45fc-b6b1-3d56321921af</RPC_CLIENTID> <RPC_CALLID>9</RPC_CALLID> </DATA> </RECORD> </EDITS>
NN通过seen.txid能够确定下次合并的Edits文件内容。
CheckPoint时间设置
默认情况下,2NN每隔1小时执行一次
<!-- hdfs-default.xml --> <property> <name>dfs.namenode.checkpoint.period</name> <value>3600</value> </property>
默认情况下,一分钟检查一次操作次数,当操作次数达到 1 百万时,2NN 执行一次。
<!-- hdfs-default.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 >
可以通过hdfs-site.xml
进行配置
NameNode故障处理
NameNode 故障后,可以采用如下两种方法恢复数据。
方法一:将 SecondaryNameNode 中数据拷贝到 NameNode 存储数据的目录;
模拟步骤:
1、kill -9 NameNode 进程
2、删除 NameNode 存储的数据(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)
rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*
3、拷贝 SecondaryNameNode 中数据到原 NameNode 存储数据目录
scp -r bd@hadoop115:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* /opt/module/hadoop-2.7.2/data/tmp/dfs/name/
4、重新启动 NameNode
sbin/hadoop-daemon.sh start namenode
方 法 二 : 使 用 -importCheckpoint 选 项 启 动 NameNode 守 护 进 程 , 从 而 将SecondaryNameNode 中数据拷贝到 NameNode 目录中。
模拟步骤:
1、修改 hdfs-site.xml 中的,修改完成之后要使用之前的xsync命令进行配置文件的分发,更新其他服务器上的配置文件
<property> <name>dfs.namenode.checkpoint.period</name> <value>120</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value> </property>
2、kill -9 NameNode 进程
3、删除 NameNode 存储的数据(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)
rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*
4、如果 SecondaryNameNode 不和 NameNode 在一个主机节点上,需要将 SecondaryNameNode 存储数据的目录拷贝到 NameNode 存储数据的平级目录,并删除 in_use.lock 文件
scp -r bd@hadoop115:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary /opt/module/hadoop-2.7.2/data/tmp/dfs ## 删除使用锁文件 rm -rf in_use.lock ## ls /opt/module/hadoop-2.7.2/data/tmp/dfs结果如下: data name namesecondary
5、导入检查点数据(等待一会 ctrl+c 结束掉)
bin/hdfs namenode -importCheckpoint
6、启动 NameNode
sbin/hadoop-daemon.sh start namenode
集群的安全模式
集群处于安全模式,不能执行重要操作(写操作,如上传文件会失败)。集群启动完成后,自动退出安全模式。
## 安全模式相关命令 ### 查看安全模式状态 bin/hdfs dfsadmin -safemode get ### 进入安全模式状态 bin/hdfs dfsadmin -safemode enter ### 离开安全模式状态 bin/hdfs dfsadmin -safemode leave ### 等待安全模式状态 bin/hdfs dfsadmin -safemode wait
等待安全模式状态案例如下:
1、查看当前模式
hdfs dfsadmin -safemode get ## 结果如下: Safe mode is OFF
2、先进入安全模式
bin/hdfs dfsadmin -safemode enter
3、创建并执行下面的脚本
#!/bin/bash ## 等待安全模式 hdfs dfsadmin -safemode wait ## 执行上传操作 hdfs dfs -put /opt/module/hadoop-2.7.2/README.txt /
执行这个脚本的时候会因为等待安全模式导致一直阻塞在那里。
4、退出安全模式
bin/hdfs dfsadmin -safemode leave
此时可以看到之前阻塞在那里的脚本执行完成了,并且打出了Safe mode is OFF
信息,文件也被上传成功了。
NN多目录配置
NameNode 的本地目录可以配置成多个,且每个目录存放内容相同,可以增加可靠性
具体配置如下:
1、先初始化所有的集群:关闭集群、删除logs和data
2、在hdfs-site.xml中增加以下内容,并将配置文件分发到各个服务器上
<property> <name>dfs.namenode.name.dir</name> <value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value> </property>
3、格式化NN(hdfs namenode -format),这里要等配置完成之后再格式化,因为格式化的时候就会读取配置文件去创建NN的目录了
4、启动集群(start-dfs.sh)
5、上传一个文件
hadoop fs -put caocao /caocao
6、查看两个namex目录下的内容,发现两个内容均相同。
这篇关于Hadoop-HDFS的NameNode和SecondaryNameNode介绍及原理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享
- 2024-11-22ansible 的archive 参数是什么意思?-icode9专业技术文章分享
- 2024-11-22ansible 中怎么只用archive 排除某个目录?-icode9专业技术文章分享
- 2024-11-22exclude_path参数是什么作用?-icode9专业技术文章分享
- 2024-11-22微信开放平台第三方平台什么时候调用数据预拉取和数据周期性更新接口?-icode9专业技术文章分享
- 2024-11-22uniapp 实现聊天消息会话的列表功能怎么实现?-icode9专业技术文章分享
- 2024-11-22在Mac系统上将图片中的文字提取出来有哪些方法?-icode9专业技术文章分享
- 2024-11-22excel 表格中怎么固定一行显示不滚动?-icode9专业技术文章分享
- 2024-11-22怎么将 -rwxr-xr-x 修改为 drwxr-xr-x?-icode9专业技术文章分享
- 2024-11-22在Excel中怎么将小数向上取整到最接近的整数?-icode9专业技术文章分享