HDFS 原理、架構與特性介紹

本文主要講述 HDFS原理-架構、副本機制、HDFS負載均衡、機架感知、健壯性、文件刪除恢復機制 html

1:當前HDFS架構詳盡分析 

   

HDFS架構 

•NameNode 
•DataNode 
•Sencondary NameNode
 

數據存儲細節 


NameNode 目錄結構 

Namenode 的目錄結構: 
           ${ dfs.name.dir}/current /VERSION
                                                  /edits
                                                  /fsimage
                                                  /fstime 
    dfs.name.dir 是 hdfs-site.xml 裏配置的若干個目錄組成的列表。 

NameNode 

             Namenode 上保存着 HDFS 的名字空間。對於任何對文件系統元數據產生修改的操做, Namenode 都會使用一種稱爲 EditLog 的事務日誌記錄下來。例如,在 HDFS 中建立一個文件, Namenode 就會在 Editlog 中插入一條記錄來表示;一樣地,修改文件的副本系數也將往 Editlog 插入一條記錄。 Namenode 在本地操做系統的文件系統中存儲這個 Editlog 。整個文件系統的名 字空間,包括數據塊到文件的映射、文件的屬性等,都存儲在一個稱爲 FsImage 的文件中,這 個文件也是放在 Namenode 所在的本地文件系統上。 
              Namenode 在內存中保存着整個文件系統的名字空間和文件數據塊映射 (Blockmap) 的映像 。這個關鍵的元數據結構設計得很緊湊,於是一個有 4G 內存的 Namenode 足夠支撐大量的文件 和目錄。當 Namenode 啓動時,它從硬盤中讀取 Editlog 和 FsImage ,將全部 Editlog 中的事務做 用在內存中的 FsImage 上,並將這個新版本的 FsImage 從內存中保存到本地磁盤上,而後刪除 舊的 Editlog ,由於這個舊的 Editlog 的事務都已經做用在 FsImage 上了。這個過程稱爲一個檢查 點 (checkpoint) 。在當前實現中,檢查點只發生在 Namenode 啓動時,在不久的未來將實現支持 週期性的檢查點。 

HDFS NameSpace 

            HDFS 支持傳統的層次型文件組織結構。用戶或者應用程序能夠建立目 錄,而後將文件保存在這些目錄裏。文件系統名字空間的層次結構和大多數 現有的文件系統相似:用戶能夠建立、刪除、移動或重命名文件。當前, HDFS 不支持用戶磁盤配額和訪問權限控制,也不支持硬連接和軟連接。但 是 HDFS 架構並不妨礙實現這些特性。 
             Namenode 負責維護文件系統命名空間,任何對文件系統名字空間或屬 性的修改都將被 Namenode 記錄下來。應用程序能夠設置 HDFS 保存的文件 的副本數目。文件副本的數目稱爲文件的副本系數,這個信息也是由 Namenode 保存的。 

DataNode 

               Datanode 將 HDFS 數據以文件的形式存儲在本地的文件系統中,它並不知道有 關 HDFS 文件的信息。它把每一個 HDFS 數據塊存儲在本地文件系統的一個單獨的文件 中。 Datanode 並不在同一個目錄建立全部的文件,實際上,它用試探的方法來肯定 每一個目錄的最佳文件數目,而且在適當的時候建立子目錄。在同一個目錄中建立所 有的本地文件並非最優的選擇,這是由於本地文件系統可能沒法高效地在單個目 錄中支持大量的文件。 
            當一個 Datanode 啓動時,它會掃描本地文件系統,產生一個這些本地文件對應 的全部 HDFS 數據塊的列表,而後做爲報告發送到 Namenode ,這個報告就是塊狀態 報告。 

配置Secondary NameNode 

• conf/masters文件指定的爲Secondary NameNode節點 
•修改在masters文件中配置了的機器上的conf/hdfs-site.xml文件,加上以下選項: 
       <property> 
               <name>dfs.http.address</name> 
              <value>namenode.hadoop-host.com:50070</value> 
      </property> 

