1. 程式人生 > >Hadoop學習筆記—2.不怕故障的海量儲存:HDFS基礎入門

Hadoop學習筆記—2.不怕故障的海量儲存:HDFS基礎入門

一.HDFS出現的背景

  隨著社會的進步,需要處理資料量越來越多,在一個作業系統管轄的範圍存不下了,那麼就分配到更多的作業系統管理的磁碟中,但是卻不方便管理和維護—>因此,迫切需要一種系統來管理多臺機器上的檔案,於是就產生了分散式檔案管理系統,英文名成為DFSDistributed File System)。

  那麼,什麼是分散式檔案系統?簡而言之,就是一種允許檔案通過網路在多臺主機上分享的檔案系統,可以讓多個機器上的多個使用者分享檔案和儲存空間。它最大的特點是“通透性”,DFS讓實際上是通過網路來訪問檔案的動作,由使用者和程式看來,就像是訪問本地的磁碟一般(In other words,使用DFS訪問資料,你感覺不到是訪問遠端不同機器上的資料)。

圖1.一個典型的DFS示例

二.深入瞭解HDFS原理

  作為Hadoop的核心技術之一,HDFS(Hadoop Distributed File System,Hadoop分散式檔案系統)是分散式計算中資料儲存管理的基礎。它所具有的高容錯、高可靠、高可擴充套件性、高吞吐率等特性為海量資料提供了不怕故障的儲存,也為超大規模資料集(Large Data Set)的應用處理帶來了很多便利。

  圖2.Hadoop HDFS的LOGO

  提到HDFS,不得不說Google的GFS。正是Google發表了關於GFS的論文,才有了HDFS這個關於GFS的開源實現。

2.1 設計前提與目標

  (1)硬體錯誤是常態而不是異常;(最核心的設計目標—>HDFS被設計為執行在眾多的普通硬體上,所以硬體故障是很正常的。因此,錯誤檢測並快速恢復是HDFS最核心的設計目標)

  (2)流式資料訪問;(HDFS更關注資料訪問的高吞吐量)

  (3)大規模資料集;(HDFS的典型檔案大小大多都在GB甚至TB級別)

  (4)簡單一致性模型;(一次寫入,多次讀取的訪問模式)

  (5)移動計算比移動資料更為划算;(對於大檔案來說,移動計算比移動資料的代價要低)

2.2 HDFS的體系結構

  HDFS是一個主/從(Master/Slave)式的結構,如下圖所示。

  

  圖3.HDFS的基本架構

  從終端使用者的角度來看,它就像傳統的檔案系統一樣,可以通過目錄路徑對檔案執行CRUD(增刪查改)操作。但由於分散式儲存的性質,HDFS擁有一個NameNode和一些DataNodes。NameNode管理檔案系統的元資料,DataNode儲存實際的資料。客戶端通過同NameNode和DataNode的互動訪問檔案系統→客戶端聯絡NameNode以獲取檔案的元資料,而真正的I/O操作是直接和DataNode進行互動的。

  下面我們再來看看HDFS的讀操作和寫操作的流程:

  ①讀操作

  圖4.HDFS的讀操作

  客戶端要訪問一個檔案,首先,客戶端從NameNode中獲得組成該檔案資料塊位置列表,即知道資料塊被儲存在哪幾個DataNode上;然後,客戶端直接從DataNode上讀取檔案資料。在此過程中,NameNode不參與檔案的傳輸。

  ②寫操作

write

