Hadoop-HDFS

一、Hadoop概述
Hadoop是Google的集羣系統的開源實現。

  • Google的集羣系統:GFS、MapReduce、BigTable
  • Hadoop的集羣系統:HDFS、MapReduce、HBase
    Hadoop的設計初衷是爲了解決Nutch海量數據存儲和處理需求,可以解決大數據場景下的海量數據的存儲和處理問題。

傳統數據和大數據的區別
①.傳統數據

  • GB、TB級別的數據
  • 數據增長不快
  • 主要爲結構化的數據
  • 統計和報表

②.大數據

  • TB、PB級別的數據
  • 數據持續的高速增長
  • 半結構化、非結構化的數據
  • 用於數據挖掘和預測性分析

    大數據是對海量數據的獲取、存儲、聚合和管理這些數據以及對這些數據進行深度分析和預測的新技術和新能力。

  • 大數據定義:

    定義1:所涉及的數據量規模巨大到無法通過人工,在合理時間內截取管理處理並整理成爲人類所能解讀的信息。(Dan Kusnetzky,What is “Big Data”?)

    定義2:不用隨機分析法(抽樣調查)這樣的捷徑,而採用所有數據的方法。(維克托 邁爾-舍恩伯格、肯尼斯 庫克耶,“大數據時代”)

    定義3:“大數據”是需要新處理模式才能具有更強的決策力、洞察發現力和流程優化能力的海量、高增長率和多樣化的信息資產。(“大數據”(Big Data)研究機構Gartner)

注:hadoop名字的起源:
Doug Cutting如此解釋Hadoop的得名:“這個名字是我的孩子給一頭吃飽了的棕黃色的大象命名的。我的命名標準就是簡短、容易發音和拼寫,沒有太多的意義,並且不會被用於別處。小孩子在這方面是高手,Google就是由孩子命名的。”
Hadoop組成:HDFS、MapReduce、Yarn


二、Hadoop版本和下載安裝

1.下載
下載地址:http://hadoop.apache.org/releases.html
Apache Hadoop的成熟版本分爲兩代,我們將第一代Hadoop稱爲Hadoop 1.0,第二代Hadoop稱爲Hadoop 2.0。
第一代Hadoop分爲三個大版本,分別是0.20.x,0.21.x和0.22.x,其中,0.20.x最後演化成1.0.x,變爲穩定版本,而0.21.x和0.22.x則添加了NameNode和HA等重大特性。
第二代Hadoop包含兩個版本,分別是0.23.x和2.x,它們完全不同於Hadoop1.0,是一套全新的架構,均包含HDFS-Federation和YARN兩個子系統,相比於0.23.x,2.x增加了NameNode HA和Wire-compatibility兩個重大特性。
當然,截止發文前,hadoop出的新版本爲 3.0.0-alpha1,但穩定版還沒有出來。穩定版出來後,Hadoop有可能會進入第三代。


2.安裝
Hadoop的安裝分爲單機方式、僞分佈式方式、完全分佈式方式。

單機模式
1. Hadoop 的默認模式。
2. 當首次解壓Hadoop 的源碼包時,Hadoop無法瞭解硬件的安裝環境,便保守的選擇了最小配置。
3. 這種模式下,所有的3個XML文件均爲空。當配置文件爲空時,Hadoop完全運行在本地。
4. 因爲不需要與其他節點進行交互,單機模式就不使用HDFS,也不加載任何Hadoop的守護進程。
5. 該模式主要用於開發調試MapReduce程序的應用邏輯。

僞分佈式模式
1. Hadoop守護進程運行在本地機器上;
2. 可以模擬一個小規模的集羣;
3. 可以使用HDFS和MapReduce.

完全分佈式模式
1. Hadoop守護進程運行在一個集羣上。



3.單機安裝

4.僞分佈式安裝

5.完全分佈式安裝


三、HDFS的特點

1.HDFS概述

  • HDFS爲了保證數據存儲的可靠性和讀取性能,對數據進行切塊後 並進行復制存儲在集羣的多個節點中。
  • HDFS中存在一個名字節點NameNode和多個數據節點DataNode

HDFS Architecture

NameNode:
1. 存儲元數據信息
2. 元數據保存在內存/磁盤中
3. 保存文件、block、datanode之間的映射關係
DataNode:
1. 存儲block內容
2. 存儲在磁盤中
3. 維護了block id到文件的映射關係