•core-site.xml:這裏有2個參數可配置,但通常來講咱們不作修改。fs.checkpoint.period表示多長時間記錄一次hdfs的鏡像。默認是1小時。fs.checkpoint.size表示一次記錄多大的size,默認64M。 
      <property> 
               <name>fs.checkpoint.period</name> 
               <value>3600</value> 
               <description>The number of seconds between two periodic checkpoints. </description>
      </property> 
        <property> 
              <name>fs.checkpoint.size</name> 
              <value>67108864</value> 
              <description>The size of the current edit log (in bytes) that triggers a periodic checkpoint even if the fs.checkpoint.period hasn't expired. </description> 
        </property> 

Secondary NameNode 

  Secondary NameNode 按期合併 fsimage 和 edits 日誌,將 edits 日誌文件大小控制在一個限度下。  node

   

  Secondary NameNode處理流程 

    (1) 、 namenode 響應 Secondary namenode 請求,將 edit log 推送給 Secondary namenode , 開始從新寫一個新的 edit log 。 
    (2) 、 Secondary namenode 收到來自 namenode 的 fsimage 文件和 edit log 。 
    (3) 、 Secondary namenode 將 fsimage 加載到內存,應用 edit log , 並生成一 個新的 fsimage 文件。 
    (4) 、 Secondary namenode 將新的 fsimage 推送給 Namenode 。 
    (5) 、 Namenode 用新的 fsimage 取代舊的 fsimage , 在 fstime 文件中記下檢查 點發生的時 
HDFS通訊協議 

            全部的 HDFS 通信協議都是構建在 TCP/IP 協議上。客戶端經過一個可 配置的端口鏈接到 Namenode , 經過 ClientProtocol 與 Namenode 交互。而 Datanode 是使用 DatanodeProtocol 與 Namenode 交互。再設計上, DataNode 經過週期性的向 NameNode 發送心跳和數據塊來保持和 NameNode 的通訊,數據塊報告的信息包括數據塊的屬性,即數據塊屬於哪 個文件,數據塊 ID ,修改時間等, NameNode 的 DataNode 和數據塊的映射 關係就是經過系統啓動時 DataNode 的數據塊報告創建的。從 ClientProtocol 和 Datanodeprotocol 抽象出一個遠程調用 ( RPC ), 在設計上, Namenode 不會主動發起 RPC , 而是是響應來自客戶端和 Datanode 的 RPC 請求。 
HDFS的安全模式 

           Namenode 啓動後會進入一個稱爲安全模式的特殊狀態。處於安全模式 的 Namenode 是不會進行數據塊的複製的。 Namenode 從全部的 Datanode 接收心跳信號和塊狀態報告。塊狀態報告包括了某個 Datanode 全部的數據 塊列表。每一個數據塊都有一個指定的最小副本數。當 Namenode 檢測確認某 個數據塊的副本數目達到這個最小值,那麼該數據塊就會被認爲是副本安全 (safely replicated) 的;在必定百分比(這個參數可配置)的數據塊被 Namenode 檢測確認是安全以後(加上一個額外的 30 秒等待時間), Namenode 將退出安全模式狀態。接下來它會肯定還有哪些數據塊的副本沒 有達到指定數目,並將這些數據塊複製到其餘 Datanode 上。 

2: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繼續讀。 

3: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設定的數量。 

  流水線複製

               當客戶端向 HDFS 文件寫入數據的時候,一開始是寫到本地臨時文件中。假設該文件的副 本系數設置爲 3 ,當本地臨時文件累積到一個數據塊的大小時,客戶端會從 Namenode 獲取一個 Datanode 列表用於存放副本。而後客戶端開始向第一個 Datanode 傳輸數據,第一個 Datanode 一小部分一小部分 (4 KB) 地接收數據,將每一部分寫入本地倉庫,並同時傳輸該部分到列表中 第二個 Datanode 節點。第二個 Datanode 也是這樣,一小部分一小部分地接收數據,寫入本地 倉庫,並同時傳給第三個 Datanode 。最後,第三個 Datanode 接收數據並存儲在本地。所以, Datanode 能流水線式地從前一個節點接收數據,並在同時轉發給下一個節點,數據以流水線的 方式從前一個 Datanode 複製到下一個 

  更細節的原理 

           客戶端建立文件的請求其實並無當即發送給 Namenode ,事實上,在剛開始階 段 HDFS 客戶端會先將文件數據緩存到本地的一個臨時文件。應用程序的寫操做被透 明地重定向到這個臨時文件。當這個臨時文件累積的數據量超過一個數據塊的大小 ,客戶端纔會聯繫 Namenode 。 Namenode 將文件名插入文件系統的層次結構中,並 且分配一個數據塊給它。而後返回 Datanode 的標識符和目標數據塊給客戶端。接着 客戶端將這塊數據從本地臨時文件上傳到指定的 Datanode 上。當文件關閉時,在臨 時文件中剩餘的沒有上傳的數據也會傳輸到指定的 Datanode 上。而後客戶端告訴 Namenode 文件已經關閉。此時 Namenode 纔將文件建立操做提交到日誌裏進行存儲 。若是 Namenode 在文件關閉前宕機了,則該文件將丟失。 