圖5.HDFS的寫操作

  客戶端首先需要向NameNode發起寫請求,NameNode會根據檔案大小和檔案塊配置情況,返回給Client它所管理部分DataNode的資訊。最後,Client(開發庫)將檔案劃分為多個檔案塊,根據DataNode的地址資訊,按順序寫入到每一個DataNode塊中。

  下面我們看看NameNode和DataNode扮演什麼角色,有什麼具體的作用:

  (1)NameNode

  NameNode的作用是管理檔案目錄結構,是管理資料節點的。NameNode維護兩套資料:一套是檔案目錄與資料塊之間的關係,另一套是資料塊與節點間的關係。前一套是靜態的,是存放在磁碟上的,通過fsimage和edits檔案來維護;後一套資料時動態的,不持久化到磁碟,每當叢集啟動的時候,會自動建立這些資訊。

  (2)DataNode

  毫無疑問,DataNode是HDFS中真正儲存資料的。這裡要提到一點,就是Block(資料塊)。假設檔案大小是100GB,從位元組位置0開始,每64MB位元組劃分為一個Block,以此類推,可以劃分出很多的Block。每個Block就是64MB(也可以自定義設定Block大小)。

  (3)典型部署

  HDFS的一個典型部署是在一個專門的機器上執行NameNode,叢集中的其他機器各執行一個DataNode。(當然,也可以在執行NameNode的機器上同時執行DataNode,或者一個機器上執行多個DataNode)一個叢集中只有一個NameNode(但是單NameNode存在單點問題,在Hadoop 2.x版本之後解決了這個問題)的設計大大簡化了系統架構。

2.3 保障HDFS的可靠性措施

  HDFS具備了較為完善的冗餘備份和故障恢復機制,可以實現在叢集中可靠地儲存海量檔案。

  (1)冗餘備份:HDFS將每個檔案儲存成一系列的資料塊Block),預設塊大小為64MB(可以自定義配置)。為了容錯,檔案的所有資料塊都可以有副本(預設為3個,可以自定義配置)。當DataNode啟動的時候,它會遍歷本地檔案系統,產生一份HDFS資料塊和本地檔案對應關係的列表,並把這個報告發送給NameNode,這就是報告塊(BlockReport),報告塊上包含了DataNode上所有塊的列表。

  (2)副本存放:HDFS叢集一般執行在多個機架上,不同機架上機器的通訊需要通過交換機。通常情況下,副本的存放策略很關鍵,機架內節點之間的頻寬比跨機架節點之間的頻寬要大,它能影響HDFS的可靠性和效能。HDFS採用一種稱為機架感知(Rack-aware)的策略來改進資料的可靠性、可用性和網路頻寬的利用率。在大多數情況下,HDFS副本系數是預設為3,HDFS的存放策略是將一個副本存放在本地機架節點上,一個副本存放在同一個機架的另一個節點上,最後一個副本放在不同機架的節點上。這種策略減少了機架間的資料傳輸,提高了寫操作的效率。機架的錯誤遠遠比節點的錯誤少所以這種策略不會影響到資料的可靠性和可用性。

  圖6.副本存放的策略

  (3)心跳檢測:NameNode週期性地從叢集中的每個DataNode接受心跳包和塊報告,NameNode可以根據這個報告驗證對映和其他檔案系統元資料。收到心跳包,說明該DataNode工作正常。如果DataNode不能傳送心跳資訊,NameNode會標記最近沒有心跳的DataNode為宕機,並且不會給他們傳送任何I/O請求。

  (4)安全模式

  (5)資料完整性檢測

  (6)空間回收

  (7)元資料磁碟失效

  (8)快照(HDFS目前還不支援)

三.HDFS常用Shell操作

  (1)列出檔案目錄:hadoop fs -ls 目錄路徑

     檢視HDFS根目錄下的目錄:hadoop fs -ls /

     遞迴檢視HDFS根目錄下的目錄:hadoop fs -lsr /

  (2)在HDFS中建立資料夾:hadoop fs -mkdir 資料夾名稱

    在根目錄下建立一個名稱為di的資料夾:

  (3)上傳檔案到HDFS中:hadoop fs -put 本地源路徑 目標存放路徑

    將本地系統中的一個log檔案上傳到di資料夾中:hadoop fs -put test.log /di

*PS:我們通過Hadoop Shell上傳的檔案是存放在DataNode的Block(資料塊)中的,通過Linux Shell是看不到檔案的,只能看到Block。因此,可以用一句話來描述HDFS:把客戶端的大檔案存放在很多節點的資料塊中。

  (4)從HDFS中下載檔案:hadoop fs -get HDFS檔案路徑 本地存放路徑

    將剛剛上傳的test.log下載到本地的Desktop資料夾中:hadoop fs -get /di/test.log /home/hadoop/Desktop

  (5)直接在HDFS中檢視某個檔案:hadoop fs -text(-cat) 檔案存放路徑

