天天看點

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

HDFS精選【精簡】

提示:請先學完hadoop基礎 hadoop知識點

HDFS

  • HDFS精選【精簡】
  • 前言
  • 一、hdfs概述?
      • 1) 介紹
      • 2) 優缺點
      • 3)組成
      • 4)HDFS 檔案塊大小(面試重點)
  • 二、hdfs shell操作
    • 1).啟動叢集
    • 2).基本指令介紹
  • 三 hdfs API操作
    • 1)檔案建立
    • 2)檔案上傳
    • 3)檔案下載下傳
    • 4)檔案重命名
    • 5)檔案移動和重命名
    • 6)檔案删除
    • 7)檢視檔案詳情
    • 8)判斷是否是檔案
  • 四 HDFS 的讀寫流程(面試重點)
    • 1) 寫資料
    • 2)讀資料
  • 五 NameNode 和 SecondaryNameNode
    • 1)第一階段:NameNode 啟動
    • 2)第二階段:Secondary NameNode 工作
    • 3) Fsimage 和 Edits 解析
    • 4) CheckPoint 時間設定
  • 六 DataNode
    • 1)DataNode 工作機制
    • 2) 資料完整性
    • 3) 掉線時限參數設定
  • 總結

前言

随着資料量越來越大,在一個作業系統存不下所有的資料,那麼就配置設定到更多的操作系

統管理的磁盤中,但是不友善管理和維護,迫切需要一種系統來管理多台機器上的檔案,這

就是分布式檔案管理系統。HDFS 隻是分布式檔案管理系統中的一種。

一、hdfs概述?

1) 介紹

HDFS(Hadoop Distributed File System),它是一個檔案系統,用于存儲檔案,通過目

錄樹來定位檔案;其次,它是分布式的,由很多伺服器聯合起來實作其功能,叢集中的服務

器有各自的角色。

HDFS 的使用場景:适合一次寫入,多次讀出的場景。一個檔案經過建立、寫入和關閉

之後就不需要改變。

2) 優缺點

優:

高容錯性

處理大量資料

建構廉價機器

缺:

不适合低延遲時資料通路做不到毫秒級存儲資料

無法高效的對大量小檔案進行儲存

不支援并發寫入和檔案随機修改 僅僅支援追加

3)組成

NameNode(nn):它是一個主管 管理hdfs名字空間 配置副本政策 管理資料塊映射資訊 處理用戶端讀寫

DataNode:實際的存儲空間 執行NameNode下達的指令

Secondary NameNode:輔助NameNode。當NameNode挂掉的時候,它并不

能馬上替換NameNode并提供服務。緊急情況可以輔助恢複NameNode

4)HDFS 檔案塊大小(面試重點)

HDFS中的檔案在實體上是分塊存儲(Block),塊的大小可以通過配置參數

( dfs.blocksize)來規定,預設大小在Hadoop2.x/3.x版本中是128M,1.x版本中是64M。

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

(1)HDFS的塊設定太小,會增加尋址時間,程式一直在找塊的開始位置;

(2)如果塊設定的太大,從磁盤傳輸資料的時間會明顯大于定位這個塊開

始位置所需的時間。導緻程式在處理這塊資料時,會非常慢。

總結:HDFS塊的大小設定主要取決于磁盤傳輸速率 不能設定太小也不能設定太大

二、hdfs shell操作

1).啟動叢集

代碼如下(示例):

start-dfs.sh
           

hadoop fs 具體指令 OR hdfs dfs 具體指令

兩個是完全相同的。

2).基本指令介紹

-help:輸出這個指令參數

-mkdir 建立/123 檔案夾

hadoop fs -mkdir /123
           

-moveFromLocal:從本地剪切粘貼到 HDFS

hadoop fs -moveFromLocal ./123.txt  /1234
           

-copyFromLocal:從本地檔案系統中拷貝檔案到 HDFS 路徑去

hadoop fs -copyFromLocal 123.txt /1234
           

-put:等同于 copyFromLocal,生産環境更習慣用 put

hadoop fs -put 123.txt /1234
           

-appendToFile:追加一個檔案到已經存在的檔案末尾

hadoop fs -appendToFile 123.txt /1234/123.txt
           

-copyToLocal:從 HDFS 拷貝到本地

hadoop fs -copyToLocal /1234/123.txt ./
           

-get:等同于 copyToLocal,生産環境更習慣用 get

hadoop fs -get /1234/123.txt ./
           

-ls: 顯示目錄資訊

hadoop fs -ls /
           

-cat:顯示檔案内容

hadoop fs -cat /123.txt
           