4:副本機制 

特色 
1. 數據類型單一 
2. 副本數比較多 
3. 寫文件時副本的放置方法 
4. 動態的副本建立策略 
5. 弱化的副本一致性要求 

副本擺放策略 

   

  修改副本數 

1.集羣只有三個Datanode,hadoop系統replication=4時,會出現什麼狀況? 
        對於上傳文件到hdfs上時,當時hadoop的副本系數是幾,這個文件的塊數副本數就會有幾份,不管之後你怎麼更改系統副本系統,這個文件的副本數都不會改變,也就說上傳到分佈式系統上的文件副本數由當時的系統副本數決定,不會受replication的更改而變化,除非用命令來更改文件的副本數。由於dfs.replication實質上是client參數,在create文件時能夠指定具體replication,屬性dfs.replication是不指定具體replication時的採用默認備份數。文件上傳後,備份數已定,修改dfs.replication是不會影響之前的文件的,也不會影響後面指定備份數的文件。隻影響後面採用默認備份數的文件。但能夠利用hadoop提供的命令後期改某文件的備份數:hadoop fs -setrep -R 1。若是你是在hdfs-site.xml設置了dfs.replication,這並必定就得了,由於你可能沒把conf文件夾加入到你的 project的classpath裏,你的程序運行時取的dfs.replication多是hdfs-default.xml裏的 dfs.replication,默認是3。可能這個就是形成你爲何dfs.replication總是3的緣由。你能夠試試在建立文件時,顯式設定replication。replication通常到3就能夠了,大了意義也不大。

5:HDFS負載均衡 

        HDFS的數據也許並非很是均勻的分佈在各個DataNode中。一個常見的緣由是在現有的集羣上常常會增添新的DataNode節點。當新增一個數據塊(一個文件的數據被保存在一系列的塊中)時,NameNode在選擇DataNode接收這個數據塊以前,會考慮到不少因素。其中的一些考慮的是: 
•將數據塊的一個副本放在正在寫這個數據塊的節點上。 
•儘可能將數據塊的不一樣副本分佈在不一樣的機架上,這樣集羣可在徹底失去某一機架的狀況下還能存活。 
•一個副本一般被放置在和寫文件的節點同一機架的某個節點上,這樣能夠減小跨越機架的網絡I/O。 
•儘可能均勻地將HDFS數據分佈在集羣的DataNode中。

6:HDFS機架感知 

        一般,大型 Hadoop 集羣是以機架的形式來組織的,同一個機架上不一樣 節點間的網絡情況比不一樣機架之間的更爲理想。 另外, NameNode 設法將 數據塊副本保存在不一樣的機架上以提升容錯性。 
         而 HDFS 不可以自動判斷集羣中各個 datanode 的網絡拓撲狀況 Hadoop 允 許集羣的管理員經過配置 dfs.network.script 參數來肯定節點所處的機架。 文 件提供了 IP->rackid 的翻譯。 NameNode 經過這個獲得集羣中各個 datanode 機器的 rackid 。 若是 topology.script.file.name 沒有設定,則每一個 IP 都會翻譯 成 / default-rack 。 
   

        有了機架感知, NameNode 就能夠畫出上圖所示的 datanode 網絡拓撲圖。 D1,R1 都是交換機,最底層是 datanode 。 則 H1 的 rackid=/D1/R1/H1 , H1 的 parent 是 R1 , R1 的是 D1 。 這些 rackid 信息能夠經過 topology.script.file.name 配置。有了這些 rackid 信息就能夠計算出任意兩臺 datanode 之間的距離。   
    
