HDFS 原理、架構與特性介紹

jopen 11年前發布 | 192K 次閱讀 HDFS 分布式/云計算/大數據

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

1:當前HDFS架構詳盡分析 

  HDFS 原理、架構與特性介紹 
</span>

HDFS架構 

?NameNode 
?DataNode 
?Sencondary NameNode
 
</span>

數據存儲細節 

HDFS 原理、架構與特性介紹

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 啟動時,在不久的將來將實現支持 周期性的檢查點。 
</span>

HDFS NameSpace 

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

DataNode 

               Datanode 將 HDFS 數據以文件的形式存儲在本地的文件系統中,它并不知道有 關 HDFS 文件的信息。它把每個 HDFS 數據塊存儲在本地文件系統的一個單獨的文件 中。 Datanode 并不在同一個目錄創建所有的文件,實際上,它用試探的方法來確定 每個目錄的最佳文件數目,并且在適當的時候創建子目錄。在同一個目錄中創建所 有的本地文件并不是最優的選擇,這是因為本地文件系統可能無法高效地在單個目 錄中支持大量的文件。 
            當一個 Datanode 啟動時,它會掃描本地文件系統,產生一個這些本地文件對應 的所有 HDFS 數據塊的列表,然后作為報告發送到 Namenode ,這個報告就是塊狀態 報告。 
</span>

配置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> 
</span>

Secondary NameNode 

  Secondary NameNode 定期合并 fsimage 和 edits 日志,將 edits 日志文件大小控制在一個限度下。 

  HDFS 原理、架構與特性介紹 
</span>

  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 上。 

</span>

2:HDFS文件讀取的解析 

文件讀取流程 

  HDFS 原理、架構與特性介紹 
</span>

  流程分析 

?使用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繼續讀。 

</span>

3:HDFS文件寫入的解析 

文件寫入流程 

  HDFS 原理、架構與特性介紹 
</span>

流程分析 

?使用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設定的數量。 
</span>

  流水線復制

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

  更細節的原理 

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

</span>

4:副本機制 

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

副本擺放策略 

  HDFS 原理、架構與特性介紹 
</span>

  修改副本數 

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就可以了,大了意義也不大。

</span>

5:HDFS負載均衡 

        HDFS的數據也許并不是非常均勻的分布在各個DataNode中。一個常見的原因是在現有的集群上經常會增添新的DataNode節點。當新增一個數據塊(一個文件的數據被保存在一系列的塊中)時,NameNode在選擇DataNode接收這個數據塊之前,會考慮到很多因素。其中的一些考慮的是: 
?將數據塊的一個副本放在正在寫這個數據塊的節點上。 
?盡量將數據塊的不同副本分布在不同的機架上,這樣集群可在完全失去某一機架的情況下還能存活。 
?一個副本通常被放置在和寫文件的節點同一機架的某個節點上,這樣可以減少跨越機架的網絡I/O。 
?盡量均勻地將HDFS數據分布在集群的DataNode中。

</span>

6:HDFS機架感知 

HDFS機架感知 

        通常,大型 Hadoop 集群是以機架的形式來組織的,同一個機架上不同 節點間的網絡狀況比不同機架之間的更為理想。 另外, NameNode 設法將 數據塊副本保存在不同的機架上以提高容錯性。 
         而 HDFS 不能夠自動判斷集群中各個 datanode 的網絡拓撲情況 Hadoop 允 許集群的管理員通過配置 dfs.network.script 參數來確定節點所處的機架。 文 件提供了 IP->rackid 的翻譯。 NameNode 通過這個得到集群中各個 datanode 機器的 rackid 。 如果 topology.script.file.name 沒有設定,則每個 IP 都會翻譯 成 / default-rack 。 
  HDFS 原理、架構與特性介紹 
</span>

        有了機架感知, 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 將不會自動遍歷、識別目錄下的文件。


11:HDFS缺點  

大量小文件  

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!