Hadoop 基礎之 HDFS 入門

前言

本文主要介紹了 HDFS 的體系架構以及其執行流程,並給出了讀寫操做的編程實例,但願對 HDFS 有個初步的認識。html

簡介

HDFS (Hadoop Distributed File System) 是一個運行在商業 PC 上的分佈式文件系統,其設計思想源自於 Google 2003 年發佈的論文 The Google File System 。HDFS的主要目的是爲了解決大規模數據存儲和管理的問題。java

體系架構

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

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

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

  1. Replication(副本)編程

    爲了保證數據的高可用,HDFS 會對寫入的數據進行冗餘存儲,默認狀況下會保存 3 份。安全

  2. Blocks架構

    Block 是最基本的存儲和操做單位(默認狀況下爲 128M),這裏的 Block 不是指物理 Block ,而是指文件系統的 Block,其大小通常是物理 Block 的整數倍。分佈式

執行流程

讀文件

讀文件的過程能夠歸納爲:函數

  1. Client 向 NameNode 發起請求獲取文件數據塊位置信息
  2. Client 按照數據塊距 Client 的遠近依次進行鏈接而後讀取數據

寫文件

寫文件的過程能夠歸納爲:oop

  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#/ 能夠查看寫入結果

    控制檯則會輸出上傳文件的內容

Thanks

  1. 初步掌握HDFS的架構及原理
  2. 深刻理解HDFS:Hadoop分佈式文件系統
  3. HDFS讀寫流程(史上最精煉詳細)
  4. Hadoop學習之路(十一)HDFS的讀寫詳解
相關文章
相關標籤/搜索