-chgrp、-chmod、-chown:Linux 檔案系統中的用法一樣,修改檔案所屬權限

hadoop fs -chmod 666 /123.txt
 hadoop fs -chown user:group  /123.txt
           

-cp:從 HDFS 的一個路徑拷貝到 HDFS 的另一個路徑

hadoop fs -cp /123.txt /1234/123.txt
           

-mv:在 HDFS 目錄中移動檔案

hadoop fs -mv /123.txt  /1234/123.txt
           

-tail:顯示一個檔案的末尾 1kb 的資料

hadoop fs -tail /1234/123.txt
           

-rm:删除檔案或檔案夾

hadoop fs -rm /1234/123.txt
           

-rm -r:遞歸删除目錄及目錄裡面内容

hadoop fs -rm -r /123
           

-du 統計檔案夾的大小資訊

hadoop fs -du -s -h /123 
           

-setrep:設定 HDFS 中檔案的副本數量

hadoop fs -setrep 10 /123.txt
           

這裡設定的副本數隻是記錄在 NameNode 的中繼資料中,是否真的會有這麼多副本,還得看 DataNode 的數量。因為目前隻有 3 台裝置,最多也就 3 個副本,隻有節點數的增加到 10台時,副本數才能達到 10。

三 hdfs API操作

下載下傳hadoop win版本

需要下載下傳winutils.exe,需要對應的版本.位址https://github.com/steveloughran/winutils,下載下傳之後直接解壓,将bin目錄裡的内容直接覆寫到hadoop的bin

然後配置環境變量

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

建立一個springboot工程并導入相應的依賴坐标+日志添加

<dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-slf4j-impl</artifactId>
 <version>2.9.1</version>
 </dependency>
 <dependency>
 <groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
 <version>3.1.3</version>
 </dependency>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.12</version>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>1.7.30</version>
 </dependency>
           

在項目的 src/main/resources 目錄下,建立一個檔案,命名為“log4j.properties”,在檔案

中填入

log4j.rootLogger=INFO, stdout 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n 
log4j.appender.logfile=org.apache.log4j.FileAppender 
log4j.appender.logfile.File=target/spring.log 
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout 
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
           

建立一個測試類

1)檔案建立

package com.example.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

public class HdfsClient {
    @Test
    public void testMkdirs() throws IOException, URISyntaxException, InterruptedException {
        Configuration configuration = new Configuration();

		//擷取連接配接HDFS檔案系統
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:8020"),configuration,"root");
        // 2 建立目錄
        fs.mkdirs(new Path("/test"));
        // 3 關閉資源
        fs.close();
    }
}

           

建立成功

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

2)檔案上傳

@Test
    public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {
        // 1 擷取檔案系統
        Configuration configuration = new Configuration();
        //設定檔案副本個數并且此參數優先級最高
        configuration.set("dfs.replication", "2");
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:8020"), configuration, "root");
        // 2 上傳檔案
        fs.copyFromLocalFile(new Path("D:\\test\\test.txt"), new Path("/test/"));
        // 3 關閉資源
        fs.close();
    }
           

參數優先級排序:(1)用戶端代碼中設定的值 >(2)ClassPath 下的使用者自定義配置文

件 >(3)然後是伺服器的自定義配置(xxx-site.xml)>(4)伺服器的預設配置(xxx-default.xml)

3)檔案下載下傳

@Test
    public void testCopyToLocalFile() throws IOException,
            InterruptedException, URISyntaxException{
        // 1 擷取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:8020"), configuration, "root");

        // 2 執行下載下傳操作
        // boolean delSrc 指是否将原檔案删除
        // Path src 指要下載下傳的檔案路徑
        // Path dst 指将檔案下載下傳到的路徑
        // boolean useRawLocalFileSystem 是否開啟檔案校驗
        fs.copyToLocalFile(false, new Path("/test/"), new Path("D:\\test.txt"), true);
        // 3 關閉資源
        fs.close();
    }
           

4)檔案重命名

@Test
    public void testRename() throws IOException, InterruptedException, URISyntaxException{
// 1 擷取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:8020"), configuration, "atguigu");
// 2 修改檔案名稱
        fs.rename(new Path("/text"), new Path("/text1.txt"));
// 3 關閉資源
        fs.close();
    }
           

5)檔案移動和重命名

@Test
    public void testRename() throws IOException, InterruptedException, URISyntaxException{
// 1 擷取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:8020"), configuration, "root");
// 2 修改檔案名稱
        fs.rename(new Path("/test"), new Path("/text1234567"));
// 3 關閉資源
        fs.close();
    }

           

