HDFS知识点总结

一:HDFS 概述

    一、简介

       1. 概念:HDFS(Hadoop Distributed File System)分布式文件存储系统,作为Google File System(GFS)的实现,是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上。它所具有的高容错、高可靠性、高可扩展性、高获得性、高吞吐率等特征为海量数据提供了不怕故障的存储,为超大数据集(Large Data Set)的应用处理带来了很多便利。

 

       2. 特点

           1. 优点

               1. 高容错性:数据自动保存多个副本,当一个副本丢失后,可以自动恢复。

               2. 适合大数据处理:文件规模大(百万个数以上),数据规模大(数据大小达GB、TB、PB或更高)。

               3. 流式数据访问:一次写入,多次读取,不能修改,只能追加,不支持多线程并行操作,保证数据一致性。

               4. 构建成本低:可以构建在廉价的机器上,例如多台低配置电脑。

 

           2. 缺点

               1. 不适合做低延迟数据访问。比如毫秒级的数据访问。

               2. 无法高效的对大量小文件进行存储。因为 HDFS 的块比磁盘的块大(默认128M),其目的是为了最小化寻址开销,大量的小文件会增加寻址开销。

               3. 无法并发写入和随机修改。因为 HDFS 被设计成适合批量处理的,而不是用户交互式的

 

    二、架构

      

       1. NameNode:管理整个文件系统的元数据,如命名空间、数据块(Block)映射信息、副本策略及处理客户端读写请求。

       2. DateNode:管理每个数据块,如存储实际的数据块,处理客户端对数据块的读/写操作。

       3. Client:通过 CLI 或 API 来操作 DataNode(读 / 写操作)和 NameNode(获取文件位置信息)。

       4. Secondary NameNode:辅助 NameNode 分担工作量,定期合并 fsimage(命名空间镜像) 和 fsedits(修改日志) 并推送给 NameNode。

       5. Block:默认最基本的存储单为是128M的数据块。

           1. 区别:不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。

           2. 目的:减少硬盘寻道时间(减少最小化寻址开销),减少 NameNode 内存消耗,加快数据传输速度。

 

    三、NameNode 和 SecondaryNameNode 工作机制

       1.  工作机制

            

           1. NameNode启动时,先滚动Edits并生成一个空的edits.inprogress,然后加载Edits和Fsimage到内存中,此时NameNode内存就持有最新的元数据信息。Client开始对NameNode发送元数据的增删改的请求,这些请求的操作首先会被记录到edits.inprogress中(查询元数据的操作不会被记录在Edits中,因为查询操作不会更改元数据信息),如果此时NameNode挂掉,重启后会从Edits中读取元数据的信息。然后,NameNode会在内存中执行元数据的增删改的操作。

           2. 由于Edits中记录的操作会越来越多,Edits文件会越来越大,导致NameNode在启动加载Edits时会很慢,所以需要对Edits和Fsimage进行合并(所谓合并,就是将Edits和Fsimage加载到内存中,照着Edits中的操作一步步执行,最终形成新的Fsimage)。SecondaryNameNode的作用就是帮助NameNode进行Edits和Fsimage的合并工作。

           3. 2NN首先会询问NN是否需要CheckPoint(触发CheckPoint需要满足两个条件中的任意一个,定时时间到和Edits中数据写满了)。直接带回NN是否检查结果。2NN执行CheckPoint操作,首先会让NameNode滚动Edits并生成一个空的edits.inprogress,滚动Edits的目的是给Edits打个标记,以后所有新的操作都写入edits.inprogress,其他未合并的Edits和Fsimage会拷贝到2NN的本地,然后将拷贝的Edits和Fsimage加载到内存中进行合并,生成fsimage.chkpoint,然后将fsimage.chkpoint拷贝给NameNode,重命名为Fsimage后替换掉原来的Fsimage。NameNode在启动时就只需要加载之前未合并的Edits和Fsimage即可,因为合并过的Edits中的元数据信息已经被记录在Fsimage中。

 

       2. 概念介绍

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

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


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

 1 # 查看 Fsimage 文件
 2 hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径
 3 hdfs oiv -p XML -i fsimage_0000000000000000025 -o  /opt/module/hadoop-2.7.2/fsimage.xml
 4 
 5 # 查看 edits 文件
 6 hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径
 7 hdfs  oev  -p  XML  -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-2.7.2/edits.xml 
 8 
 9 # CheckPoint 设置(默认每隔一小时执行或者数据满100万条)