在HDFS檢視剛剛上傳的test.log檔案:hadoop fs -text /di/test.log

  (6)刪除在HDFS中的某個檔案(夾):hadoop fs -rm(r) 檔案存放路徑

刪除剛剛上傳的test.log檔案:hadoop fs -rm /di/test.log

    刪除HDFS中的di資料夾:hadoop fs -rmr /di

  (7)善用help命令求幫助:hadoop fs -help 命令

    檢視ls命令的幫助:hadoop fs -help ls

四.使用Java操作HDFS

  我們在工作中寫完的各種程式碼是在伺服器中執行的,HDFS的操作程式碼也不例外。在開發階段,我們使用Windows下的Eclipse作為開發環境,訪問執行在虛擬機器中的HDFS,也就是通過在本地的Eclipse中的Java程式碼訪問遠端Linux中的HDFS。

  在本地的開發除錯過程中,要使用宿主機中的Java程式碼訪問客戶機中的HDFS,需要確保以下幾點:
宿主機和虛擬機器的網路能否互通?確保宿主機和虛擬機器中的防火牆都關閉!確保宿主機與虛擬機器中的jdk版本一致!                                 

  4.1 準備工作:

  (1)匯入依賴jar包,如下圖所示

  

  (2)關聯hadoop原始碼專案,如下圖所示

  

  4.2 第一個Java-HDFS程式

  (1)定義HDFS_PATH:public static final String HDFS_PATH = "hdfs://hadoop-master:9000/testdir/testfile.log";

  (2)讓URL型別識別hdfs://(URL型別預設只識別http://):URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());

  (3)具體詳細程式碼如下:

 1 package hdfs;
 2 
 3 import java.io.InputStream;
 4 import java.net.MalformedURLException;
 5 import java.net.URL;
 6 
 7 import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
 8 import org.apache.hadoop.io.IOUtils;
 9 
10 public class firstApp {
11     
12     public static final String HDFS_PATH = "hdfs://hadoop-master:9000/testdir/testfile.log";
13     
14     /**
15      * @param args
16      * @throws MalformedURLException 
17      */
18     public static void main(String[] args) throws Exception {
19         // TODO Auto-generated method stub
20         URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
21         final URL url = new URL(HDFS_PATH);
22         final InputStream in = url.openStream();
23         /**
24          * @params in 輸入流
25          * @params out 輸出流
26          * @params buffersize 緩衝區大小
27          * @params close 是否自動關閉流
28          */
29         IOUtils.copyBytes(in, System.out, 1024, true);
30     }
31 
32 }
View Code

    (4)執行結果(後面不再貼執行結果圖):

  

  4.3 對HDFS進行CRUD程式設計

  (1)獲得萬能的大神物件:final FileSystem fileSystem = FileSystem.get(new URI(HDFS_PATH),new Configuration());

  (2)呼叫HDFS API進行CRUD操作,詳情見下程式碼

public class FileSystemApp {

    private static final String HDFS_PATH = "hdfs://hadoop-master:9000/testdir/";
    private static final String HDFS_DIR = "/testdir/dir1";

    public static void main(String[] args) throws Exception {
        FileSystem fs = getFileSystem();

        // 01.建立資料夾  對應shell:mkdir
        createDirectory(fs);

        // 02.刪除檔案  對應shell:hadoop fs -rm(r) xxx
        deleteFile(fs);

        // 03.上傳檔案  對應shell:hadoop fs -input xxx
        uploadFile(fs);

        // 04.下載檔案  對應shell:hadoop fs -get xxx xxx
        downloadFile(fs);

        // 05.瀏覽資料夾  對應shell:hadoop fs -lsr /
        listFiles(fs,"/");
    }

    private static void listFiles(FileSystem fs,String para) throws IOException {
        final FileStatus[] listStatus = fs.listStatus(new Path(para));
        for (FileStatus fileStatus : listStatus) {
            String isDir = fileStatus.isDir() ? "Directory" : "File";
            String permission = fileStatus.getPermission().toString();
            short replication = fileStatus.getReplication();
            long length = fileStatus.getLen();
            String path = fileStatus.getPath().toString();
            System.out.println(isDir + "\t" + permission + "\t" + replication
                    + "\t" + length + "\t" + path);
            
            if(isDir.equals("Directory")){
                listFiles(fs, path);
            }
        }
    }