2.HDFS優點

  • 支持超大文件
    超大文件在這裏指的是幾百M,幾百GB,甚至幾TB大小的文件。
    一般來說hadoop的文件系統會存儲TB級別或者PB級別的數據。
    所以在企業的應用中,數據節點有可能有上千個。

  • 檢測和快速應對硬件故障
    在集羣的環境中,硬件故障是常見的問題。
    因爲有上千臺服務器連接在一起,這樣會導致高故障率
    因此故障檢測和自動恢復是hdfs文件系統的一個設計目標

  • 流式數據訪問
    Hdfs的數據處理規模比較大,應用一次需要訪問大量的數據;
    同時這些應用一般都是批量處理,而不是用戶交互式處理。
    應用程序能以流的形式訪問數據集。
    主要的是數據的吞吐量,而不是訪問速度。

  • 簡化的一致性模型
    大部分hdfs 操作文件時,需要一次寫入,多次讀取。
    在hdfs中,一個文件一旦經過創建、寫入、關閉後,一般就不需要修改了。
    這樣簡單的一致性模型,有利於提高吞吐量

  • 高容錯性
    數據自動保存多個副本,副本丟失後自動恢復
    可構建在廉價機器
    構建在廉價機器上可以輕鬆的通過擴展機器數量來近乎線性的提高集羣存儲能力


3.HDFS缺點

  • 低延遲數據訪問
    低延遲數據。如和用戶進行交互的應用,需要數據在毫秒或秒的範圍內得到響應。
    由於hadoop針對高數據吞吐量做了優化,犧牲了獲取數據的延遲,所以對於低延遲來說,不適合用hadoop來做。

  • 大量的小文件
    Hdfs支持超大的文件,是通過數據分佈在數據節點,數據的元數據保存在名字節點上。
    名字節點的內存大小,決定了hdfs文件系統可保存的文件數量。
    雖然現在的系統內存都比較大,但大量的小文件還是會影響名字節點的性能。

  • 多用戶寫入文件、修改文件
    Hdfs的文件只能有一次寫入,不支持追加寫入(2.0版本支持),也不支持修改。只有這樣數據的吞吐量才能大。

  • 不支持超強的事務
    沒有像關係型數據庫那樣,對事務有強有力的支持。


四、HDFS技術細節

1.Block

  • 最基本的存儲單位
  • 在HDFS中,有一個特別重要的概念:數據塊(Block)。前面介紹到,在HDFS中存儲的文件都是超大數據的文件,我們可以把這個超大規模的文件以一個標準切分成幾塊,分別存儲到不同的磁盤上。這個標準就稱爲Block。
  • Block 默認的大小爲64(128)M。這樣做有以下幾點好處:
    ①.文件塊可以保存在不同的磁盤上。在HDFS系統中,一個文件可以分成不同的Block存儲在不同的磁盤上。
    ②.簡化存儲系統。這樣不需要管理文件,而是管理文件塊就可以了。
    ③.有利於數據的複製。在HDFS系統中,一個數據節點一般會複製3份
  • 對於文件內容而言,一個文件的長度大小是size,那麼從文件的0偏移開始,按照固定的大小,順序對文件進行劃分並編號,劃分好的每一個塊稱一個Block。HDFS默認Block大小是128MB,以一個256MB文件,共有256/128=2個Block.
  • 不同於普通文件系統的是,HDFS中,如果一個文件小於一個數據塊的大小,並不佔用整個數據塊存儲空間


2.NameNode

  • NameNode維護着HDFS中的元信息,包括文件和Block之間關係的信息、Block數量信息、Block和DataNode之間的關係信息,數據格式參照如下:
    FileName replicas block-Ids id2host
    例如: /test/a.log,3,{b1,b2},[{b1:[h0,h1,h3]},{b2:[h0,h2,h4]}]

  • NameNode中的元數據信息存儲在內存/文件中,內存中爲實時信息,文件中爲數據鏡像作爲持久化存儲使用。

  • 文件包括:
    fsimage 元數據鏡像文件。存儲某NameNode元數據信息,並不是實時同步內存中的數據。
    edits 操作日誌文件
    fstime 保存最近一次checkpoit的時間

  • 當有寫請求時,NameNode會首先寫editlog磁盤edits文件中,成功後纔會修改內存,並向客戶端返回

  • NameNode的metadata信息會在啓動後加載到內存


