分佈式文件系統:HDFS

  學習Hadoop,兩個東西確定是繞不過,MapReduce和HDFS,上一篇博客介紹了MapReduce的處理流程,這一篇博客就來學習一下HDFS。html

  HDFS是一個分佈式的文件系統,就是將多臺機器的存儲當作一個文件系統來使用,由於在大數據的情景下,單機的存儲量已經徹底不夠用了,因此採起分佈式的方法來擴容,解決本地文件系統在文件大小、文件數量、打開文件數等的限制問題。咱們首先來看一下HDFS的架構node

HDFS架構

  從上圖能夠看到,HDFS的主要組成部分爲Namenode、Datanodes、Client,還有幾個名詞:Block、Metadata、Replication 、Rack,它們分別是什麼意思呢?算法

  對於分佈式的文件系統,數據存儲在不少的機器上,而Datanode表明的就是這些機器,是數據實際存儲的地方,數據存好以後,咱們須要知道它們具體存在哪個Datanode上,這就是Namenode作的工做,它記錄着元數據信息(也就是Metadata,其主要內容就是哪一個數據塊存在哪一個Datanode上的哪一個目錄下,這也是爲何HDFS不適合存大量小文件的緣由,由於 爲了響應速度,Namenode 把文件系統的元數據放置在內存中,因此文件系統所能容納的文件數目是由 Namenode 的內存大小來決定。通常來講,每個文件、文件夾和 Block 須要佔據 150 字節左右的空間,若是存100 萬個小文件,至少須要 300MB內存,但這麼多小文件實際卻沒有存太多數據,這樣就太浪費內存了),有了元數據信息,咱們就能經過Namenode來查到數據塊的具體位置了,而與Namenode打交道的工具就是Client,Client給咱們用戶提供存取數據的接口,咱們能夠經過Client進行數據存取的工做。apache

  而剩下來的幾個名詞,Block表示的是數據塊,由於存在HDFS上的通常都是很大的文件,咱們須要將它拆成不少個數據塊進行存儲;Replication是副本的意思,這是爲了數據的可靠性,若是某個數據塊丟失了,還能經過它的副本找回來,HDFS默認一個數據塊存儲三份;Rack表示的是機架的意思,能夠理解爲存放多個Datanode的地方。網絡

       總結一下就是,數據存在Datanode上,而且有副本,而Namenode知道數據及其副本具體存在哪一個Datanode上,咱們想要找數據或者寫數據的時候就經過Client來和Namenode聯繫,由它來告訴咱們應該把數據存在哪裏或者到哪裏去取。架構

HDFS讀寫流程

  看完了HDFS的架構,咱們來看一下HDFS具體是怎麼存取數據的。首先是寫流程:app

 

注:如下步驟並不嚴格對應如中的發生順序分佈式

  1)使用HDFS提供的客戶端開發庫,向遠程的Namenode發起請求;ide

  2)Namenode會檢查要建立的文件是否已經存在,建立者是否有權限進行操做,成功則會爲文件建立一個記錄,不然會讓客戶端拋出異常;工具

  3)當客戶端開始寫入文件的時候,會將文件切分紅多個packets(數據包),並在內部以「data queue」(數據隊列)的形式管理這些packets,並向Namenode申請新的blocks,獲取用來存儲replication的合適的datanodes列表,列表的大小根據在Namenode中對replication的設置而定。

  4)開始以pipeline(管道)的形式將packet寫入全部的replication中。先將packet以流的方式寫入第一個datanode,該datanode把該packet存儲以後,再將其傳遞給在此pipeline中的下一個datanode,直到最後一個datanode,這種寫數據的方式呈流水線的形式。

  5)最後一個datanode成功存儲以後會返回一個ack packet(確認包),在pipeline裏傳遞至客戶端,在客戶端內部維護着「ack queue」(確認隊列),成功收到datanode返回的ackpacket後會從「ack queue」移除相應的packet,表明該packet寫入成功。

  6)若是傳輸過程當中,有某個datanode出現了故障,那麼當前的pipeline會被關閉,出現故障的datanode會從當前的pipeline中移除,剩餘的block會在剩下的datanode中繼續以pipeline的形式傳輸,同時Namenode會分配一個新的datanode,保持replication設定的數量。

  接下來是讀流程:

 

注:如下步驟並不嚴格對應如中的發生順序

  1)使用HDFS提供的客戶端,向遠程的Namenode發起請求;

  2)Namenode會視狀況返回文件的部分或者所有block列表,對於每一個block,Namenode都會返回有該block拷貝的Datanode地址;

  3)客戶端會選取離客戶端最接近的Datanode來讀取block;

  4)讀取完當前block的數據後,關閉與當前的Datanode鏈接,併爲讀取下一個block尋找最佳的Datanode;

  5)當讀完列表的block後,且文件讀取尚未結束,客戶端會繼續向Namenode獲取下一批的block列表。

  6)讀取完一個block都會進行checksum(校驗和)驗證,看文件內容是否出錯;另外,若是讀取Datanode時出現錯誤,客戶端會通知Namenode,而後再從下一個擁有該block拷  貝的Datanode繼續讀。

  以上即是HDFS的讀寫流程,瞭解這些以後,咱們思考幾個問題,對於分佈式的文件系統,咱們怎麼保證數據的一致性?就是說若是有多個客戶端向同一個文件寫數據,那麼咱們該怎麼處理?另外,咱們看到Namenode在HDFS中很是重要,它保存着關鍵的元數據信息,可是從架構圖中看到,Namenode只有一個,若是它掛掉了,咱們怎麼保證系統可以繼續工做?