    private static void downloadFile(FileSystem fs) throws IOException {
        final FSDataInputStream in = fs.open(new Path(HDFS_PATH + "check.log"));
        final FileOutputStream out = new FileOutputStream("E:\\check.log");
        IOUtils.copyBytes(in, out, 1024, true);
        System.out.println("Download File Success!");
    }

    private static void uploadFile(FileSystem fs) throws IOException {
        final FSDataOutputStream out = fs.create(new Path(HDFS_PATH
                + "check.log"));
        final FileInputStream in = new FileInputStream("C:\\CheckMemory.log");
        IOUtils.copyBytes(in, out, 1024, true);
        System.out.println("Upload File Success!");
    }

    private static void deleteFile(FileSystem fs) throws IOException {
        fs.delete(new Path(HDFS_DIR), true);
        System.out.println("Delete File:" + HDFS_DIR + " Success!");
    }

    private static void createDirectory(FileSystem fs) throws IOException {
        fs.mkdirs(new Path(HDFS_DIR));
        System.out.println("Create Directory:" + HDFS_DIR + " Success!");
    }

    private static FileSystem getFileSystem() throws IOException,
            URISyntaxException {
        return FileSystem.get(new URI(HDFS_PATH), new Configuration());
    }

}
View Code

參考文獻與資料

作者:周旭龍

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。

相關推薦

Hadoop學習筆記2.不怕故障海量儲存HDFS基礎入門

一.HDFS出現的背景   隨著社會的進步,需要處理資料量越來越多,在一個作業系統管轄的範圍存不下了,那麼就分配到更多的作業系統管理的磁碟中,但是卻不方便管理和維護—>因此,迫切需要一種系統來管理多臺機器上的檔案,於是就產生了分散式檔案管理系統,英文名成為DFS(Distributed File Sy

Hadoop 學習筆記 (2) -- 關於MapReduce

規模 pre 分析 bsp 學習筆記 reduce 數據中心 階段 圖例 1. MapReduce 定義: 是一種可用於數據處理的編程的模型 優勢: MapReduce 本質上是並行運行的,因此可以將大規模的數據分析任務,分發給任何一個擁有足夠多機器

hadoop學習筆記2---hadoop的三種運行模式

hadoop1、單機模式安裝簡單,在一臺機器上運行服務,幾乎不用做任何配置,但僅限於調試用途。沒有分布式文件系統,直接讀寫本地操作系統的文件系統。2、偽分布式模式在單節點上同時啟動namenode、datanode、jobtracker、tasktracker、secondary namenode等進程,模擬

Day4.Hadoop學習筆記2

零、SSH密碼認證流程 一、HDFS架構 簡單瞭解HDFS HDFS借鑑了GFS的資料冗餘度思想 存在批量的硬碟;【DataNode 資料節點】 HDFS預設冗餘度為“3”,就是一份同樣資料儲存三份; 利用“水平復制”提升上傳效率; 以“資料塊”作為單

淺解MapReduce與簡單MapReduce程式出包---Hadoop學習筆記(2)

淺略理解MapReduce的概念機制是開始真正使用Hadoop開發Mapreduce程式的第一步,是一個充分條件。理解和實踐並進才能讓更多的問題暴露對理論的理解的不夠。繼續學習《Hadoop基礎教程》。 1.Map與Reduce Hado

Tiny6410學習筆記2——DRAM Controller(儲存控制器)

一些關於Tiny6410中SDRAM的科普知識 兩種啟動方式介紹 SDBOOT: 程式被直接燒入SDRAM(S3C6410中,DRAM起始地址為0x50000000)開始執行。 Nand BOOT: 程式首先被燒寫到Nand Flash中的

誰說菜鳥不會資料分析(入門篇)----- 學習筆記2(結構為王確定分析思路 4P 5W2H )

1、資料分析方法論 確定分析思路需要以營銷、管理等理論為指導,把這些跟資料分析相關的營銷、管理等理論統稱為資料分析方法論。 資料分析方法論主要用來指導資料分析師進行一次完整的資料分析,更多的是指資料分析思路,如從哪方面開展資料分析?各方面包含什麼內容和指標。 資料分析方法論主要

誰說菜鳥不會資料分析(工具篇)----- 學習筆記2(結構為王確定分析思路)

1、資料分析方法論 確定分析思路需要以營銷、管理等理論為指導,把這些跟資料分析相關的營銷、管理等理論統稱為資料分析方法論。 資料分析方法論主要用來指導資料分析師進行一次完整的資料分析,更多的是指資料分析思路,如從哪方面開展資料分析?各方面包含什麼內容和指標。 資料分析方

Hadoop學習筆記一(通過Java API 操作HDFS,檔案上傳、下載)

package demo.hdfs; import java.util.Arrays; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.BlockLocation; impor

springmvc學習筆記(一) -- 從零搭建,基礎入門

out hand char webapp core localhost list ges del 1、新建maven項目 參考mybatis學習筆記(五) -- maven+spring+mybatis從零開始搭建整合詳細過程(上)第一部分,修改配置 2、修

Hadoop學習筆記-Day 2

名詞解釋 ▪ Operations are eager when they are executed as soon as the statement is reached in the code; 勤快執行:接收到程式碼立刻執行; ▪ Operations are lazy when the execu

Hadoop學習筆記(Day1Hadoop家族體系、權威指南1、2.4章)

<本系列文章主要供自己學習Hadoop技術筆記用> 1)Hadoop家族體系 Hadoop家族成員概述 這篇文章簡明扼要地介紹了Hadoop家族各個成員的功能。 這篇文章除了介紹家族成員外,還介紹了其學習路線圖。 2)Hadoop權威指南 2.4.1

