一、HDFS体系结构

HDFS支持主从结构,主节点称为 NameNode ,是因为主节点上运行的有NameNode进程,NameNode支持多个。从节点称为 DataNode ,是因为从节点上面运行的有DataNode进程,DataNode支持多个。HDFS中还包含一个 SecondaryNameNode 进程,这个进程从字面意思上看像是第二个NameNode的意思,其实不是。

在这大家可以这样理解:

公司BOSS:NameNode

秘书:SecondaryNameNode

员工:DataNode

接着看一下这张图,这就是HDFS的体系结构,这里面的TCP、RPC、HTTP表示是不同的网络通信方式,通过这张图是想加深大家对HDFS体系结构的理解。

hadoop namenode datanode hadoop namenode datanode 域名解析_上传

二、NameNode介绍

首先是NameNode,NameNode是整个文件系统的管理节点

它主要维护着整个文件系统的文件目录树,文件/目录的信息 和 每个文件对应的数据块列表,并且还负责接收用户的操作请求

  • 目录树:表示目录之间的层级关系,就是我们在hdfs上执行ls命令可以看到的那个目录结构信息。
  • 文件/目录的信息:表示文件/目录的的一些基本信息,所有者 属组 修改时间 文件大小等信息。
  • 每个文件对应的数据块列表:如果一个文件太大,那么在集群中存储的时候会对文件进行切割,这个时候就类似于会给文件分成一块一块的,存储到不同机器上面。所以HDFS还要记录一下一个文件到底被分了多少块,每一块都在什么地方存储

hadoop namenode datanode hadoop namenode datanode 域名解析_hdfs_02

  • 接收用户的操作请求:其实我们在命令行使用hdfs操作的时候,是需要先和namenode通信 才能开始去操作数据的。

为什么呢?因为文件信息都在namenode上面存储着的,namenode是非常重要的,它的这些信息最终是会存储到文件上的,那接下来我们来看一下NameNode中包含的那些文件。

NameNode主要包括以下文件:

hadoop namenode datanode hadoop namenode datanode 域名解析_上传_03

 这些文件所在的路径是由hdfs-default.xml的dfs.namenode.name.dir属性控制的

hdfs-default.xml文件在哪呢?

我使用的是HDP,它在/usr/hdp/2.6.5.0-292/hadoop-hdfs/hadoop-hdfs-2.7.3.2.6.5.0-292.jar,这个文件中包含了HDFS相关的所有默认参数,咱们在配置集群的时候会修改一个hdfs-site.xml文件(位置/usr/hdp/2.6.5.0-292/hadoop/conf),hdfs-site.xml文件属于hdfs-default.xml的一个扩展,它可以覆盖掉hdfs-default.xml中同名的参数。

那我们来看一下这个文件中的dfs.namenode.name.dir属性

hadoop namenode datanode hadoop namenode datanode 域名解析_hdfs_04

 进入到/data1/hadoop/hdfs/namenode目录下

hadoop namenode datanode hadoop namenode datanode 域名解析_hdfs_05

 

 

 发现这个下面会有一个current 目录,表示当前的意思,还有一个in_use.lock 这个只是一个普通文件,但是它其实有特殊的含义,你看他的文件名后缀值lock 表示是锁的意思,文件名是in_use 表示这个文件现在正在使用,不允许你再启动namenode。

当我们启动namonde的时候 会判断这个目录下是否有in_use.lock 这个相当于一把锁,如果没有的话,才可以启动成功,启动成功之后就会加一把锁, 停止的时候会把这个锁去掉

hadoop namenode datanode hadoop namenode datanode 域名解析_hdfs_06

 里面有edits文件和fsimage文件

1、fsimage文件

fsimage文件有两个文件名相同的,有一个后缀是md5 md5是一种加密算法,这个其实主要是为了做md5校验的,为了保证文件传输的过程中不出问题,相同内容的md5是一样的,所以后期如果我把这个fsimage和对应的fsimage.md5发给你 然后你根据md5对fsimage的内容进行加密,获取一个值 和fsimage.md5中的内容进行比较,如果一样,说明你接收到的文件就是完整的。

我们在网站下载一些软件的时候 也会有一些md5文件,方便验证下载的文件是否完整。在这里可以把fsimage 拆开 fs 是文件系统 filesystem image是镜像,说明是文件系统镜像,就是给文件照了一个像,把文件的当前信息记录下来。我们可以看一下这个文件,这个文件需要使用特殊的命令进行查看

