Hadoop 基礎之 HDFS 入門

ikroal發表於2019-05-13

前言

本文主要介紹了 HDFS 的體系架構以及其執行流程,並給出了讀寫操作的程式設計例項,希望對 HDFS 有個初步的認識。

簡介

HDFS (Hadoop Distributed File System) 是一個執行在商業 PC 上的分散式檔案系統,其設計思想源自於 Google 2003 年釋出的論文 The Google File System 。HDFS的主要目的是為了解決大規模資料儲存和管理的問題。

體系架構

Hadoop 基礎之 HDFS 入門

上圖表明 HDFS 是一個標準的 master/slave 架構,主要由三個部分構成:

  1. NameNode(master 節點)
    • 後設資料(MetaData)的管理,其中後設資料由檔案路徑名資料塊ID以及儲存位置等資訊構成
    • 管理 HDFS 的名字空間。
  2. SecondaryNameNode
    • 定期合併 NameNode 的 edit logs(對檔案系統的改動序列) 到 fsimage(對整個檔案系統的快照),並拷貝修改後的 fsimage 到 NameNode。
    • 提供一個 NameNode 的檢查點(切忌認為是 NameNode 的備份),可用於 NameNode 的故障恢復。
  3. DataNode(slave 節點)
    • 提供檔案儲存和進行資料塊操作。
    • 週期性的向 NameNode 彙報塊資訊。

這裡對圖中出現的一些概念進行說明:

  1. Replication(副本)

    為了保證資料的高可用,HDFS 會對寫入的資料進行冗餘儲存,預設情況下會儲存 3 份。

  2. Blocks

    Block 是最基本的儲存和操作單位(預設情況下為 128M),這裡的 Block 不是指物理 Block ,而是指檔案系統的 Block,其大小一般是物理 Block 的整數倍。

執行流程

讀檔案

Hadoop 基礎之 HDFS 入門

讀檔案的過程可以概括為:

  1. Client 向 NameNode 發起請求獲取檔案資料塊位置資訊
  2. Client 按照資料塊距 Client 的遠近依次進行連線然後讀取資料

寫檔案

Hadoop 基礎之 HDFS 入門

寫檔案的過程可以概括為:

  1. Client 向 NameNode 發起寫檔案的請求獲得可寫的 DataNode 列表等資訊
  2. Client 根據 HDFS 設定的分塊大小對檔案進行分塊
  3. Client 和 NameNode 分配的 DataNode 構成 pipeline 並進行資料寫入
  4. 寫入完成之後,NameNode 接收來自 DataNode 的訊息進行後設資料的更新

常用命令

檔案操作

  1. 列出檔案

    hdfs dfs -ls <path>
    複製程式碼
  2. 建立目錄

    hdfs dfs -mkdir <path>
    複製程式碼
  3. 上傳檔案

    hdfs dfs -put <localsrc> <dst>
    複製程式碼
  4. 輸出檔案內容

    hdfs dfs -cat <src>
    複製程式碼
  5. 檔案複製到本地

    hdfs dfs -get <src> <localdst>
    複製程式碼
  6. 刪除檔案和目錄

    hdfs dfs -rm <src>
    hdfs dfs -rmdir <dir>
    複製程式碼

管理

  1. 檢視統計資訊

    hdfs dfsadmin -report
    複製程式碼
  2. 進入和退出安全模式(該模式不允許檔案系統有任何修改)

    hdfs dfsadmin -safemode enter
    hdfs dfsadmin -safemode leave
    複製程式碼

程式設計例項

  1. IDEA 新建 Maven 專案

    在這裡插入圖片描述

    勾選相關選項後,點選 next 填入專案相關資訊即可

  2. pom.xml 中新增依賴

    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.9.2</version> //根據 Hadoop 版本進行選擇
        </dependency>
    
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.9.2</version>
        </dependency>
    
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.9.2</version>
        </dependency>
    </dependencies>
    
    複製程式碼
  3. 讀寫檔案

    建立 Sample 類編寫相應的讀寫函式

    • Sample 類

      import org.apache.hadoop.conf.Configuration;
      import org.apache.hadoop.fs.FSDataInputStream;
      import org.apache.hadoop.fs.FSDataOutputStream;
      import org.apache.hadoop.fs.FileSystem;
      import org.apache.hadoop.fs.Path;
      
      import java.io.*;
      
      /**
       * @author ikroal
       */
      public class Sample {
          //預設的 HDFS 地址
          private static final String DEFAULT_FS = "hdfs://localhost:9000";
          private static final String PATH = DEFAULT_FS + "/tmp/demo.txt";
          private static final String DEFAULT_FILE = "demo.txt";
      
          public static void main(String[] args) {
              Configuration conf = new Configuration();
              FileSystem fs = null;
              conf.set("fs.defaultFS", DEFAULT_FS); //配置 HDFS 地址
      
              try {
                  fs = FileSystem.get(conf);
                  write(fs, DEFAULT_FILE, PATH);
                  read(fs, PATH);
              } catch (IOException e) {
                  e.printStackTrace();
              } finally {
                  try {
                      if (fs != null) {
                          fs.close();
                      }
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
      複製程式碼
    • write 函式

      /**
      * 進行檔案寫入
      * @param inputPath 待寫入檔案路徑
      * @param outPath HDFS 的寫入路徑
      */
      public static void write(FileSystem fileSystem, String inputPath, String outPath) {
          FSDataOutputStream outputStream = null;
          FileInputStream inputStream = null;
          try {
              outputStream = fileSystem.create(new Path(outPath)); //獲得 HDFS 的寫入流
              inputStream = new FileInputStream(inputPath); //讀取本地檔案
              int data;
              while ((data = inputStream.read()) != -1) { //寫入操作
                  outputStream.write(data);
              }
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              try {
                  if (outputStream != null) {
                      outputStream.close();
                  }
                  if (inputStream != null) {
                      inputStream.close();
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      複製程式碼
    • read 函式

      /**
      * 進行檔案讀取
      * @param path HDFS 上待讀取檔案路徑
      */
      public static void read(FileSystem fileSystem, String path) {
          FSDataInputStream inputStream = null;
          BufferedReader reader = null;
          try {
              inputStream = fileSystem.open(new Path(path)); //獲取 HDFS 讀取流
              reader = new BufferedReader(new InputStreamReader(inputStream));
              String content;
              while ((content = reader.readLine()) != null) { //讀取並輸出到控制檯
                  System.out.println(content);
              }
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              try {
                  if (inputStream != null) {
                      inputStream.close();
                  }
                  if (reader != null) {
                      reader.close();
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      複製程式碼
  4. 在工程資料夾的根目錄下建立計劃上傳的檔案(這裡是 demo.txt),填入 Hello World!

  5. 啟動 Hadoop 然後執行程式檢視結果

    通過 http://localhost:50070/explorer.html#/ 可以檢視寫入結果

    Hadoop 基礎之 HDFS 入門

    控制檯則會輸出上傳檔案的內容

    Hadoop 基礎之 HDFS 入門

Thanks

  1. 初步掌握HDFS的架構及原理
  2. 深入理解HDFS:Hadoop分散式檔案系統
  3. HDFS讀寫流程(史上最精煉詳細)
  4. Hadoop學習之路(十一)HDFS的讀寫詳解

相關文章