分佈式領域CAP理論

  CAP理論是分佈式中一個經典的理論,具體內容以下:

  Consistency(一致性):在分佈式系統中的全部數據備份,在同一時刻是否一樣的值。

  Availability(可用性):在集羣中一部分節點故障後,集羣總體是否還能響應客戶端的讀寫請求。

  Partition tolerance(分區容錯性):系統應該能持續提供服務,即便系統內部有消息丟失(分區)。

  一致性和可用性比較好理解,主要解釋一下分區容錯性,它的意思就是說由於網絡的緣由,多是網絡斷開了,也多是某些機器宕機了,網絡延時等致使數據交換沒法在指望的時間內完成。由於網絡問題是避免不了的,因此咱們老是須要解決這個問題,也就是得保證分區容錯性。爲了保證數據的可靠性,HDFS採起了副本的策略。

  對於一致性,HDFS提供的是簡單的一致性模型,爲一次寫入,屢次讀取一個文件的訪問模式,支持追加(append)操做,但沒法更改已寫入數據。HDFS中的文件都是一次性寫入的,而且嚴格要求在任什麼時候候只能有一個寫入者。何時一個文件算寫入成功呢?對於HDFS來講,有兩個參數:dfs.namenode.replication.min (默認爲1) 和dfs.replication (默認爲 3),一個文件的副本數大於等於參數dfs.namenode.replication.min 時就被標記爲寫成功,可是副本數要是小於參數dfs.replication,此文件還會標記爲「unreplication」,會繼續往其它Datanode裏寫副本,因此若是咱們想要直到全部要保存數據的DataNodes確認它們都有文件的副本時,數據才被認爲寫入完成,咱們能夠將dfs.namenode.replication.min設置與dfs.replication相等。所以,數據一致性是在寫的階段完成的,一個客戶端不管選擇從哪一個DataNode讀取,都將獲得相同的數據。

  對於可用性,HDFS2.0對Namenode提供了高可用性(High Availability),這裏提一下,Secondary NameNode不是HA,Namenode由於須要知道每一個數據塊具體在哪,因此爲每一個數據塊命名,並保存這個命名文件(fsimage文件),只要有操做文件的行爲,就將這些行爲記錄在編輯日誌中(edits文件),爲了響應的速度,這兩個文件都是放在內存中的,可是隨着文件操做額進行,edits文件會愈來愈大,因此Secondary NameNode會階段性的合併edits和fsimage文件,以縮短集羣啓動的時間。當NameNode失效的時候,Secondary NameNode並沒有法馬上提供服務,Secondary NameNode甚至沒法保證數據完整性,若是NameNode數據丟失的話,在上一次合併後的文件系統的改動會丟失。Secondary NameNode合併edits和fsimage文件的流程具體以下:

  目前HDFS2中提供了兩種HA方案,一種是基於NFS(Network File System)共享存儲的方案,一種基於Paxos算法的方案Quorum Journal Manager(QJM),下面是基於NFS共享存儲的方案

 

  經過上圖可知,Namenode的高可用性是經過爲其設置一個Standby Namenode來實現的,要是目前的Namenode掛掉了,就啓用備用的Namenode。而兩個Namenode之間經過共享的存儲來同步信息,如下是一些要點:

   • 利用共享存儲來在兩個NameNode間同步edits信息。

  • DataNode同時向兩個NameNode彙報塊信息。這是讓Standby NameNode保持集羣最新狀態的必需步驟。

  • 用於監視和控制NameNode進程的FailoverController進程(一旦工做的Namenode掛了,就啓用切換程序)。

  • 隔離(Fencing),防止腦裂,就是保證在任什麼時候候只有一個主NameNode,包括三個方面:

         • 共享存儲fencing,確保只有一個NameNode能夠寫入edits。

         • 客戶端fencing,確保只有一個NameNode能夠響應客戶端的請求。

             • DataNode fencing,確保只有一個NameNode能夠向DataNode下發命令,譬如刪除塊,複製塊,等等。

  另外一種是QJM方案:

  簡單來講,就是爲了讓Standby Node與Active Node保持同步,這兩個Node都與一組稱爲JNS(Journal Nodes)的互相獨立的進程保持通訊。它的基本原理就是用2N+1臺JournalNode存儲edits文件,每次寫數據操做有大多數(大於等於N+1)返回成功時即認爲該次寫成功。由於QJM方案是基於Paxos算法的,而Paxos算法不是兩三句就能說清楚的,有興趣的能夠看這個知乎專欄:Paxos算法或者參考官方文檔

總結

       本篇博客主要介紹了HDFS的架構、讀寫流程和HDFS在CAP上的作法,幫助你們對HDFS的理解,若是想要更詳細的技術細節,能夠看看官方文檔或者我在參考中列出的連接。

參考

       《Hadoop權威指南》 

    http://www.cnblogs.com/youngerchina/p/5624459.html

        http://blog.csdn.net/hguisu/article/details/7259716

    http://www.cnblogs.com/codeOfLife/p/5375120.html 

        https://www.zybuluo.com/jewes/note/68185

相關文章
相關標籤/搜索