10 <property>
11   <name>dfs.namenode.checkpoint.txns</name>
12   <value>1000000</value>
13   <description>操作动作次数</description>
14 </property>
15 
16 <property>
17   <name>dfs.namenode.checkpoint.check.period</name>
18   <value>60</value>
19   <description> 1分钟检查一次操作次数</description>
20 </property >

 

       3. 故障处理及多目录设置

 1 # 一:将 SecondaryNameNode 中数据拷贝到 NameNode 存储数据的目录
 2 ### 删除NameNode存储的数据(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)
 3 [root@master ~]$ rm -rf $HADOOP_HOME/data/tmp/dfs/name/*
 4 
 5 ### 拷贝SecondaryNameNode的数据到原NameNode存储数据目录
 6 [root@master ~]$ scp -r  root@master:$HADOOP_HOME/data/tmp/dfs/namesecondary/* $HADOOP_HOME/data/tmp/dfs/name/
 7 
 8 ### 重新启动NameNode
 9 [root@master ~]$ start-dfs.sh
10 
11     1
12 
13 # 二:使用-importCheckpoint选项启动NameNode守护进程,从而将SecondaryNameNode中数据拷贝到NameNode目录中。
14 
15 ### 修改hdfs-site.xml
16 <property>
17   <name>dfs.namenode.checkpoint.period</name>
18   <value>120</value>
19 </property>
20 
21 <property>
22   <name>dfs.namenode.name.dir</name>
23   <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
24 </property>
25 
26 ### 删除NameNode存储的数据(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)
27 [root@master ~]$ rm -rf $HADOOP_HOME/data/tmp/dfs/name/*
28 
29 ### 拷贝SecondaryNameNode的数据到原NameNode存储数据目录
30 [root@master ~]$ scp -r  root@master:$HADOOP_HOME/data/tmp/dfs/namesecondary/* $HADOOP_HOME/data/tmp/dfs/name/
31 
32 ### 导入检查点数据
33 [root@master ~]$ hdfs namenode -importCheckpoint
34 
35 ### 重新启动NameNode
36 [root@master ~]$ start-dfs.sh
37 
38 # 设置多级目录(修改hdfs-site.xml,删除集群中的数据并格式化后重启)
39 <property>
40     <name>dfs.namenode.name.dir</name>
41     <value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value>
42 </property>

 

       4. 安全模式

          

 1 # 查看安全模式状态
 2 [root@master ~]# hdfs dfsadmin -safemode get  
 3 Safe mode is OFF
 4 
 5 # 进入安全模式状态
 6 [root@master ~]# hdfs dfsadmin -safemode enter
 7 Safe mode is ON
 8 
 9 # 退出安全模式状态
10 [root@master ~]# hdfs dfsadmin -safemode leave
11 Safe mode is OFF
12 
13 # 等待安全模式状态
14 [root@master ~]# hdfs dfsadmin -safemode wait
15 Safe mode is OFF

 

    四、DataNode 工作机制

       1. 工作机制

          

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

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

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

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

 

       2. 数据完整性

           1. 当 DataNode 读取 block 的时候,它会计算 checksum。

           2. 如果计算后的 checksum,与 block 创建时值不一样,说明 block 已经损坏。

           3. client 读取其他 DataNode 上的 block。

           4. DataNode 在其文件创建后周期验证 checksum。
          

 

       3. 掉线时限参数设置

           1. DataNode 进程死亡或者网络故障造成 DataNode 无法与 NameNode 通信, NameNode 不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。

           2. HDFS 默认的超时时长为 10 分钟+30 秒。如果定义超时时间为 timeout,则超时时长的计算公式为:

 1 # 超时时长计算公式
 2 timeout = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval。
 3 
 4 # 修改超时时长
 5 <property>
 6     <name>dfs.namenode.heartbeat.recheck-interval</name>
 7     <value>300000</value>
 8     <description>默认为5分钟,单位为毫秒</description>
 9 </property>
10 <property>
11     <name> dfs.heartbeat.interval </name>
12     <value>3</value>
13     <description>默认为3秒,单位为秒</description>
14 </property>

 

       4. 服务和退役数据节点

 1 # 服务新数据节点
 2 ### 在 /etc/hadoop 目录下创建 dfs.hosts 文件并添加服务数据节点
 3 [root@master ~]$ vi $HADOOP_HOME/etc/hadoop/dfs.hosts
 4 master
 5 slaver1
 6 slaver2
 7 slaver3(新节点)
 8 
 9 ### 在 NameNode 的 hdfs-site.xml 配置文件中增加 dfs.hosts 属性
10 <property>
11     <name>dfs.hosts</name>
12     <value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts</value>
13 </property>
14 
15 ### 刷新 NameNode 和 ResourceManager
16 [root@master ~]$ hdfs dfsadmin -refreshNodes
17 Refresh nodes successful
18 [root@master ~]$ yarn rmadmin -refreshNodes
19 20/06/6 14:17:11 INFO client.RMProxy: Connecting to ResourceManager at master/192.168.200.54:8033
20 
21 ### 添加工作数据节点
22 [root@master ~]# vi $HADOOP-HOME/etc/hadoop/workers 
23 master
24 slaver1
25 slaver2 
26 salver3
27 
28 ### 启动
29 [root@master ~]# start-all.sh 
30 
31 # 退役旧数据节点
32 ### 在 /etc/hadoop 目录下创建 dfs.hosts.exclude 文件并添加数据节点
33 [root@master ~]# vi $HADOOP-HOME/etc/hadoop/dfs.hosts.exclude
34 slaver3
35 
36 ### 在 NameNode 的 hdfs-site.xml 配置文件中增加 dfs.hosts.exclude 属性
37 <property>
38     <name>dfs.hosts.exclude</name>
39     <value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts.exclude</value>
40 </property>
41 
42 ### 刷新 NameNode 和 ResourceManager
43 [root@master ~]$ hdfs dfsadmin -refreshNodes
44 Refresh nodes successful
45 [root@master ~]$ yarn rmadmin -refreshNodes
46 20/06/6 14:17:11 INFO client.RMProxy: Connecting to ResourceManager at master/192.168.200.54:8033
47 
48 ### 启动
49 [root@master ~]# start-all.sh 
50 
51 # 注意:白名单和黑名单不能有共同的数据节点,并且修改完配置后要分发到集群
52 
53 # DataNode 多级目录配置:目录存储的数据不一样(数据不是副本)
54 <property>
55     <name>dfs.datanode.data.dir</name>
56     <value>file:///${hadoop.tmp.dir}/dfs/data1,file:///${hadoop.tmp.dir}/dfs/data2</value>
57 </property>

 

二:HDFS 的数据流

    一、机架感知(副本存放策略)

       

 

    二、网络拓扑(节点距离计算)

       

       1. Hadoop 采用近似方法,即使用两个节点之间的跳数(线缆的段数)来代表节点之间的距离。

       2. Hadoop 将整个集群理解为树形结构,树的每个节点代表集群中的每个机器(处理机或者路由器)。

       3. 如果将数据中心 d1 里的机架 r1 上的节点 n1 定义为 /d1/r1/n1 的话,那么

           1. 同一节点上的两个应用程序:distance(/d1/r1/n1,/d1/r1/n1) = 0

           2. 同一机架上的两个节点:distance(/d1/r1/n1,/d1/r1/n2) = 2

           3. 同一数据中心里不同机架上的两个节点:distance(/d1/r1/n1,/d1/r2/n3) = 4

           4. 不同数据中心的两个节点:distance(/d1/r1/n1, /d2/r4/n1) = 6

 

    三、写数据流程

      

       1. 客户端通过调用 DistributedFileSystem 的 create 方法,请求上传一个文件。

       2. DistributedFileSystem 接收到请求后通过 RPC(远程过程调用)调用NameNode,去创建一个没有 Blocks 关联的新文件。

       3. NameNode 接收到创建请求后会做各种校验,如果校验通过,NameNode 就会记录下新文件,并响应可以上传文件,否则就会抛出IO异常。

       4. 客户端通过验证后调用 FSDataOutputStream(输出流对象) 请求建立 Blocks 传输通道。

       5. DataStreamer 依次接收请求并找到最适合存储的 DataNode ,然后将信息响应给 FSDataOutputStream。

       6. FSDataOutputStream 将数据切成 packet 后排成队列依次存入DataNode中。

 

    四、读数据流程

      

       1. 客户端通过调用 DistributedFileSystem 的 open 方法,请求下载一个文件。

       2. DistributedFileSystem 接收到请求后通过 RPC 调用 NameNode,得到文件的 Blocks

       3. NameNode 接收到创建请求后会做各种校验,如果校验通过,NameNode 响应 Blocks并通过下载,否则就会抛出IO异常。

       4. 客户端通过验证后调用 FSDataInputStream(输入流对象) 请求读取 Blocks 。

       5. DataStreamer 依次接收请求并将 Blocks 信息响应给 FSDataInputStream。

       6. FSDataInputStream 将接受到的数据存储在本地系统。 

 

三:HDFS 操作

    一、Shell

       1. 文件系统操作

          

 

       2. 管理命令

          

 

    二、API

       1. 环境搭建

           1. 解压 hadoop-3.1.3.tar.gz 到本地并配置环境变量

              

 

           2. 创建 Maven 项目,导入相关依赖(必须要log4j的配置文件)

 1 <dependencies>
 2     <dependency>
 3         <groupId>junit</groupId>
 4         <artifactId>junit</artifactId>
 5         <version>RELEASE</version>
 6     </dependency>
 7 
 8     <dependency>
 9         <groupId>org.apache.logging.log4j</groupId>
10         <artifactId>log4j-core</artifactId>
11         <version>2.8.2</version>
12     </dependency>
13 
14     <dependency>
15         <groupId>org.apache.hadoop</groupId>
16         <artifactId>hadoop-common</artifactId>
17         <version>3.1.3</version>
18     </dependency>
19 
20     <dependency>
21         <groupId>org.apache.hadoop</groupId>
22         <artifactId>hadoop-client</artifactId>
23         <version>3.1.3</version>
24     </dependency>
25 
26     <dependency>         
27         <groupId>org.apache.hadoop</groupId>
28         <artifactId>hadoop-hdfs</artifactId>       
29         <version>3.1.3</version>
30     </dependency>
31 </dependencies>

 

       2. API 操作

 1 public class HDFSClient {
 2     @Test
 3     public void test() throws Exception {
 4         // 读取配置文件(底层的四大site配置文件)
 5         Configuration configuration = new Configuration();
 6         // 获取文件系统(HDFS 文件系统)
 7         FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"), configuration, "root");
 8 
 9         /**
10          * 文件上传和下载
11          */
12         // 将本地文件上传到 HDFS,删除原文件
13         fs.copyFromLocalFile(true, new Path("d:/test.txt"), new Path("/user/input"));
14         // 从 HDFS 下载文件到本地,不删除原文件
15         fs.copyToLocalFile(false, new Path("/user/input/mm.txt"), new Path("d:/"));
16         
17         /**
18          * 创建、删除、重命名
19          */
20         // 创建目录
21         fs.mkdirs(new Path("/user/test"));
22         // 删除文件
23         fs.delete(new Path("/user/input/mm.txt"), false);
24         // 文件重命名
25         fs.rename(new Path("/user/input/test.txt"), new Path("/user/input/jj.txt"));
26         
27         /**
28          * 查看文件列表信息
29          */
30         RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
31         while (listFiles.hasNext()) {
32             LocatedFileStatus files = listFiles.next();
33             // 获取文件名
34             System.out.println(files.getPath().getName()); // 文件名
35             // 获取权限信息
36             System.out.println(files.getPermission()); // 权限信息
37             // 获取副本数
38             System.out.println(files.getReplication()); // 副本数
39             // 获取块大小
40             System.out.println(files.getBlockSize()); // 块大小
41             // 获取块位置信息
42             BlockLocation[] blockLocations = files.getBlockLocations();
43             for (BlockLocation blockLocation : blockLocations) {
44                 // 获取块所在位置信息的主机名
45                 String[] hosts = blockLocation.getHosts();
46                 for (String host : hosts) {
47                     System.out.println(host);
48                 }
49             }
50         }
51 
52         /**
53          * 查看文件状态信息
54          */
55         FileStatus[] listStatus = fs.listStatus(new Path("/"));
56         for (FileStatus fileStatus : listStatus) {
57             // 判断是不是文件和目录
58             if (fileStatus.isFile()) { 
59                 System.out.println("f:" + fileStatus.getPath().getName());
60             } else { // isDirectory()
61                 System.out.println("d:" + fileStatus.getPath().getName());
62             }
63             
64         }    
65 
66 // 释放资源 67 fs.close(); 68 } 69 }

 

       3. IO流操作

 1 public class HDFSClient {
 2     /**
 3      * 自定义文件上传和下载
 4      */
 5     @Test
 6     public void upAndDown() throws Exception {
 7         // 读取配置文件和获取文件系统
 8         Configuration configuration = new Configuration();
 9         FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"), configuration, "root");
10 
11         /**
12          * 上传
13          */
14         // 1. 获取输入流
15         FileInputStream fis = new FileInputStream(new File("d:/test.txt"));
16         // 2. 获取输出流
17         FSDataOutputStream fos = fs.create(new Path("/user/output/"));
18         // 3. 流对拷
19         IOUtils.copyBytes(fis, fos, configuration);
20         
21         /**
22          * 下载
23          */
24         // 1. 获取输入流
25         FSDataInputStream in = fs.open(new Path("/user/output/test.txt"));
26         // 2. 获取输出流
27         FileOutputStream out = new FileOutputStream(new File("d:/"));
28         // 3. 流对拷
29         IOUtils.copyBytes(in, out, configuration);
30         
31         // 关闭资源
32         IOUtils.closeStreams(fos,fis,in,out);
33         fs.close();
34     }
35 
36     /**
37      * 定位读取文件
38      */
39     @Test
40     public void readFileSeek() throws Exception {
41         // 读取配置文件和获取文件系统
42         Configuration configuration = new Configuration();
43         FileSystem fs = FileSystem.get(new URI("hdfs://master:9000"), configuration, "root");
44 
45         /**
46          * 下载第一块
47          */
48         // 1. 获取输入流
49         FSDataInputStream fis = fs.open(new Path("/user/output/hadoop-3.1.3.tar.gz"));
50         // 2. 获取输出流
51         FileOutputStream fos = new FileOutputStream(new File("d:/"));
52         // 3. 流对拷
53         byte[] bytes = new byte[1024];
54         for (int i = 0; i < bytes.length * 128; i++) {
55             fis.read(bytes);
56             fos.write(bytes);
57         }
58 
59         /**
60          * 下载第二块
61          */
62         // 1. 获取输入流
63         FSDataInputStream in = fs.open(new Path("/user/output/hadoop-3.1.3.tar.gz"));
64         // 2. 设置读取的起点
65         in.seek(1024*1024*128); 
66         // 3. 获取输出流
67         FileOutputStream out = new FileOutputStream(new File("d:/hadoop-3.1.3.tar.gz"));
68         // 4. 流对拷
69         IOUtils.copyBytes(in, out, configuration);
70        
71         // 关闭资源
72         IOUtils.closeStreams(fos, fis, in, out);
73         fs.close();
74     }
75 }

 