-i 输入文件 -o 输出文件

sudo -u hdfs hdfs oiv -p XML -i fsimage_0000000000186514797 -o fsimage56.xml

fsimage56.xml文件如下,里面最外层是一个fsimage标签,看里面的inode标签,这个inode表示是hdfs中的每一个目录或者文件信息:

hadoop namenode datanode hadoop namenode datanode 域名解析_hdfs_07

  • id:唯一编号
  • type:文件类型
  • name:文件名称
  • replication:文件的副本数量
  • mtime:修改时间
  • atime:访问时间
  • preferredBlockSize:推荐每一个数据块的大小
  • permission:权限信息
  • blocks:包含多少数据块【文件被切成数据块】
  • block:内部的id表示是块id,genstamp是一个唯一编号,numBytes表示当前数据块的实际大小,storagePolicyId表示是数据的存储策略

这个文件中其实就维护了整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表,所以说fsimage中存放了hdfs最核心的数据。

2、edits文件

当我们上传一个文件的时候,上传一个10G的文件,假设传到9G的时候上传失败了,这个时候就需要重新传,那hdfs怎么知道这个文件失败了呢?这个是在edits文件中记录的。

当我们上传大文件的时候,一个大文件会分为多个block,那么edits文件中就会记录这些block的上传状态,只有当全部block都上传成功了以后,这个时候edits中才会记录这个文件上传成功了,那么我们执行hdfs dfs -ls 的时候就能查到这个文件了,所以当我们在hdfs中执行ls命令的时候,其实会查询fsimage和edits中的内容。

为什么会有这两个文件呢?首先,我们固化的一些文件内容是存储在fsimage文件中,当前正在上传的文件信息是存储在edits文件中。 这个时候我们来查看一下这个edits文件的内容,挑一个edits文件内容多一些的文件

hdfs oev -i  edits_0000000000000000057-0000000000000000065  -o edits.xml

分析生成的edits.xml文件,这个地方注意,可能有的edits文件生成的edits.xml为空,需要多试几个。这个edits.xml中可以大致看一下,里面有很多record。每一个record代表不同的操作,例如 OP_ADD,OP_CLOSE 等等,具体挑一个实例进行分析。

  • OP_ADD:执行上传操作
  • OP_ALLOCATE_BLOCK_ID:申请block块id
  • OP_SET_GENSTAMP_V2:设置GENSTAMP
  • OP_ADD_BLOCK:添加block块
  • OP_CLOSE:关闭上传操作
<RECORD>
    <OPCODE>OP_ADD</OPCODE>
    <DATA>
      <TXID>58</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>16396</INODEID>
      <PATH>/user.txt</PATH>
      <REPLICATION>3</REPLICATION>
      <MTIME>1586349095694</MTIME>
      <ATIME>1586349095694</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME>DFSClient_NONMAPREDUCE_-1768454371_1</CLIENT_NAME>
      <CLIENT_MACHINE>192.168.182.1</CLIENT_MACHINE>
      <OVERWRITE>true</OVERWRITE>
      <PERMISSION_STATUS>
        <USERNAME>yehua</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
      <ERASURE_CODING_POLICY_ID>0</ERASURE_CODING_POLICY_ID>
      <RPC_CLIENTID>1722b83a-2dc7-4c46-baa9-9fa956b755cd</RPC_CLIENTID>
      <RPC_CALLID>0</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
    <DATA>
      <TXID>59</TXID>
      <BLOCK_ID>1073741830</BLOCK_ID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
    <DATA>
      <TXID>60</TXID>
      <GENSTAMPV2>1006</GENSTAMPV2>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ADD_BLOCK</OPCODE>
    <DATA>
      <TXID>61</TXID>
      <PATH>/user.txt</PATH>
      <BLOCK>
        <BLOCK_ID>1073741830</BLOCK_ID>
        <NUM_BYTES>0</NUM_BYTES>
        <GENSTAMP>1006</GENSTAMP>
      </BLOCK>
      <RPC_CLIENTID/>
      <RPC_CALLID>-2</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_CLOSE</OPCODE>
    <DATA>
      <TXID>62</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>0</INODEID>
      <PATH>/user.txt</PATH>
      <REPLICATION>3</REPLICATION>
      <MTIME>1586349096480</MTIME>
      <ATIME>1586349095694</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME/>
      <CLIENT_MACHINE/>
      <OVERWRITE>false</OVERWRITE>
      <BLOCK>
        <BLOCK_ID>1073741830</BLOCK_ID>
        <NUM_BYTES>17</NUM_BYTES>
        <GENSTAMP>1006</GENSTAMP>
      </BLOCK>
      <PERMISSION_STATUS>
        <USERNAME>yehua</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>