6)檔案删除

@Test
    public void testDelete() throws IOException, InterruptedException, URISyntaxException{
// 1 擷取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:8020"), configuration, "root");
// 2 執行删除 true為遞歸删除
        fs.delete(new Path("/test1234567"), true);
// 3 關閉資源
        fs.close();
    }
           

7)檢視檔案詳情

@Test
    public void testListFiles() throws IOException, InterruptedException, URISyntaxException {
// 1 擷取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:8020"), configuration, "root");
// 2 擷取檔案詳情 true遞歸查詢
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
        while (listFiles.hasNext()) {
            LocatedFileStatus fileStatus = listFiles.next();
            System.out.println("========" + fileStatus.getPath() + "=========");
            System.out.println(fileStatus.getPermission());
            System.out.println(fileStatus.getOwner());
            System.out.println(fileStatus.getGroup());
            System.out.println(fileStatus.getLen());
            System.out.println(fileStatus.getModificationTime());
            System.out.println(fileStatus.getReplication());
            System.out.println(fileStatus.getBlockSize());
            System.out.println(fileStatus.getPath().getName());
// 擷取塊資訊
            BlockLocation[] blockLocations = fileStatus.getBlockLocations();
            System.out.println(Arrays.toString(blockLocations));
        }
// 3 關閉資源
        fs.close();
    }
           

8)判斷是否是檔案

@Test
    public void testListStatus() throws IOException, InterruptedException,
            URISyntaxException{
        // 1 擷取檔案配置資訊
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:8020"),
                configuration, "root");
        // 2 判斷是檔案還是檔案夾
        FileStatus[] listStatus = fs.listStatus(new Path("/"));
        for (FileStatus fileStatus : listStatus) {
            // 如果是檔案
            if (fileStatus.isFile()) {
                System.out.println("f:"+fileStatus.getPath().getName());
            }else {
                System.out.println("d:"+fileStatus.getPath().getName());
            }
        }
        // 3 關閉資源
        fs.close();
    }
           

四 HDFS 的讀寫流程(面試重點)

1) 寫資料

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

(1)用戶端通過 Distributed FileSystem 子產品向 NameNode 請求上傳檔案,NameNode 檢查目标檔案是否已存在,父目錄是否存在。

(2)NameNode 傳回是否可以上傳。

(3)用戶端請求第一個 Block 上傳到哪幾個 DataNode 伺服器上。

(4)NameNode 傳回 3 個 DataNode 節點,分别為 dn1、dn2、dn3。 (5)用戶端通過 FSDataOutputStream 子產品請求 dn1 上傳資料,dn1 收到請求會繼續調用

dn2,然後 dn2 調用 dn3,将這個通信管道建立完成。

(6)dn1、dn2、dn3 逐級應答用戶端。

(7)用戶端開始往 dn1 上傳第一個 Block(先從磁盤讀取資料放到一個本地記憶體緩存),

以 Packet 為機關,dn1 收到一個 Packet 就會傳給 dn2,dn2 傳給 dn3;dn1 每傳一個 packet

會放入一個應答隊列等待應答。

(8)當一個 Block 傳輸完成之後,用戶端再次請求 NameNode 上傳第二個 Block 的服務

器。(重複執行 3-7 步)。

提問

在 HDFS 寫資料的過程中,NameNode 會選擇距離待上傳資料最近距離的 DataNode 接

收資料。那麼這個最近距離怎麼計算呢?

節點距離:兩個節點到達最近的共同父節點的距離總和

2)讀資料

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

(1)用戶端通過 DistributedFileSystem 向 NameNode 請求下載下傳檔案,NameNode 通過查

詢中繼資料,找到檔案塊所在的 DataNode 位址。

(2)挑選一台 DataNode(就近原則,然後随機)伺服器,請求讀取資料。 (3)DataNode 開始傳輸資料給用戶端(從磁盤裡面讀取資料輸入流,以 Packet 為機關

來做校驗)。

(4)用戶端以 Packet 為機關接收,先在本地緩存,然後寫入目标檔案。

五 NameNode 和 SecondaryNameNode

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

1)第一階段:NameNode 啟動

(1)第一次啟動 NameNode 格式化後,建立 Fsimage 和 Edits 檔案。如果不是第一次啟動,直接加載編輯日志和鏡像檔案到記憶體。

(2)用戶端對中繼資料進行增删改的請求。

(3)NameNode 記錄記錄檔,更新滾動日志。

(4)NameNode 在記憶體中對中繼資料進行增删改

2)第二階段: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。

3) Fsimage 和 Edits 解析