distance(/D1/R1/H1,/D1/R1/H1)=0  相同的 datanode   
distance(/D1/R1/H1,/D1/R1/H2)=2  同一 rack 下的不一樣 datanode   
distance(/D1/R1/H1,/D1/R1/H4)=4  同一 IDC 下的不一樣 datanode   
distance(/D1/R1/H1,/D2/R3/H7)=6   不一樣 IDC 下的 datanode   

7:HDFS訪問方式    

          HDFS 給應用提供了多種訪問方式。用戶能夠經過 Java API 接口訪問,也 能夠經過 C 語言的封裝 API 訪問,還能夠經過瀏覽器的方式訪問 HDFS 中的文件。   

8:HDFS 健壯性   

         HDFS 的主要目標就是即便在出錯的狀況下也要保證數據存儲的可靠性。 常見的三種出錯狀況是: Namenode 出錯 , Datanode 出錯和網絡割裂 ( network partitions) 。  

   磁盤數據錯誤,心跳檢測和從新複製   

          每一個 Datanode 節點週期性地向 Namenode 發送心跳信號。網絡割裂可能 致使一部分 Datanode 跟 Namenode 失去聯繫。 Namenode 經過心跳信號的缺 失來檢測這一狀況,並將這些近期再也不發送心跳信號 Datanode 標記爲宕機 ,不會再將新的 IO 請求發給它們。任何存儲在宕機 Datanode 上的數據將不 再有效。 Datanode 的宕機可能會引發一些數據塊的副本系數低於指定值, Namenode 不斷地檢測這些須要複製的數據塊,一旦發現就啓動複製操做。 在下列狀況下,可能須要從新複製:某個 Datanode 節點失效,某個副本遭 到損壞, Datanode 上的硬盤錯誤,或者文件的副本系數增大。   

   數據完整性  

             從某個 Datanode 獲取的數據塊有多是損壞的,損壞多是由 Datanode 的存儲設備錯誤、網絡錯誤或者軟件 bug 形成的。 HDFS 客戶端軟 件實現了對 HDFS 文件內容的校驗和 (checksum) 檢查。當客戶端建立一個新 的 HDFS 文件,會計算這個文件每一個數據塊的校驗和,並將校驗和做爲一個 單獨的隱藏文件保存在同一個 HDFS 名字空間下。當客戶端獲取文件內容後 ,它會檢驗從 Datanode 獲取的數據跟相應的校驗和文件中的校驗和是否匹 配,若是不匹配,客戶端能夠選擇從其餘 Datanode 獲取該數據塊的副本。   

   元數據磁盤錯誤   

          FsImage 和 Editlog 是 HDFS 的核心數據結構。若是這些文件損壞了,整個 HDFS 實例都將失效。於是, Namenode 能夠配置成支持維護多個 FsImage 和 Editlog 的副本。任何對 FsImage 或者 Editlog 的修改,都將同步到它們的副 本上。這種多副本的同步操做可能會下降 Namenode 每秒處理的名字空間事 務數量。然而這個代價是能夠接受的,由於即便 HDFS 的應用是數據密集的 ,它們也非元數據密集的。當 Namenode 重啓的時候,它會選取最近的完整 的 FsImage 和 Editlog 來使用。   
           Namenode 是 HDFS 集羣中的單點故障 (single point of failure) 所在。若是 Namenode 機器故障,是須要手工干預的。目前,自動重啓或在另外一臺機器 上作 Namenode 故障轉移的功能還沒實現。    

    快照   

            快照支持某一特定時刻的數據的複製備份。利用快照,可讓 HDFS 在 數據損壞時恢復到過去一個已知正確的時間點。 HDFS 目前還不支持快照功 能,但計劃在未來的版本進行支持。    