这里面的每一个record都有一个事务id,txid,事务id是连续的,其实一个put操作会在edits文件中产生很多的record,对应的就是很多步骤,这些步骤对我们是屏蔽的。

注意了,根据我们刚才的分析,我们所有对hdfs的增删改操作都会在edits文件中留下信息,那么fsimage文件中的内容是从哪来的?其实是这样的,edits文件会定期合并到fsimage文件中。

有同学可能有疑问了,edits文件和fsimage文件中的内容是不一样的,这怎么能是合并出来的呢?

注意,这个其实是框架去做的,在合并的时候会对edits中的内容进行转换,生成新的内容,其实edits中保存的内容是不是太细了,单单一个上传操作就分为了好几步,其实上传成功之后,我们只需要保存文件具体存储的block信息就行了把,所以在合并的时候其实是对edits中的内容进行了精简。

他们具体合并的代码我们不用太过关注,但是我们要知道是那个进程去做的这个事情,其实就是我们之前提到的secondarynamenode。这个进程就是负责定期的把edits中的内容合并到fsimage中。他只做一件事,这是一个单独的进程,在实际工作中部署的时候,也需要部署到一个单独的节点上面。

3、seentxid文件

current目录中还有一个seentxid文件,HDFS format之后是0,它代表的是namenode里面的edits*文件的尾数,namenode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性。

hadoop namenode datanode hadoop namenode datanode 域名解析_上传_08

 4、VERSION文件

这里面显示的集群的一些信息、当重新对hdfs格式化之后,这里面的信息会变化。

hadoop namenode datanode hadoop namenode datanode 域名解析_元数据_09

 

总结:

(1)fsimage: 元数据镜像文件,存储某一时刻NameNode内存中的元数据信息,就类似是定时做了一个快照操作。【这里的元数据信息是指文件目录树、文件/目录的信息、每个文件对应的数据块列表】

(2)edits: 操作日志文件【事务文件】,这里面会实时记录用户的所有操作

(3)seentxid: 是存放transactionId的文件,format之后是0,它代表的是namenode里面的edits*文件的尾数,namenode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性。

(4)VERSION:保存了集群的版本信息

NameNode中的元数据是存储在哪里?首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了。因此产生在磁盘中备份元数据的FsImage。

这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦NameNode节点断电,就会产生数据丢失。因此,引入Edits文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。

但是,如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。

所以NameNode的工作机制是这样的:

hadoop namenode datanode hadoop namenode datanode 域名解析_上传_10

 第一阶段:NameNode启动

(1)第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。

(2)客户端对元数据进行增删改的请求。
(3)NameNode记录操作日志,更新滚动日志。
(4)NameNode在内存中对元数据进行增删改。

第二阶段:Secondary NameNode工作

(1)Secondary NameNode询问NameNode是否需要CheckPoint。直接带回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。

三、SecondaryNameNode介绍

刚才在分析edits日志文件的时候我们已经针对SecondaryNameNode做了介绍,在这里再做一个总结,以示重视。

SecondaryNameNode主要负责定期的把edits文件中的内容合并到fsimage中,这个合并操作称为checkpoint,在合并的时候会对edits中的内容进行转换,生成新的内容保存到fsimage文件中。

注意:在NameNode的HA架构中没有SecondaryNameNode进程,文件合并操作会由standby NameNode负责实现。

所以在Hadoop集群中,SecondaryNameNode进程并不是必须的。

下图是工作中SecondaryNameNode挂了,在重启SecondaryNameNode节点时Ambari的提示,提示内容:开启namenode节点安全模式,创建一个checkpoint。

hadoop namenode datanode hadoop namenode datanode 域名解析_元数据_11

四、DateNode介绍