3.SecondaryNameNode

  • SecondaryNameNode並不是NameNode的熱備份,而是協助者幫助NameNode進行元數據的合併,從另外的角度來看可以提供一定的備份功能,但並不是熱備,這種合併過程可能會造成極端情況下數據丟失!可以從snn中恢復部分數據,但是無法恢復全部。

  • 何時觸發數據合併?:
    根據配置文件設置的時間間隔:fs.checkpoint.period 默認3600秒
    根據配置文件設置的edits log大小 fs.checkpoint.size 默認64MB

  • 合併過程:

    這裏寫圖片描述

步驟:
①.達到條件後 snn會將nn中的fsimageedits文件拷貝過來;
②.同時nn中會創建一個新的edits.new文件,新的讀寫請求會寫入到這個edits.new中;
③.在snn中將拷貝過來的fsimageedits合併爲一個新的fsimage
④.snn將合併完成的fsimage文件拷貝回nn替換之前的fsimage;
⑤.nn再將edtis.new改爲 edits。
注:由於NameNode實時數據都在內存中,此處的合併指的是磁盤中的持久化的數據的處理。

判斷: ssn可以對元數據做一定程度的備份,但是不是熱備,對不對?
思考:什麼情況下可能造成NameNode元數據信息丟失?
snn並不是nn的熱備,但是能保存大部分備份數據。原因就在於edits.new中的數據丟失了就找不回來了

  • 通常NameNode和SNN要放置到不同機器中以此提升性能,並提供一定的元數據安全性。


4.DataNode

  • 在hadoop中,數據是存放在DataNode上面的。是以Block的形式存儲的。
  • DataNode節點會不斷向NameNode節點發送心跳報告
  • 初始化時,每個數據節點將當前存儲的數據塊告知NameNode節點。
  • 通過向NameNode主動發送心跳保持與其聯繫(3秒一次)
  • 後續DataNode節點在工作的過程中,數據節點仍會不斷的更新
  • NameNode節點與之對應的元數據信息,並接受來自NameNode節點的指令,創建、移動或者刪除本地磁盤上的數據塊。
  • 如果10分鐘都沒收到dn的心跳,則認爲其已經lost,並copy其上的block到其他dn。
  • Replication。多複本。默認是三個。


5.Block副本放置策略:

  • 第一個副本:放置在上傳文件的DN,如果是集羣就外提交,就隨機選擇一臺磁盤不太滿,cpu不太忙的節點
  • 第二個副本:放置在第一個副本不同機架的節點上
  • 第三個副本:放置在與第二個副本相同機架的節點上
  • 更多副本:隨機節點

機架感知策略(參看文章)


五、HDFS的shell操作

  • hadoop fs -mkdir /user/trunk
  • hadoop fs -ls /user
  • hadoop fs -lsr /user (遞歸的)
  • hadoop fs -put test.txt /user/trunk
  • hadoop fs -put test.txt . (複製到hdfs當前目錄下,首先要創建當前目錄)
  • hadoop fs -get /user/trunk/test.txt . (複製到本地當前目錄下)
  • hadoop fs -cat /user/trunk/test.txt
  • hadoop fs -tail /user/trunk/test.txt (查看最後1000字節)
  • hadoop fs -rm /user/trunk/test.txt
  • hadoop fs -rmdir /user/trunk
  • hadoop fs -help ls (查看ls命令的幫助文檔)

六、HDFS執行流程

1.HDFS讀流程

這裏寫圖片描述

  • 使用HDFS提供的客戶端開發庫Client,向遠程的Namenode發起RPC請求;
  • Namenode會視情況返回文件的部分或者全部block列表,對於每個block,Namenode都會返回有該block拷貝的DataNode地址;
  • 客戶端開發庫Client會選取離客戶端最接近的DataNode來讀取block;如果客戶端本身就是DataNode,那麼將從本地直接獲取數據.
  • 讀取完當前block的數據後,關閉與當前的DataNode連接,併爲讀取下一個block尋找最佳的DataNode;
  • 當讀完列表的block後,且文件讀取還沒有結束,客戶端開發庫會繼續向Namenode獲取下一批的block列表。
  • 讀取完一個block都會進行checksum驗證,如果讀取datanode時出現錯誤,客戶端會通知Namenode,然後再從下一個擁有該block拷貝的datanode繼續讀。
  • 當文件最後一個塊也都讀取完成後,datanode會連接namenode告知關閉文件。


2.HDFS的寫流程