:HDFS 新特性

    一、小文件归档

       1. 背景:hdfs 并不擅长存储小文件,因为每个文件最少一个 block,每个 block 的元数据都会在 NameNode 中占用150byte内存。如果存储大量的小文件,它们会占用 NameNode 节点的大量内存。

       2. 解决:Hadoop Archive 是一个高效地将小文件放入 HDFS 块中的文件存档工具。它能将多个小文件打包成一个HAR文件,这样在减少NameNode内存使用的同时,仍然允许对小文件进行透明的访问。

       3. 使用

 1 # 归档命令:hadoop archive <-archiveName <NAME>.har> <-p <parent path>> [-r <replication factor>] <src>* <dest>
 2 
 3 # 归档前目录结构
 4 [root@master ~]# hadoop fs -ls /user/input          
 5 Found 3 items
 6 -rw-r--r--   3 root supergroup          0 2020-06-08 16:01 /user/input/aa.txt
 7 -rw-r--r--   3 root supergroup          0 2020-06-08 16:01 /user/input/bb.txt
 8 -rw-r--r--   3 root supergroup          0 2020-06-05 00:16 /user/input/mm.txt
 9 
10 # 归档后目录结构
11 [root@master ~]# hadoop archive -archiveName  test.har  -p /user/ input/* /user/output/
12 ......
13 [root@master ~]# hadoop fs -ls /user/input/  # 不会删除原文件
14 Found 3 items
15 -rw-r--r--   3 root supergroup          0 2020-06-08 16:01 /user/input/aa.txt
16 -rw-r--r--   3 root supergroup          0 2020-06-08 16:01 /user/input/bb.txt
17 -rw-r--r--   3 root supergroup          0 2020-06-05 00:16 /user/input/mm.txt
18 [root@master ~]# hadoop fs -ls /user/output 
19 drwxr-xr-x   - root supergroup          0 2020-06-08 16:12 /user/output/test.har
20 
21 # 查看归档文件
22 [root@master ~]# hadoop fs -ls har:///user/output/test.har/input  # 文件协议
23 2020-06-08 16:15:47,069 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
24 Found 3 items
25 -rw-r--r--   3 root supergroup          0 2020-06-08 16:01 har:///user/output/test.har/input/aa.txt
26 -rw-r--r--   3 root supergroup          0 2020-06-08 16:01 har:///user/output/test.har/input/bb.txt
27 -rw-r--r--   3 root supergroup          0 2020-06-05 00:16 har:///user/output/test.har/input/mm.txt

 

    二、垃圾回收站

       1. HDFS 删除的文件并不会真正的删除,而是放入回收站。HDFS会为每一个用户创建一个回收站目录:/user/用户名/.Trash/

       2. 在指定时间阈值回收站里的文件可以快速恢复,当回收站里文件的存放时间超过这个阈值或是回收站被清空时,文件才会被彻底删除,并且释放占用的数据块。

       3. 使用

 1 # 开启 trash 功能
 2 [root@master ~]# vi $HADOOP_HOME/etc/hadoop/core-site.xml 
 3 <property>
 4     <name>fs.trash.checkpoint.interva</name>
 5     <value>0</value>
 6     <description>删除后多长时间放入回收站</description>
 7 </property>
 8 
 9 <property>