DataNode是提供真实文件数据的存储服务。针对datanode主要掌握两个概念,一个是block,一个是replication。

首先是block,HDFS会按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block,HDFS默认Block大小是 128MB。

Blokc块是HDFS读写数据的基本单位,不管你的文件是文本文件 还是视频 或者音频文件,针对hdfs而言都是字节。

以user.txt文件为例,他的block信息可以在fsimage文件中看到,也可以在hdfs webui上面看到, 里面有block的id信息,并且也会显示这个数据在哪个节点上面

hadoop namenode datanode hadoop namenode datanode 域名解析_上传_12

这里显示在bigdata02和bigdata03上面都有,那我们过去看一下,datanode中数据的具体存储位置是由dfs.datanode.data.dir来控制的,通过查询hdfs-default.xml可以知道

hadoop namenode datanode hadoop namenode datanode 域名解析_上传_13

 然后进入current目录,继续一路往下走

[root@bigdata02 data]# cd current/
[root@bigdata02 current]# ll
total 4
drwx------. 4 root root  54 Apr  8 20:30 BP-1517789416-192.168.182.100-1586268855170
-rw-r--r--. 1 root root 229 Apr  8 20:30 VERSION
[root@bigdata02 current]# cd BP-1517789416-192.168.182.100-1586268855170/
[root@bigdata02 BP-1517789416-192.168.182.100-1586268855170]# ll
total 4
drwxr-xr-x. 4 root root  64 Apr  8 20:25 current
-rw-r--r--. 1 root root 166 Apr  7 22:21 scanner.cursor
drwxr-xr-x. 2 root root   6 Apr  8 20:30 tmp
[root@bigdata02 BP-1517789416-192.168.182.100-1586268855170]# cd current/
[root@bigdata02 current]# ll
total 8
-rw-r--r--. 1 root root  20 Apr  8 20:25 dfsUsed
drwxr-xr-x. 3 root root  21 Apr  8 15:34 finalized
drwxr-xr-x. 2 root root   6 Apr  8 22:13 rbw
-rw-r--r--. 1 root root 146 Apr  8 20:30 VERSION
[root@bigdata02 current]# cd finalized/
[root@bigdata02 finalized]# ll
total 0
drwxr-xr-x. 3 root root 21 Apr  8 15:34 subdir0
[root@bigdata02 finalized]# cd subdir0/
[root@bigdata02 subdir0]# ll
total 4
drwxr-xr-x. 2 root root 4096 Apr  8 22:13 subdir0
[root@bigdata02 subdir0]# cd subdir0/
[root@bigdata02 subdir0]# ll
total 340220
-rw-r--r--. 1 root root     22125 Apr  8 15:55 blk_1073741828
-rw-r--r--. 1 root root       183 Apr  8 15:55 blk_1073741828_1004.meta
-rw-r--r--. 1 root root      1361 Apr  8 15:55 blk_1073741829
-rw-r--r--. 1 root root        19 Apr  8 15:55 blk_1073741829_1005.meta
-rw-r--r--. 1 root root        17 Apr  8 20:31 blk_1073741830
-rw-r--r--. 1 root root        11 Apr  8 20:31 blk_1073741830_1006.meta
-rw-r--r--. 1 root root 134217728 Apr  8 22:13 blk_1073741831
-rw-r--r--. 1 root root   1048583 Apr  8 22:13 blk_1073741831_1007.meta
-rw-r--r--. 1 root root 134217728 Apr  8 22:13 blk_1073741832
-rw-r--r--. 1 root root   1048583 Apr  8 22:13 blk_1073741832_1008.meta
-rw-r--r--. 1 root root  77190019 Apr  8 22:13 blk_1073741833
-rw-r--r--. 1 root root    603055 Apr  8 22:13 blk_1073741833_1009.meta

这里面就有很多的block块了,注意: 这里面的.meta文件也是做校验用的

根据前面看到的blockid信息到这对应的找到文件,可以直接查看,发现文件内容就是我们之前上传上去的内容。

[root@bigdata02 subdir0]# cat blk_1073741830
jack
tom
jessic

注意:这个block中的内容可能只是文件的一部分,如果你的文件较大的话,就会分为多个block存储,默认 hadoop3中一个block的大小为128M。根据字节进行截取,截取到128M就是一个block。如果文件大小没有默认的block块大,那最终就只有一个block。