這裏寫圖片描述

  • 使用HDFS提供的客戶端開發庫Client,向遠程的Namenode發起RPC請求;
  • Namenode會檢查要創建的文件是否已經存在,創建者是否有權限進行操作,成功則會爲文件創建一個記錄,否則會讓客戶端拋出異常;
  • 當客戶端開始寫入文件的時候,開發庫會將文件切分成多個packets,並在內部以數據隊列”data queue”的形式管理這些packets,並向Namenode申請新的blocks,獲取用來存儲replicas的合適的datanodes列表,列表的大小根據在Namenode中對replication的設置而定。
  • 開始以pipeline(管道)的形式將packet寫入所
    有的replicas中。開發庫把packet以流的方式寫入第一個datanode,該datanode把該packet存儲之後,再將其傳遞給在此
    pipeline中的下一個datanode,直到最後一個datanode,這種寫數據的方式呈流水線的形式。
  • 最後一個datanode成功存儲之後會返回一個ack packet,在pipeline裏傳遞至客戶端,在客戶端的開發庫內部維護着”ack
    queue”,成功收到datanode返回的ack packet後會從”ack queue”移除相應的packet。
  • 如果傳輸過程中,有某個datanode出現了故障,那麼當前的pipeline會被關閉,出現故障的datanode會從當前的pipeline中移除,剩餘的block會繼續剩下的datanode中繼續以pipeline的形式傳輸,同時Namenode會分配一個新的datanode,保持replicas設定的數量。


3.HDFS的刪除流程

  • 先在NameNode上執行節點名字的刪除。
  • 當NameNode執行delete方法時,它只標記操作涉及的需要被刪除的數據塊,而不會主動聯繫這些數據塊所在的DataNode節點。
  • 當保存着這些數據塊的DataNode節點向NameNode節點發送心跳時,在心跳應答裏,NameNode節點會向DataNode發出指令,從而把數據刪除掉。
  • 所以在執行完delete方法後的一段時間內,數據塊才能被真正的刪除掉。


4.安全模式 **

  • 在重新啓動HDFS後,會立即進入安全模式,此時不能操作hdfs中的文件,只能查看目錄文件名等,讀寫操作都不能進行。
  • namenode啓動時,需要載入fsimage文件到內存,同時執行edits文件中各項操作
  • 一旦在內存中成功建立文件系統元數據的映射,則創建一個新的fsimage文件(這個步驟不需要SNN的參與)和一個空的編輯文件。
  • 此時namenode文件系統對於客戶端來說是隻讀的。
  • 再此階段NameNode收集各個DataNode的報告,當數據塊達到最小複本數以上時,會被認爲是“安全”的,在一定比例的數據塊被確定爲安全後,再經過若干時間,安全模式結束
  • 當檢測到副本數不足的數據塊時,該塊會被複制直到到達最小副本數,系統中數據塊的位置並不是namenode維護的,而是以塊列表的形式存儲在datanode中。
  • 當啓動報如下錯誤時: org.apache.hadoop.dfs.SafeModeException: Cannot delete/user/hadoop/input. Name node is in safe mode
    使用如下命令退出安全模式:
    hadoop dfsadmin -safemode leave

七、java接口方式操作HDFS

1.Eclipse中Hadoop插件的使用

    //導入jar
    hadoop/share/hadoop/common/*.jar
    hadoop/share/hadoop/common/lib/*.jar
    hadoop/hdfs/*.jar

    //--下載
    FileSystem fs = FileSystem.get(new URI("hdfs://xxxx:9000")new Configuration());
    InputStream in = fs.open(new Path("/xxx"));//HDFS路徑
    OutputStream out = ..
    IOUtils.copyBytes(in,out,buffersize,close);

    //--上傳
    InputStream in = ..
    FileSystem fs = FileSystem.get(new URI("hdfs://xxxx:9000")new Configuration());
    OutputStream out = fs.create(new Path("..."));//hdfs路徑
    IOUtils.copyBytes(in,out,buffersize,close);

    #問題:Permission Denied -- 權限錯誤
    FileSystem fs = FileSystem.get(new URI("hdfs://xxxx:9000")new Configuration(),"root");

    //--刪除文件、文件夾(如果要刪除的文件夾中有內容,必須選擇遞歸刪除)
    boolean fs.delete(new Path("目標hdfs路徑"),是否遞歸刪除);

    //--創建文件夾
    boolean fs.mkdirs(new Path(".."));
發佈了40 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章