HDFS元数据管理机制
问题1:NameNode如何管理和存储元数据?
计算机中存储数据两种:内存或者是磁盘
元数据存储磁盘:存储磁盘无法面对客户端对元数据信息的任意的快速低延迟的响应,但是安全性高
元数据存储内存:元数据存放内存,可以高效的查询以及快速响应客户端的查询请求,数据保存在内
存,如果断点,内存中的数据全部丢失。
解决方案:内存+磁盘;NameNode内存+FsImage的文件(磁盘)
新问题:磁盘和内存中元数据如何划分
两个数据一模一样,还是两个数据合并到一起才是一份完整的数据呢?
一模一样:client如果对元数据进行增删改操作,需要保证两个数据的一致性。FsImage文件操作起来
效率也不高。
两个合并=完整数据:NameNode引入了一个edits文件(日志文件:只能追加写入)edits文件记录的
是client的增删改操作,
不再选择让NameNode把数据dump出来形成FsImage文件(这种操作是比较消耗资源)。
NameNode在执行格式化之后,会在/opt/lagou/servers/hadoop-2.9.2/data/tmp/dfs/name/current
目录下产生如下文件
Fsimage文件:是namenode中关于元数据的镜像,一般称为检查点,这里包含了HDFS文件系统所有目录以及文件相关信息(Block数量,副本数量,权限等信息)
Edits文件 :存储了客户端对HDFS文件系统所有的更新操作记录,Client对HDFS文件系统所有的更新操作都会被记录到Edits文件中(不包括查询操作)
seen_txid:该文件是保存了一个数字,数字对应着最后一个Edits文件名的数字
VERSION:该文件记录namenode的一些版本号信息,比如:CusterId,namespaceID等
https://hadoop.apache.org/docs/r2.9.2/hadoop-project-dist/hadoophdfs/HdfsImageViewer.html
查看oiv和oev命令
[root@linux121 current]$ hdfs
oiv Offline Image Viewer View a Hadoop fsimage INPUTFILE using the specified
PROCESSOR,saving the results in OUTPUTFILE.
oev Offline edits viewer Parse a Hadoop edits log file INPUT_FILE and save results in
OUTPUT_FILE
基本语法
hdfs oiv -p 文件类型(xml) -i 镜像文件 -o 转换后文件输出路径
[root@linux121 current]$ cd /opt/lagou/servers/hadoop-
2.9.2/data/tmp/dfs/name/current
[root@linux121 current]$ hdfs oiv -p XML -i fsimage_0000000000000000265 -o
/opt/lagou/servers/fsimage.xml
[root@linux121 current]$ cat /opt/lagou/servers/fsimage.xml
<fsimage>
<version>
<layoutVersion>-63layoutVersion>
<onDiskVersion>1onDiskVersion>
<oivRevision>826afbeae31ca687bc2f8471dc841b66ed2c6704oivRevision>
version>
<NameSection>
<namespaceId>1393381414namespaceId>
<genstampV1>1000genstampV1>
<genstampV2>1024genstampV2>
<genstampV1Limit>0genstampV1Limit>
<lastAllocatedBlockId>1073741848lastAllocatedBlockId>
<txid>265txid>
NameSection>
<INodeSection>
<inode>
<id>16398id>
<type>DIRECTORYtype>
<name>historyname>
<mtime>1592376391028mtime>
<permission>root:supergroup:0777permission>
<nsquota>-1nsquota>
<dsquota>-1dsquota>
inode>
<inode>
<id>16399id>
<type>DIRECTORYtype>
<name>done_intermediatename>
<mtime>1592375256896mtime>
<permission>root:supergroup:1777permission>
<nsquota>-1nsquota>
<dsquota>-1dsquota>
inode>
<inode>
<id>16400id>
<type>DIRECTORYtype>
<name>rootname>
<mtime>1592378079208mtime>
<permission>root:supergroup:0777permission>
<nsquota>-1nsquota>
<dsquota>-1dsquota>
inode>
<inode>
<id>16413id>
<type>FILEtype>
<name>job_1592375222804_0001-1592375231176-root-word+count-
1592375281926-1-1-SUCCEEDED-default-1592375261492.jhistname>
<replication>3replication>
<mtime>1592375282039mtime>
<atime>1592375281980atime>
<preferredBlockSize>134217728preferredBlockSize>
<permission>root:supergroup:0777permission>
<blocks>
<block>
<id>1073741834id>
<genstamp>1010genstamp>
<numBytes>33584numBytes>
block>
blocks>
<storagePolicyId>0storagePolicyId>
inode>
<inode>
<id>16414id>
<type>FILEtype>
<name>job_1592375222804_0001_conf.xmlname>
<replication>3replication>
<mtime>1592375282121mtime>
<atime>1592375282053atime>
<preferredBlockSize>134217728preferredBlockSize>
<permission>root:supergroup:0777permission>
<blocks>
<block>
<id>1073741835id>
<genstamp>1011genstamp>
<numBytes>196027numBytes>
block>
blocks>
<storagePolicyId>0storagePolicyId>
inode>
<inode>
<id>16415id>
<type>DIRECTORYtype>
<name>donename>
<mtime>1592376776670mtime>
<permission>root:supergroup:0777permission>
<nsquota>-1nsquota>
<dsquota>-1dsquota>
inode>
<inode>
<id>16427id>
<type>DIRECTORYtype>
<name>logsname>
<mtime>1592378009623mtime>
<permission>root:root:0770permission>
<nsquota>-1nsquota><dsquota>-1dsquota>
inode>
<inode>
<id>16428id>
<type>DIRECTORYtype>
<name>application_1592376944601_0001name>
<mtime>1592378045481mtime>
<permission>root:root:0770permission>
<nsquota>-1nsquota>
<dsquota>-1dsquota>
inode>
<inode>
<id>16430id>
<type>DIRECTORYtype>
<name>wcoutputname>
<mtime>1592378037463mtime>
<permission>root:supergroup:0755permission>
<nsquota>-1nsquota>
<dsquota>-1dsquota>
inode>
<inode>
<id>16436id>
<type>FILEtype>
<name>part-r-00000name>
<replication>3replication>
<mtime>1592378037264mtime>
<atime>1592378037074atime>
<preferredBlockSize>134217728preferredBlockSize>
<permission>root:supergroup:0644permission>
<blocks>
<block>
<id>1073741842id>
<genstamp>1018genstamp>
<numBytes>43numBytes>
block>
blocks>
<storagePolicyId>0storagePolicyId>
inode>
<inode>
<id>16445id>
<type>FILEtype>
<name>linux123_39919name>
<replication>3replication>
<mtime>1592378045469mtime>
<atime>1592378045331atime>
<preferredBlockSize>134217728preferredBlockSize>
<permission>root:root:0640permission>
<blocks>
<block>
<id>1073741848id>
<genstamp>1024genstamp>
<numBytes>56910numBytes>
block>
blocks>
<storagePolicyId>0storagePolicyId>
inode>
<inode>
<id>16446id>
<type>DIRECTORYtype>
<name>0617name>
<mtime>1592387393490mtime>
<permission>root:supergroup:0755permission>
<nsquota>-1nsquota>
<dsquota>-1dsquota>
inode>
<inode>
<id>16449id>
<type>FILEtype>
<name>banzhang.txtname>
<replication>1replication>
<mtime>1592388309046mtime>
<atime>1592388309026atime>
<preferredBlockSize>134217728preferredBlockSize>
<permission>root:supergroup:0644permission>
<storagePolicyId>0storagePolicyId>
inode>
INodeSection>
fsimage>
问题:Fsimage中为什么没有记录块所对应DataNode?
在内存元数据中是有记录块所对应的dn信息,但是fsimage中就剔除了这个信息;HDFS集群在启动的
时候会加载image以及edits文件,block对应的dn信息都没有记录,集群启动时会有一个安全模式
(safemode),安全模式就是为了让dn汇报自己当前所持有的block信息给nn来补全元数据。后续每隔
一段时间dn都要汇报自己持有的block信息
[root@linux121 current]$ hdfs oev -p XML -i edits_0000000000000000266-
0000000000000000267 -o /opt/lagou/servers/hadoop-2.9.2/edits.xml
[root@linux121 current]$ cat /opt/lagou/servers/hadoop-2.9.2/edits.xml
<EDITS>
<EDITS_VERSION>-63EDITS_VERSION>
<RECORD>
<OPCODE>OP_START_LOG_SEGMENTOPCODE>
<DATA>
<TXID>113TXID>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>114TXID>
<SRC>/wcoutput/_SUCCESSSRC>
<MODE>493MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>115TXID>
<SRC>/wcoutput/part-r-00000SRC>
<MODE>493MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>116TXID>
<SRC>/wcoutputSRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>117TXID>
<SRC>/wcoutput/_SUCCESSSRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>118TXID>
<SRC>/wcoutput/part-r-00000SRC>
<MODE>511MODE>
DATA>
RECORD>
<OPCODE>OP_DELETEOPCODE>
<DATA>
<TXID>119TXID>
<LENGTH>0LENGTH>
<PATH>/wcoutput/part-r-00000PATH>
<TIMESTAMP>1592377324171TIMESTAMP>
<RPC_CLIENTID>RPC_CLIENTID>
<RPC_CALLID>-2RPC_CALLID>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>120TXID>
<SRC>/SRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>121TXID>
<SRC>/tmpSRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>122TXID>
<SRC>/tmp/hadoop-yarnSRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>123TXID>
<SRC>/tmp/hadoop-yarn/stagingSRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>124TXID>
<SRC>/tmp/hadoop-yarn/staging/historySRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>125TXID>
<SRC>/tmp/hadoop-yarn/staging/history/doneSRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
<OPCODE>OP_SET_PERMISSIONSOPCODE>
<DATA>
<TXID>126TXID>
<SRC>/tmp/hadoop-yarn/staging/history/done/2020SRC>
<MODE>511MODE>
DATA>
RECORD>
<RECORD>
备注:Edits中只记录了更新相关的操作,查询或者下载文件并不会记录在内!!
问题:NameNode启动时如何确定加载哪些Edits文件呢?
nn启动时需要加载fsimage文件以及那些没有被2nn进行合并的edits文件,nn如何判断哪些edits已经
被合并了呢?
可以通过fsimage文件自身的编号来确定哪些已经被合并
[hdfs-default.xml]
<property>
<name>dfs.namenode.checkpoint.periodname>
<value>3600value>
property>
<property>
<name>dfs.namenode.checkpoint.txnsname>
<value>1000000value>
<description>操作动作次数description>
property>
<property>
<name>dfs.namenode.checkpoint.check.periodname>
<value>60value>
<description> 1分钟检查一次操作次数description>
property >
NameNode故障后,HDFS集群就无法正常工作,因为HDFS文件系统的元数据需要由NameNode来管
理维护并与Client交互,如果元数据出现损坏和丢失同样会导致NameNode无法正常工作进而HDFS文
件系统无法正常对外提供服务。
如果元数据出现丢失损坏如何恢复呢?
高级命令
HDFS文件限额配置
HDFS文件的限额配置允许我们以文件大小或者文件个数来限制我们在某个目录下上传的文件数量
或者文件内容总量,以便达到我们类似百度网盘网盘等限制每个用户允许上传的最大的文件的量
hdfs dfs -mkdir -p /user/root/lagou #创建hdfs文件夹
hdfs dfsadmin -setQuota 2 /user/root/lagou # 给该文件夹下面设置最多上传两
个文件,上传文件,发现只能上传一个文件
hdfs dfsadmin -clrQuota /user/root/lagou # 清除文件数量限制
hdfs dfsadmin -setSpaceQuota 4k /user/root/lagou # 限制空间大小4KB
#上传超过4Kb的文件大小上去提示文件超过限额
hdfs dfs -put /export/softwares/xxx.tar.gz /user/root/lagou
hdfs dfsadmin -clrSpaceQuota /user/root/lagou #清除空间限额
#查看hdfs文件限额数量
hdfs dfs -count -q -h /user/root/lagou
安全模式是HDFS所处的一种特殊状态,在这种状态下,文件系统只接受读数据请求,而不接
受删除、修改等变更请求。在NameNode主节点启动时,HDFS首先进入安全模式,DataNode在
启动的时候会向NameNode汇报可用的block等状态,当整个系统达到安全标准时,HDFS自动离
开安全模式。如果HDFS出于安全模式下,则文件block不能进行任何的副本复制操作,因此达到
最小的副本数量要求是基于DataNode启动时的状态来判定的,启动时不会再做任何复制(从而达
到最小副本数量要求),HDFS集群刚启动的时候,默认30S钟的时间是出于安全期的,只有过了
30S之后,集群脱离了安全期,然后才可以对集群进行操作
hdfs dfsadmin -safemode
主要解决HDFS集群存在大量小文件的问题!!
由于大量小文件会占用NameNode的内存,因此对于HDFS来说存储大量小文件造成NameNode
内存资源的浪费!
Hadoop存档文件HAR文件,是一个更高效的文件存档工具,HAR文件是由一组文件通过archive
工具创建而来,在减少了NameNode的内存使用的同时,可以对文件进行透明的访问,通俗来说
就是HAR文件对NameNode来说是一个文件减少了内存的浪费,对于实际操作处理文件依然是一
个一个独立的文件。
start-yarn.sh
bin/hadoop archive -archiveName input.har –p
/user/root/input /user/root/output
[root@linux121 hadoop-2.9.2]$ hadoop fs -lsr /user/root/output/input.har
[root@linux121 hadoop-2.9.2]$ hadoop fs -lsrhar:///user/root/output/input.har
[root@linux121 hadoop-2.9.2]$ hadoop fs -cp har:/// user/root/output/input.har/* /user/root