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