1.NN和2NN的工作机制
思考:Namenode中的元数据存储在哪里的
解:元数据存储在内存中,但如果只存在内存中,一旦断电,元数据丢失,集群无法工作,因此产生了在磁盘中备份元数据
的Fsimage,当内存中元数据需要更新时,同时又要更新Fsimage,导致效率低下,如果不更新,就会发生一致性问题,一旦
namenode节点断电,就会产生元数据丢失,因此产生了edits文件(只进行追加操作,效率高),当元数据需要更新或者添加
元数据时,可以在内存中修改并追加带edits文件中,这样一旦namenode节点断电,只需将Fsimage与edits合并,合成元数
据,但是如果长时间添加数据带edits中,会导致文件数据过大,效率低,而且一旦namenode断电,恢复元数据时间比较长,
因此引入了一个新的节点secondaryNamenode,专门用于Fsimage和Edits的合并
1.第一阶段:Namenode启动
(1)第一次启动NameNode格式化后,创建Fsimage和Edits文件,如果不是第一次启动,直接加载编辑日志和镜像文件到内存中
(2)客户端对元数据进行增删改的请求
(3)NameNode记录操作日志到edits,更新滚动日志到内存
(4)NameNode在内存中队员数据进行增删改操作
2.第二阶段:secondaryNameNode启动
(1)secondaryNameNode询问Namenode是否需要CheckPoint,直接带回Namenode是否检查的结果
(2)secondaryNameNode请求执行CheckPoint
(3)Namenode滚动正在写的编辑日志
(4)将滚定前的编辑日志和镜像文件拷贝到secondaryNameNode
(5)secondaryNameNode将编辑日志和镜像文件加载到内存中,并合并
(6)生成新的镜像文件夹Fsimage.CheckPoint
(7)Fsimage.CheckPoint拷贝到Namenode中
(8)Namenode将拷贝的镜像文件Fsimage.CheckPoint重命名为fsimage
2) Fsimage和edits解析
1.概念
Fsimage和Edits概念:
namenode被格式化后,将在/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current目录中产生如下文件
fsimage_0000000000000000000
fsimage_0000000000000000000.md5
seen_txid
VERSION
(1)fsimage文件:HDFS文件系统元数据的一个永久性的检查点,其中包含HDFS文件系统的所有目录和文件inode序列化信息
(2)edits文件:存放HDFS文件系统的所有更新操作的路径,文件系统客户端执行所有写操作首先会被记录到edits中
(3)seen_txid:文件保存的是一个数字,就是最后一个edits_的数字
(4)每次Namenode启动的时候都将Fsimage文件读入内存,加载edits里面的更新操作,保证内存中的元数据信息是最新、
同步的, 可以看成Namenode启动的时候就将Fsimage和Edits文件进行合并
2.oiv查看Fsimage文件
(1)查看oiv和oev命令
[[email protected] current]$ hdfs
oiv apply the offline fsimage viewer to an fsimage //查看fsimage
oev apply the offline edits viewer to an edits file //查看edits
(2)基本语法
hdfs oiv -p 文件类型 -i镜像文件 -o 转换后文件输出路径
(3)案例实操
[[email protected] current]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs/name1/current
[[email protected] current]$ hdfs oiv -p XML -i fsimage_0000000000000000232 -o fs.xml
[[email protected] current]$ cat fs.xml
将内容复制到eclipse中打开并整理格式快捷键ctrl+a+i
<?xml version="1.0"?>
<fsimage>
<NameSection>
<genstampV1>1000</genstampV1>
<genstampV2>1001</genstampV2>
<genstampV1Limit>0</genstampV1Limit>
<lastAllocatedBlockId>1073741825</lastAllocatedBlockId>
<txid>232</txid>
</NameSection>
<INodeSection>
<lastInodeId>16386</lastInodeId>
<inode>
<id>16385</id>
<type>DIRECTORY</type>
<name></name>
<mtime>1581934515166</mtime>
<permission>atguigu:supergroup:rwxr-xr-x</permission>
<nsquota>9223372036854775807</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16386</id>
<type>FILE</type>
<name>README.txt</name>
<replication>4</replication>
<mtime>1581934515159</mtime>
<atime>1581934514575</atime>
<perferredBlockSize>134217728</perferredBlockSize>
<permission>atguigu:supergroup:rw-r--r--</permission>
<blocks>
<block>
<id>1073741825</id>
<genstamp>1001</genstamp>
<numBytes>1366</numBytes>
</block>
</blocks>
</inode>
</INodeSection>
<INodeReferenceSection></INodeReferenceSection>
<SnapshotSection>
<snapshotCounter>0</snapshotCounter>
</SnapshotSection>
<INodeDirectorySection>
<directory>
<parent>16385</parent>
<inode>16386</inode>
</directory>
</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上报数据块信息,并间隔一段时间后再次上报。
3.oev查看Edits文件
(1)基本语法
hdfs oev -p 文件类型 -i编辑日志 -o 转换后文件输出路径
(2)案例实操
[[email protected] current]$ hdfs oev -p XML -i edits_0000000000000000231-0000000000000000232 -o ed.xml
[[email protected] current]$ hdfs oev -p XML -i edits_inprogress_0000000000000000233 -o edits.xml
将内容复制到eclipse中打开并整理格式快捷键ctrl+a+i
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>263</TXID>
<GENSTAMPV2>1005</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>264</TXID>
<PATH>/user/atguigu/logs/hadoop-atguigu-datanode-hadoop109.log._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741829</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1005</GENSTAMP>
</BLOCK>
<RPC_CLIENTID></RPC_CLIENTID>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_CLOSE</OPCODE>
<DATA>
<TXID>265</TXID>
<LENGTH>0</LENGTH>
<INODEID>0</INODEID>
<PATH>/user/atguigu/logs/hadoop-atguigu-datanode-hadoop109.log._COPYING_</PATH>
<REPLICATION>4</REPLICATION>
<MTIME>1581951089760</MTIME>
<ATIME>1581951089606</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME></CLIENT_NAME>
<CLIENT_MACHINE></CLIENT_MACHINE>
<OVERWRITE>false</OVERWRITE>
<BLOCK>
<BLOCK_ID>1073741829</BLOCK_ID>
<NUM_BYTES>26806</NUM_BYTES>
<GENSTAMP>1005</GENSTAMP>
</BLOCK>
<PERMISSION_STATUS>
<USERNAME>atguigu</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_RENAME_OLD</OPCODE>
<DATA>
<TXID>266</TXID>
<LENGTH>0</LENGTH>
<SRC>/user/atguigu/logs/hadoop-atguigu-datanode-hadoop109.log._COPYING_</SRC>
<DST>/user/atguigu/logs/hadoop-atguigu-datanode-hadoop109.log</DST>
<TIMESTAMP>1581951089762</TIMESTAMP>
<RPC_CLIENTID>fa2bd490-ab32-4300-a67e-1ac775a61b75</RPC_CLIENTID>
<RPC_CALLID>18</RPC_CALLID>
</DATA>
</RECORD>
Namenode如何确定下次开机启动的时候合并哪些edits
根据seen_txid的数值
3.CheckPoint时间设置
(1)通常情况下,SecondaryNameNode每隔一小时执行一次。
[hdfs-default.xml]
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
(2)一分钟检查一次操作次数,3当操作次数达到1百万时,SecondaryNameNode执行一次。
<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 >
4.NameNode故障处理
方法一:将SecondaryNameNode中数据拷贝到NameNode存储数据的目录;
1. kill -9 NameNode进程
2. 删除NameNode存储的数据(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)
[[email protected] hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*
3. 拷贝SecondaryNameNode中数据到原NameNode存储数据目录
[[email protected] dfs]$ scp -r [email protected]:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./name/
4. 重新启动NameNode
[atguig[email protected] hadoop-2.7.2]$ 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/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)
[[email protected] hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*
4. 如果SecondaryNameNode不和NameNode在一个主机节点上,需要将SecondaryNameNode存储数据的目录拷贝到NameNode存储数据的平级目录,并删除in_use.lock文件
[[email protected] dfs]$ scp -r [email protected]:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary ./
[[email protected] namesecondary]$ rm -rf in_use.lock
[[email protected] dfs]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs
[[email protected] dfs]$ ls
data name namesecondary
5. 导入检查点数据(等待一会ctrl+c结束掉)
[[email protected] hadoop-2.7.2]$ bin/hdfs namenode -importCheckpoint
6. 启动NameNode
[atguig[email protected] hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode
5)集群安全模式
1.概念
a.namenode启动
namenode启动时,首先将Fsimage载入内存,并执行edits中的各种操作,一旦在内存中成功建立文件系统元数据的映像,
则创建一个新的Fsimage文件和一个空的编辑日志。此时,namenode开始监听Datanodo请求,这个过程期间,
namnode一直运行在安全模式中,即namenode的文件系统对于客户端来说是只读的
b.Datanode启动
系统中的数据块的位置并不是由namenode维护的,而是以块的形式存储在Datanode中,在系统的正常操作期间,
namenode会在内存中保留所在块位置的映射信息,在安全模式下,各个datanode回想namenode发送最新的块列表信息,
namenode了解到足够多的块信息之后,即可高效运行文件系统
c.安全模式退出判断
如果满足“最小副本条件”,namenode会在30s之后就退出安全模式,
最小副本条件指在整个文件系统中99.9%的块满足最小副本级别(默认值:dfs.replication.min=1)
在启动一个刚刚格式化的HDFS集群时,因为系统中还没有任何块,所以namenode不会进入安全模式
2. 基本语法
集群处于安全模式,不能执行重要操作(写操作)。集群启动完成后,自动退出安全模式。
(1)bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式状态)
(2)bin/hdfs dfsadmin -safemode enter (功能描述:进入安全模式状态)
(3)bin/hdfs dfsadmin -safemode leave (功能描述:离开安全模式状态)
(4)bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式状态)
3. 案例
模拟等待安全模式
(1)查看当前模式
[[email protected] hadoop-2.7.2]$ hdfs dfsadmin -safemode get
Safe mode is OFF
(2)先进入安全模式
[[email protected] hadoop-2.7.2]$ bin/hdfs dfsadmin -safemode enter
(3)创建并执行下面的脚本
在/opt/module/hadoop-2.7.2路径上,编辑一个脚本safemode.sh
[[email protected] hadoop-2.7.2]$ touch safemode.sh
[[email protected] hadoop-2.7.2]$ vim safemode.sh
#!/bin/bash
hdfs dfsadmin -safemode wait
hdfs dfs -put /opt/module/hadoop-2.7.2/README.txt /
[[email protected] hadoop-2.7.2]$ chmod 777 safemode.sh
[[email protected] hadoop-2.7.2]$ ./safemode.sh
(4)再打开一个窗口,执行
[[email protected] hadoop-2.7.2]$ bin/hdfs dfsadmin -safemode leave
(5)观察
(a)再观察上一个窗口
Safe mode is OFF
(b)HDFS集群上已经有上传的数据了。
6.NameNode多目录配置
1. NameNode的本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性
2. 具体配置如下
(1)在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>
(2)停止集群,删除data和logs中所有数据。
[[email protected] op-2.7.2]$ rm -rf data/ logs/
[[email protected]]$ rm -rf data/ logs/
[[email protected]]$ rm -rf data/ logs/
(3)格式化集群并启动。
[[email protected]]$ bin/hdfs namenode –format
[[email protected]]$ sbin/start-dfs.sh
(4)查看结果
[[email protected] dfs]$ ll
总用量 12
drwx------. 3 atguigu atguigu 4096 12月 11 08:03 data
drwxrwxr-x. 3 atguigu atguigu 4096 12月 11 08:03 name1
drwxrwxr-x. 3 atguigu atguigu 4096 12月 11 08:03 name2