hadoop學習筆記2)偽分佈模式配置

前面介紹了linux下hadoop的安裝和簡單配置,主要是獨立模式的配置,所謂獨立模式是指不需要執行任何守護程序(daemon),所有程式都再單個JVM上執行,由於在獨立模式下測試和除錯MapReduce程式較為方便,因此該模式適合用在開發階段。 這裡主要記錄了本人配置hadoop偽分佈模式的過程。所謂

java大資料最全課程學習筆記(2)--Hadoop完全分散式執行模式

> 目前[CSDN](https://blog.csdn.net/weixin_42208775),[部落格園](https://home.cnblogs.com/u/gitBook/),[簡書](https://www.jianshu.com/u/da41700fde04)同步發表中,更多精彩歡迎訪問

hadoop學習筆記-HDFS的REST接口

字段 edi -o created hadoop ftw rar hdfs lang 在學習HDFS的過程中,重點關註了HDFS的REST訪問接口。以前對REST的認識非常籠統,這次通過對HDFS的REST接口進行實際操作,形成很直觀的認識。 1? 寫文件操作 寫文件

學習筆記2

建議 coo line 長度 cape 發展 div+css 加載 不兼容 雙標簽: <html><head><title><body><table><tr><td><span>

Jmeter學習筆記2-原件作用域與執行順序

校驗 height sse proc tro 有效 收集 技術分享 控制 1.元件的作用域 (1)配置元件(config elements):會影響其作用範圍內的所有元件。 (2)前置處理程序(per-processors):在其作用範圍內的每一個sampler元件之

python學習筆記2字符串

nbsp 大小 alpha .com format 大小寫 fin 判斷大小 key python學習筆記2:字符串 總結:字符串是不可變變量,不能通過下標修改其值    字符串的方法都不會改變字符串原來的值,而是新生成一個字符串 一、3種寫法——單引號,雙引號,三引號  

java 學習筆記2 面向對象(上)

awr ges abs nal mage 有效 面向對象 ima col 類和對象 類是某一批對象的抽象,可以把類理解成某種概念。對象是一個具體存在的實體。類和對象是面向對象的核心。 類定義的是多個實例的特征,類不是具體存在,實例才是具體存在。 定義類(class)的語法:

Git學習筆記2——Git版本庫的創建

文件添加 不但 提交 linu 記錄 例子 blog 所有 out 創建一個版本庫非常簡單,首先,選擇一個合適的地方,創建一個空目錄: $ cd s: $ cd Git_Learing $ pwd s/Git_Learning pwd命令用於顯示當前目錄。在我的wind