10     <name>fs.trash.interval</name>
11     <value>1440</value>
12     <description>文件删除后保留时长,单位为分钟</description>
13 </property>
14 
15 # 删除 HDFS 文件(放入回收站)
16 [root@master ~]# hadoop fs -rm -f /user/input/aa.txt
17 2020-06-08 16:38:48,956 INFO fs.TrashPolicyDefault: Moved: 'hdfs://master:9000/user/input/aa.txt' to trash at: hdfs://master:9000/user/root/.Trash/Current/user/input/aa.txt
18 
19 # 恢复
20 [root@master ~]# hadoop fs -mv hdfs://master:9000/user/root/.Trash/Current/user/input/aa.txt /user/input/
21 
22 # 清空回收站
23 [root@master ~]# hadoop fs -expunge  
24 2020-06-08 16:46:20,266 INFO fs.TrashPolicyDefault: TrashPolicyDefault#deleteCheckpoint for trashRoot: hdfs://master:9000/user/root/.Trash
25 2020-06-08 16:46:20,267 INFO fs.TrashPolicyDefault: TrashPolicyDefault#deleteCheckpoint for trashRoot: hdfs://master:9000/user/root/.Trash
26 2020-06-08 16:46:20,283 INFO fs.TrashPolicyDefault: TrashPolicyDefault#createCheckpoint for trashRoot: hdfs://master:9000/user/root/.Trash
27 2020-06-08 16:46:20,290 INFO fs.TrashPolicyDefault: Created trash checkpoint: /user/root/.Trash/200608164620

 

    三、快照管理

       1. HDFS 的快照(snapshot)是在某一时间点对指定文件系统拷贝,快照采用只读模式,可以对重要数据进行恢复、防止用户错误性的操作。

       2. 特点

           1. 快照创建是瞬间的:成本是0(1)排除查找信息节点的时间 。

           2. 额外的内存使用仅仅当对快照进行修改时产生:内存使用时0(M),M是修改文件/目录的数量。

           3. 在datanode中的块不会被拷贝:快照文件记录这些块列表和文件大小,不会产生数据拷贝。

           4. 快照不会对日常的HDFS操作产生不利的影响:修改被按反向时间排序记录,这样当前数据可以直接的访问。

       3. 使用

 1 # 快照的开启和关闭
 2 ### 开启:hdfs dfsadmin -allowSnapshot  <path>
 3 ### 关闭:hdfs dfsadmin -disallowSnapshot  <path>
 4 [root@master ~]# hdfs dfsadmin -allowSnapshot /user/input/
 5 Allowing snapshot on /user/input/ succeeded
 6 
 7 # 快照的创建、删除和重命名
 8 ### 创建:hadoop fs -createSnapshot <snapshotDir> <snapshotName> 
 9 [root@master ~]# hadoop fs -createSnapshot /user/input/ test