HDFS中,如果一个文件小于一个数据块的大小,那么并不会占用整个数据块的存储空间

 

hadoop namenode datanode hadoop namenode datanode 域名解析_元数据_14

 

size是表示我们上传文件的实际大小,blocksize是指文件的最大块大小。

 假设我们上传了两个10M的文件 又上传了一个200M的文件

问1:会产生多少个block块? 4个

问2:在hdfs中会显示几个文件?3个

下面看一下副本,副本表示数据有多少个备份

我们现在的集群有两个从节点,所以最多可以有2个备份,这个是在hdfs-site.xml中进行配置的,dfs.replication 默认这个参数的配置是3。表示会有3个副本。副本只有一个作用就是保证数据安全。

DataNode工作机制

hadoop namenode datanode hadoop namenode datanode 域名解析_上传_15

(1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。

(2)DataNode启动后向NameNode注册,通过后,周期性(1小时)地向NameNode上报所有的块信息。

(3)心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。

(4)集群运行中可以安全加入和退出一些机器。

DataNode数据损坏

(1)当DataNode读取Block的时候,它会计算CheckSum。
(2)如果计算后的CheckSum,与Block创建时值不一样,说明Block已经损坏。
(3)Client读取其他DataNode上的Block。
(4)DataNode在其文件创建后周期验证CheckSum。

五、NameNode总结

注意:block块存放在哪些datanode上,只有datanode自己知道,当集群启动的时候,datanode会扫描自己节点上面的所有block块信息,然后把节点和这个节点上的所有block块信息告诉给namenode。这个关系是每次重启集群都会动态加载的【这个其实就是集群为什么数据越多,启动越慢的原因】

咱们之前说的fsimage(edits)文件中保存的有文件和block块之间的信息。

这里说的是block块和节点之间的关系,这两块关联在一起之后,就可以根据文件找到对应的block块,再根据block块找到对应的datanode节点,这样就真正找到了数据。

所以说 其实namenode中不仅维护了文件和block块的信息 还维护了block块和所在的datanode节点的信息。

可以理解为namenode维护了两份关系:

第一份关系:file 与block list的关系,对应的关系信息存储在fsimage和edits文件中,当NameNode启动的时候会把文件中的元数据信息加载到内存中

第二份关系:datanode与block的关系,对应的关系主要在集群启动的时候保存在内存中,当DataNode启动时会把当前节点上的Block信息和节点信息上报给NameNode

注意了,刚才我们说了NameNode启动的时候会把文件中的元数据信息加载到内存中,然后每一个文件的元数据信息会占用150字节的内存空间,这个是恒定的,和文件大小没有关系,咱们前面在介绍HDFS的时候说过,HDFS不适合存储小文件,其实主要原因就在这里,不管是大文件还是小文件,一个文件的元数据信息在NameNode中都会占用150字节,NameNode节点的内存是有限的,所以它的存储能力也是有限的,如果我们存储了一堆都是几KB的小文件,最后发现NameNode的内存占满了,确实存储了很多文件,但是文件的总体大小却很小,这样就失去了HDFS存在的价值

最后,在datanode的数据目录下面的current目录中也有一个VERSION文件。这个VERSION和namenode的VERSION文件是有一些相似之处的,我们来具体对比一下两个文件的内容。

namenode的VERSION文件

[root@bigdata01 current]# cat VERSION 
#Wed Apr 08 20:30:00 CST 2020
namespaceID=498554338
clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=1586268855170
storageType=NAME_NODE
blockpoolID=BP-1517789416-192.168.182.100-1586268855170
layoutVersion=-65

datanode的VERSION文件

[root@bigdata02 current]# cat VERSION 
#Wed Apr 08 20:30:04 CST 2020
storageID=DS-0e86cd27-4961-4526-bacb-3b692a90b1b0
clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=0
datanodeUuid=0b09f3d7-442d-4e28-b3cc-2edb0991bae3
storageType=DATA_NODE
layoutVersion=-57

我们前面说了namenode不要随便格式化,因为格式化了以后VERSION里面的clusterID会变,但是datanode的VERSION中的clusterID并没有变,所以就对应不上了。如果确实要重新格式化的话需要把/data/hadoop_repo数据目录下的内容都清空,全部都重新生成是可以的。

六、HDFS的回收站

我们windows系统里面有一个回收站,当想恢复删除的文件的话就可以到这里面进行恢复,HDFS也有回收站。

HDFS会为每一个用户创建一个回收站目录:/user/用户名/.Trash/,每一个被用户在Shell命令行删除的文件/目录,会进入到对应的回收站目录中,在回收站中的数据都有一个生存周期,也就是当回收站中的文件/目录在一段时间之内没有被用户恢复的话,HDFS就会自动的把这个文件/目录彻底删除,之后,用户就永远也找不回这个文件/目录了。

默认情况下hdfs的回收站是没有开启的,需要通过一个配置来开启,在core-site.xml中添加如下配置,value的单位是分钟,1440分钟表示是一天的生存周期

<property>
    <name>fs.trash.interval</name>
    <value>1440</value>
</property>

在修改配置信息之前先验证一下删除操作,显示的是直接删除掉了。

[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r /NOTICE.txt
Deleted /NOTICE.txt

修改回收站配置,先在bigdata01上操作,然后再同步到其它两个节点,先停止集群

[root@bigdata01 hadoop-3.2.0]# sbin/stop-all.sh 
[root@bigdata01 hadoop-3.2.0]# vi etc/hadoop/core-site.xml 
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://bigdata01:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/data/hadoop_repo</value>
   </property>
    <property>
        <name>fs.trash.interval</name>
        <value>1440</value>
    </property>
</configuration>
[root@bigdata01 hadoop-3.2.0]# scp -rq etc/hadoop/core-site.xml bigdata02:/data/soft/hadoop-3.2.0/etc/hadoop/
[root@bigdata01 hadoop-3.2.0]# scp -rq etc/hadoop/core-site.xml bigdata03:/data/soft/hadoop-3.2.0/etc/hadoop/

启动集群,再执行删除操作

[root@bigdata01 hadoop-3.2.0]# sbin/start-all.sh
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r /README.txt
2020-04-09 11:43:47,664 INFO fs.TrashPolicyDefault: Moved: 'hdfs://bigdata01:9000/README.txt' to trash at: hdfs://bigdata01:9000/user/root/.Trash/Current/README.txt

此时看到提示信息说把删除的文件移到到了指定目录中,其实就是移动到了当前用户的回收站目录。

回收站的文件也是可以下载到本地的。其实在这回收站只是一个具备了特殊含义的HDFS目录。

注意:如果删除的文件过大,超过回收站大小的话会提示删除失败 需要指定参数 -skipTrash ,指定这个参数表示删除的文件不会进回收站

[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r -skipTrash /user.txt
Deleted /user.txt

七、HDFS的安全模式

大家在平时操作HDFS的时候,有时候可能会遇到这个问题,特别是刚启动集群的时候去上传或者删除文件,会发现报错,提示NameNode处于safe mode。

这个属于HDFS的安全模式,因为在集群每次重新启动的时候,HDFS都会检查集群中文件信息是否完整,例如副本是否缺少之类的信息,所以这个时间段内是不允许对集群有修改操作的,如果遇到了这个情况,可以稍微等一会,等HDFS自检完毕,就会自动退出安全模式。

[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r /hadoop-3.2.0.tar.gz
2020-04-09 12:00:36,646 WARN fs.TrashPolicyDefault: Can't create trash directory: hdfs://bigdata01:9000/user/root/.Trash/Current
org.apache.hadoop.hdfs.server.namenode.SafeModeException: Cannot create directory /user/root/.Trash/Current. Name node is in safe mode.

此时访问HDFS的web ui界面,可以看到下面信息,on表示处于安全模式,off表示安全模式已结束

hadoop namenode datanode hadoop namenode datanode 域名解析_元数据_16

 

或者通过hdfs命令也可以查看当前的状态

[root@bigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode get
Safe mode is ON

如果想快速离开安全模式,可以通过命令强制离开,正常情况下建议等HDFS自检完毕,自动退出

[root@bigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode leave
Safe mode is OFF

此时,再操作HDFS中的文件就可以了。

八、HDFS读写流程

1、HDFS写流程

 

 

hadoop namenode datanode hadoop namenode datanode 域名解析_上传_17

2、HDFS读流程

hadoop namenode datanode hadoop namenode datanode 域名解析_上传_18