閱讀902 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Hadoop上小文件存儲處理

Hadoop–小文件存儲處理

本篇文章項目是Cloudera論壇中無意中看到的,雖然原文寫於2009年,但是當前開來Hadoop的小文件存儲方案並沒有很好的解決方案,所以感覺作者寫的很好,也很詳細,於是就抽空翻譯了。本次翻譯主要針對對Hadoop感興趣和工作中使用到Hadoop的開發人員提供有價值的中文資料,希望能夠對大家的工作和學習有所幫助。

由於我英語水平有限,部分翻譯雖能了解其大意,但是卻沒法很好的表達出來,所以有些地方翻譯的不是很好。同時也由於能力見識有限,翻譯過程中難免出現個人的主觀或者客觀原因導致與原文檔有差異。在此,我還是建議有能力的童鞋能夠自己去原文看看,同時如果大家發現更好的關於Hadoop小文件處理的文件,也建議大家提出來與大家一同分享。

 

小文件問題

February 2, 2009

By Tom White

32 Comments

Categories: General Hadoop

在Hadoop中小文件是一個大問題 — 或者說, 至少, 他們在用戶的討論區域是比較熱門的話題. 在這篇文章中我將直麵這個問題, 並提出一些常見的解決方案.

在HDFS中的小文件問題

這裏討論的小文件指的是那些在HDFS中小於HDFS塊大小(默認是64M)的文件. 如果你存儲了很多這種小文件, 或者你有很多這種小文件 (如果你並沒有使用Hadoop), 這裏討論的問題是Hadoop不能處理大量的這種文件.

每一個文件, 目錄和塊在HDFS中代表一個對象存儲在namenode的內存中, 它們每一個占用150 字節, 根據經驗. 所以1000萬個文件,每一個使用一個塊, 將大約需要3GB的內存. 遠遠超過當前的硬件處理水平. 當然10億個文件直接沒法處理.

此外, HDFS是沒有能力去有效地訪問小文件:它主要是專為串行流式訪問的大文件設計的. 閱讀小文件通常會導致從一個DataNode到DataNode檢索每個小文件, 所有的這些訪問數據效率都是很低下的.

在MapReduce中小文件問題

Map任務每次能處理一個塊的輸入 (使用的是默認的 FileInputFormat). 如果文件非常小而且還很多, 導致每次Map任務產生非常小的輸入, 同時這裏需要大量的map任務, 這樣增加了很多額外的開銷. 比較一個1GB 文件分成16 64MB 塊, 10,000 或者 100KB 文件. 10,000文件每個文件使用一個map任務, 這個任務比一個相等的大文件要慢10或者上百倍.

這裏有一些特征能夠減輕額外的開銷:多個任務使用一個JVM, 從而避免了一些JVM啟動開銷 (看mapred.job.reuse.jvm.num.tasks 屬性), 和MultiFileInputSplit 可以運行多個以上的分割任務.

小文件怎麼產生的?

這裏至少有兩個場景

  1. 這些文件是一個更大的邏輯文件. 由於HDFS最近才支持追加,一個非常通用的保存無界文件(例如日誌文件)的模式是寫在HDFS塊.
  2. 有的文件一直比較小. 想象一個大的圖像庫. 每一個文件是一個不同的文件, 沒有自然的方法把它們組合成一個更大的文件.

這兩者需要不同的解決方案. 對於第一個實例, 文件是有一個個記錄組成, 這個問題可以通過調用 HDFS’s sync() 方法來避免 (這個是追加, 深入了解可以看 this discussion) 每一個如此頻繁地寫大文件. 另外,你可以通過寫一個程序來把小文件連接在一起 (查看 Nathan Marz’s post 工具能夠實現這種功能).

對於第二種情況,通過一些方式來對文件進行分組操作. Hadoop提供了幾種方案.

HAR files

Hadoop Archives (HAR 文件)被引入到HDFS在0.18.0版本中為了減輕存放許多文件在namenode內存中的問題. HAR 文件的工作原理是在HDFS中建立一個分層的文件係統. 一個 HAR文件創建通過使用hadoop archive 命令,他通過運行一個MapReduce任務把HDFS中的小文件進行打包. 對於客戶端使用HAR文件係統沒有改變: 所有的原始文件是可見的和可訪問的 (通過使用 har:// URL). 然而, 在HDFS上的文件數量並沒有減少.
SequenceFile and MapFile File Layouts

在HDFS上讀文件比HAR上麵效率要高一些, 事實上,可能會比較慢因為每個HAR文件訪問需要兩個索引文件的讀取以及數據文件的讀取(見下圖). 雖然HAR文件能夠作為MapReduce的輸入文件 , HAR並沒有準許在進行Map操作的時候把所有的文件當著一個塊來操作. 它應該是提供一個輸入的格式能夠在HARs提升改進的地方, 實際上它並沒有. 請注意 MultiFileInputSplit, 即使在 HADOOP-4565 通過選擇本地文件分割來提高, 將也需要查詢每一個小的文件. 通過與SequenceFile文件性能比較是很有趣的, 所以說.現在HARs最常使用的是來處理文檔.

Sequence Files

通常回答關於“小文件問題” 是: 使用SequenceFile. SequenceFile文件的設計思想是使用文件名作為key文件內容作為值. 這在實踐中很好. 回到10,000 100KB 文件問題, 你可以寫一個程序把他們放到一個單獨的SequenceFile文件裏麵, 並且你可以通過串流的形勢對其進行訪問(直接或者通過MapReduce) 在SequenceFile文件上進行操作. 更神奇的地方是. SequenceFiles文件能夠被可拆分, 所以MapReduce可以打破成塊,每一塊獨立操作. 它們也支持壓縮, 不像HARs. 塊壓縮是大多數情況下最好的選擇, 由於壓縮了幾個記錄塊(相當於每個記錄).

它可以將現有的數據轉化成為SequenceFiles. 然而,完全有可能在並行創建一係列sequencefiles. (Stuart Sierra 已經寫了一篇很有用的關於 post 轉換tar文件到SequenceFile文件 — 這種工具是很有益的, 看到更多的人會很好).最好的設計在寫入數據的時候直接寫入到SequenceFiles文件裏麵, 如果可能,而不是寫小文件作為中間步驟.

HAR File Layout
不像HAR文件, SequenceFile文件沒法羅列出所有的keys,簡短的閱讀需要獲取通過整個文件. (MapFiles文件很像一個已經對key進行排序的 SequenceFiles 文件, 維護部分索引, 所以他們不能羅列所有它們的keys — 如圖所示.)

SequenceFile文件相當於Java的核心. TFile文件被設計成跨平台的, 是一個可以替代的 SequenceFile, 但它尚未提供.

HBase

如果你產生了很多小文件, 然而, 根據訪問模式, 不同類型的存儲可能更合適. HBase 存儲數據通過MapFiles (索引SequenceFiles), 是一個很好的選擇如果你需要MapReduce流分析同時也需要隨機訪問查看. 如果延遲是一個問題, 然而這裏有許多其他的選擇 — 看Richard Jones’ 傑出的survey of key-value stores.

轉載自 並發編程網 - ifeve.com

最後更新:2017-05-19 16:37:58

  上一篇:go  《Spark 官方文檔》Spark調優
  下一篇:go  《Maven官方指南》可選的依賴和依賴排除