2013-06-21 54 views
10

如果我需要對大小在200和500mb之間變化的成千上萬個gzip文件進行順序掃描(不可分割),那麼適當的塊這些文件的大小?Hadoop - 適用於不同大小(200-500mb)的不可分割文件的合適塊大小

爲了這個問題,我們假設所做的處理速度非常快,因此即使對於大塊大小,重新啓動映射器也不是昂貴的。

我的理解是:

  1. 有幾乎塊大小的上限,因爲有「大量文件」爲映射器對我的簇的大小適當的量。
  2. 爲了確保數據本地化,我希望每個gzip文件都在1個塊中。

但是,gzip文件大小不一。如果我選擇一個〜500mb的塊大小(例如,所有輸入文件的最大文件大小),數據如何存儲?選擇「非常大」的塊大小比如2GB會更好嗎?在兩種情況下,HDD容量是否浪費過度?

我想我真的在問如何在hdfs塊中實際存儲和分割文件 - 以及試圖瞭解不可拆分文件的最佳實踐。

更新:一個具體的例子

說我是三個200 MB的文件,存儲在下面的插圖運行的MR工作。

如果HDFS存儲了像情況A那樣的文件,則3個映射器將被保證能夠分別處理「本地」文件。但是,如果文件按情況B存儲,則一個映射器需要從另一個數據節點獲取文件2的一部分。

由於有大量的空閒塊,HDFS存儲文件如情況A或情況B所示嗎?

HDFS strategies

回答

3

如果你有非可分開的文件,則最好使用較大的塊大小 - 自己一樣大的文件(或更大,這都沒有區別)。

如果塊大小小於整個文件大小,那麼您可能會遇到所有塊都不在同一個數據節點上並且丟失數據局部性的可能性。這對於可拆分文件不是問題,因爲將爲每個塊創建映射任務。

作爲用於塊大小的上限,我知道,對於某些較舊版本的Hadoop,限爲2GB(在其上方的塊內容物不能獲得) - 見https://issues.apache.org/jira/browse/HDFS-96

沒有缺點,用於存儲更小用更大的塊大小的文件 - 強調這一點考慮1MB和2 GB的文件,各有2 GB的塊大小:

  • 1 MB - 1塊,在名稱節點單一的入口,1 MB物理存儲在每個數據節點上的副本
  • 2 GB - 1塊,單個條目在Nam演進節點,2 GB物理地存儲在每個數據節點複製

所以其它所要求的物理存儲,沒有缺點的名稱節點塊表(這兩個文件具有在塊表中的單個條目)。

唯一可能的缺點是複製較小塊與較大塊所需的時間,但另一方面,如果數據節點從羣集中丟失,則任務需要2000 x 1 MB的塊才能進行復制塊2 GB塊。

更新 - 一個工作實例

看到,因爲這會引起一些混亂,繼承人一些工作的例子:

假設我們有一個300 MB HDFS塊大小的系統,並且使事情變得更簡單我們有一個只有一個數據節點的假集羣。

如果你想存儲一個1100MB的文件,那麼HDFS會將該文件分解成最多 300MB的塊,並將其存儲在數據節點中的特殊塊索引文件中。如果你去到數據節點,並期待在其中存儲物理磁盤上的索引塊文件,您可能會看到這樣的事情:

/local/path/to/datanode/storage/0/blk_000000000000001 300 MB 
/local/path/to/datanode/storage/0/blk_000000000000002 300 MB 
/local/path/to/datanode/storage/0/blk_000000000000003 300 MB 
/local/path/to/datanode/storage/0/blk_000000000000004 200 MB 

注意該文件是不是300 MB整除,所以該文件的最後一個塊的大小與文件的模塊大小相同。

現在,如果我們重複相同的鍛鍊比塊尺寸小的文件,比如說1 MB,看看它是如何被存儲在數據節點上:

/local/path/to/datanode/storage/0/blk_000000000000005 1 MB 

再次注意,實際的文件存儲在數據節點上是1 MB,不是一個200 MB的文件與299 MB零填充(我認爲這是混淆來自哪裏)。

現在塊大小確實起作用的一個因素是名稱節點。對於上述兩個例子中,名稱節點需要維持地圖中的文件名的,以阻止名稱和數據節點的位置(以及,在總文件大小和塊大小):

filename  index  datanode 
------------------------------------------- 
fileA.txt blk_01 datanode1 
fileA.txt blk_02 datanode1 
fileA.txt blk_03 datanode1 
fileA.txt blk_04 datanode1 
------------------------------------------- 
fileB.txt blk_05 datanode1 

可以看到如果要爲fileA.txt使用1 MB的塊大小,則上圖中需要1100個條目而不是4個(這會在名稱節點中需要更多內存)。同時拉回所有塊將會更加昂貴,因爲您要對datanode1進行1100次RPC調用而不是4次。

+0

如果我在300 MB塊中存儲3 200 MB文件會發生什麼?將每個第二個文件分成兩個塊,還是每個塊中剩餘100 MB未使用?將塊大小設置爲max(filesize)或max(filesize)* 20'可能會對性能(文件不可分割時)或存儲「浪費」產生巨大影響,這取決於文件如何跨塊傳輸。 – jkgeyti

+0

如果存儲塊大小爲300 MB塊大小的200 MB文件,則不會浪費。它不像傳統文件系統上的塊大小,未使用的100 MB不會被浪費。 HDFS中唯一的低效就是如果你存儲的塊大小太小的大文件,在這種情況下主要是名稱節點的內存需求來跟蹤文件的每個塊 –

+0

好吧,說整個設置是調整的僅處理這些200 MB文件。如果我理解正確,每個200 MB文件將存儲在單獨的300 MB塊中。當然,其他文件在每個塊中仍有100 MB可用,但是如果我只*存儲200 MB文件,那麼我實際上會在每個塊中留下100 MB未使用的文件,對嗎? – jkgeyti

1

我將嘗試通過示例的方式突出顯示塊拆分在引用文件大小方面的差異。在HDFS您有:

Splittable FileA size 1GB 
dfs.block.size=67108864(~64MB) 

對這個文件MapRed工作:

16 splits and in turn 16 mappers. 

讓我們來看看這個場景與壓縮(非裂開的)文件:

Non-Splittable FileA.gzip size 1GB 
dfs.block.size=67108864(~64MB) 

MapRed工作對此文件:

16 Blocks will converge on 1 mapper. 

最好主動避免這種情況,因爲這意味着tasktracker將不得不提取16個數據塊,其中大部分數據對於任務跟蹤器來說不會是本地的。

最後,塊,拆分和文件之間的關係可以概括如下:

               block boundary 
|BLOCK   | BLOCK  | BLOCK  | BLOCK |||||||| 
|FILE------------|----------------|----------------|---------| 
|SPLIT   |    |    |  | 

分割可以超出塊,因爲分裂取決於如何分割InputFormat類定義該文件可能與塊大小不一致,所以拆分擴展到包括源內的查找點。

+0

這有助於很多,謝謝。我可以問你和我問克里斯懷特一樣的問題嗎?如果我在300 MB塊中存儲3 200 MB文件會發生什麼?將每個第二個文件分成兩個塊,還是每個塊中剩餘100 MB未使用? – jkgeyti

+0

看起來Chris很好的回答了你在評論中提出的問題,但是這裏的要點是,與傳統文件系統不同,HDFS有效地利用了它的空間,因此塊遵從文件大小的邏輯邊界而不會浪費空間。 – Engineiro