NameNode被格式化之後,将在/opt/module/hadoop-3.1.3/data/tmp/dfs/name/current目錄中産生如下檔案

(1)Fsimage檔案:HDFS檔案系統中繼資料的一個永久性的檢查點,其中包含HDFS檔案系統的所有目

錄和檔案inode的序列化資訊。

fsimage_0000000000000000000
fsimage_0000000000000000000.md5
seen_txid
VERSION
           

(2)Edits檔案:存放HDFS檔案系統的所有更新操作的路徑,檔案系統用戶端執行的所有寫操作首先

會被記錄到Edits檔案中。

(3)seen_txid檔案儲存的是一個數字,就是最後一個edits_的數字

(4)每 次NameNode啟動的時候都會将Fsimage檔案讀入記憶體,加 載Edits裡面的更新操作,保證記憶體中的中繼資料資訊是最新的、同步的,可以看成NameNode啟動的時候就将Fsimage和Edits檔案進行了合并。

要用檢視 oiv 和 oev 指令才能檢視

hdfs oiv -p 檔案類型 -i 鏡像檔案 -o 轉換後檔案輸出路徑
           

4) CheckPoint 時間設定

(1)通常情況下,SecondaryNameNode 每隔一小時執行一次。

[hdfs-default.xml]

<property>
 <name>dfs.namenode.checkpoint.period</name>
 <value>3600s</value>
</property>
           

(2)一分鐘檢查一次操作次數,當操作次數達到 1 百萬時,SecondaryNameNode 執行一次。

<property>
<name>dfs.namenode.checkpoint.txns</name>
 <value>1000000</value>
<description>操作動作次數</description>
</property>
<property>
 <name>dfs.namenode.checkpoint.check.period</name>
 <value>60s</value>
<description> 1 分鐘檢查一次操作次數</description>
</property>
           

六 DataNode

1)DataNode 工作機制

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

(1)一個資料塊在 DataNode 上以檔案形式存儲在磁盤上,包括兩個檔案,一個是資料

本身,一個是中繼資料包括資料塊的長度,塊資料的校驗和,以及時間戳。

(2)DataNode 啟動後向 NameNode 注冊,通過後,周期性(6 小時)的向 NameNode 上

報所有的塊資訊。

DN 向 NN 彙報目前解讀資訊的時間間隔,預設 6 小時;

<property>
<name>dfs.blockreport.intervalMsec</name>
<value>21600000</value>
<description>Determines block reporting interval in 
milliseconds.</description>
</property>
           

DN 掃描自己節點塊資訊清單的時間,預設 6 小時

<property>
<name>dfs.datanode.directoryscan.interval</name>
<value>21600s</value>
<description>Interval in seconds for Datanode to scan datadirectories and reconcile the difference between blocks in memory and on 
the disk.
Support multiple time unit suffix(case insensitive), as described
in dfs.heartbeat.interval.
</description>
</property>
           

(3)心跳是每 3 秒一次,心跳傳回結果帶有 NameNode 給該 DataNode 的指令如複制塊

資料到另一台機器,或删除某個資料塊。如果超過 10 分鐘沒有收到某個 DataNode 的心跳,

則認為該節點不可用。

(4)叢集運作中可以安全加入和退出一些機器。

2) 資料完整性

(1)當 DataNode 讀取 Block 的時候,它會計算 CheckSum。

(2)如果計算後的 CheckSum,與 Block 建立時值不一樣,說明 Block 已經損壞。

(3)Client 讀取其他 DataNode 上的 Block。

(4)常見的校驗算法 crc(32),md5(128),sha1(160)

(5)DataNode 在其檔案建立後周期驗證 CheckSum。

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

3) 掉線時限參數設定

HDFS重點HDFS精選【精簡】前言一、hdfs概述?二、hdfs shell操作三 hdfs API操作四 HDFS 的讀寫流程(面試重點)五 NameNode 和 SecondaryNameNode六 DataNode總結

需要注意的是 hdfs-site.xml 配置檔案中的 heartbeat.recheck.interval 的機關為毫秒,

dfs.heartbeat.interval 的機關為秒。

<property>
 <name>dfs.namenode.heartbeat.recheck-interval</name>
 <value>300000</value>
</property>
<property>
 <name>dfs.heartbeat.interval</name>
 <value>3</value>
</property>
           

總結

1、HDFS檔案塊大小(面試重點)

硬碟讀寫速度

在企業中 一般128m(中小公司) 256m (大公司)

2、HDFS的Shell操作(開發重點)

3、HDFS的讀寫流程(面試重點)

繼續閱讀