9:HDFS 文件刪除恢復機制  

              當用戶或應用程序刪除某個文件時,這個文件並無馬上從 HDFS 中刪 除。實際上, HDFS 會將這個文件重命名轉移到 /trash 目錄。只要文件還在 /trash 目錄中,該文件就能夠被迅速地恢復。文件在 /trash 中保存的時間是可 配置的,當超過這個時間時, Namenode 就會將該文件從名字空間中刪除。 刪除文件會使得該文件相關的數據塊被釋放。注意,從用戶刪除文件到 HDFS 空閒空間的增長之間會有必定時間的延遲。   
            只要被刪除的文件還在 /trash 目錄中,用戶就能夠恢復這個文件。若是 用戶想恢復被刪除的文件,他 / 她能夠瀏覽 /trash 目錄找回該文件。 /trash 目 錄僅僅保存被刪除文件的最後副本。 /trash 目錄與其餘的目錄沒有什麼區別 ,除了一點:在該目錄上 HDFS 會應用一個特殊策略來自動刪除文件。目前 的默認策略是刪除 /trash 中保留時間超過 6 小時的文件。未來,這個策略能夠 經過一個被良好定義的接口配置。   

開啓回收站      

hdfs-site.xml   
<configuration>   
       <property>   
               <name>fs.trash.interval</name>   
                <value>    1440   </value>   
                <description>Number ofminutes between trash checkpoints.   
                        If zero, the trashfeature is disabled.   
                </description>   
       </property>   
</configuration>   
1, fs.trash.interval參數設置保留時間爲 1440 分鐘(1天)   
2, 回收站的位置:在HDFS上的 /user/$USER/.Trash/Current/     

10:HDFS 分佈式緩存(DistributedCache 

(1)在HDFS上準備好要共享的數據(text、archive、jar)你拼路徑的時候必須加前綴"file://"說明是本地路徑,不然hadoop默認訪問的路徑是hdfs。 瀏覽器

(2)DistributedCache 在 Mapper 或者 Reducer 啓動時會被 copy to local,而後被 DistributedCache.getLocalCacheFiles() 調用,運行完 job 後 local cache file 會被刪掉,若是另外一個 job 也須要這樣一份文件,須要從新添加、從新緩存,由於在分佈式場景下 task 並不知道該 node 是否存在 cache file。若是在同臺機器已經有了dist cache file,不會再次download,DistributedCache 根據緩存文檔修改的時間戳進行追蹤。 在做業執行期間,當前應用程序或者外部程序不能修改緩存文件,因此分佈式緩存通常用來緩存只讀文件。 緩存

(3)DistributedCache 在添加的時候注意要添加具體的文件,若是你添加目錄,DistributedCache 將不會自動遍歷、識別目錄下的文件。 安全

關於 DistributedCache 的應用,請參考:Hadoop 多表 join:map side join 範例 網絡

http://my.oschina.net/leejun2005/blog/111963 數據結構

11:HDFS缺點  

大量小文件  

     由於 Namenode 把文件系統的元數據放置在內存中,因此文件系統所能 容納的文件數目是由 Namenode 的內存大小來決定。通常來講,每個文件 、文件夾和 Block 須要佔據 150 字節左右的空間,因此,若是你有 100 萬個文 件,每個佔據一個 Block ,你就至少須要 300MB 內存。當前來講,數百萬 的文件仍是可行的,當擴展到數十億時,對於當前的硬件水平來講就無法實 現了。還有一個問題就是,由於 Map task 的數量是由 splits 來決定的,因此 用 MR 處理大量的小文件時,就會產生過多的 Maptask ,線程管理開銷將會 增長做業時間。舉個例子,處理 10000M 的文件,若每一個 split 爲 1M ,那就會 有 10000 個 Maptasks ,會有很大的線程開銷;若每一個 split 爲 100M ,則只有 100 個 Maptasks ,每一個 Maptask 將會有更多的事情作,而線程的管理開銷也 將減少不少。  架構

SPOF 問題

請參考:深刻理解Hadoop集羣和網絡 app

http://my.oschina.net/leejun2005/blog/75941 負載均衡


Refer: 

http://sishuok.com/forum/blogPost/list/5936.html#19653

http://my.oschina.net/leejun2005/blog/82602

http://www.csdn.net/article/2010-11-29/282725

http://f.dataguru.cn/thread-24868-1-1.html (本文主體來源)

相關文章
相關標籤/搜索