10 Created snapshot /user/input/.snapshot/test
11 
12 ### 删除:hadoop fs -deleteSnapshot <snapshotDir> <snapshotName>
13 
14 ### 重命名:hadoop fs -renameSnapshot <snapshotDir> <oldName> <newName>
15 [root@master ~]# hadoop fs -renameSnapshot /user/input/  test  snapshot-test  
16 [root@master ~]# hadoop fs -ls /user/input/.snapshot/
17 Found 1 items
18 drwxr-xr-x   - root supergroup          0 2020-06-08 16:57 /user/input/.snapshot/snapshot-test
19 
20 # 查看当前用户快照列表
21 [root@master ~]# hdfs lsSnapshottableDir
22 drwxr-xr-x 0 root supergroup 0 2020-06-08 16:57 1 65536 /user/input
23 
24 # 查看快照详细信息
25 [root@master ~]# hadoop fs -ls /user/input/.snapshot/test
26 Found 3 items
27 -rw-r--r--   3 root supergroup          0 2020-06-08 16:01 /user/input/.snapshot/test/aa.txt
28 -rw-r--r--   3 root supergroup          0 2020-06-08 16:01 /user/input/.snapshot/test/bb.txt
29 -rw-r--r--   3 root supergroup          0 2020-06-05 00:16 /user/input/.snapshot/test/mm.txt

 

五:HDFS HA