2010-10-26 70 views
1

我試圖使用map/reduce來處理大量的二進制數據。該應用程序的特點如下:記錄數量可能很大,因此我並不想將每條記錄作爲單獨的文件存儲在HDFS(我打算將它們全部連接成單個二進制序列文件),並且每條記錄都是一個大的連貫的(即不可分裂的)斑點,大小在一個到幾百MB之間。記錄將被C++可執行文件使用和處理。如果不是記錄的大小,Hadoop Pipes API可以:但是這似乎是基於將輸入映射/減少任務作爲連續的字節塊傳遞的,這在這種情況下是不切實際的。Hadoop Pipes:如何通過大數據記錄來映射/減少任務

我不確定最好的方法來做到這一點。是否有任何緩衝接口允許每個M/R任務以可管理的塊抽取多個數據塊?否則,我正在考慮通過API傳遞文件偏移量,並在C++端從HDFS中傳輸原始數據。

我想從任何類似嘗試任何人的任何意見 - 我對hadoop很新。

回答

1

Hadoop不適用於大小爲100MB的記錄。你會得到OutOfMemoryError和不均勻分割,因爲有些記錄是1MB,有些是100MB。通過Ahmdal's Law您的並行性將受到很大影響,從而降低吞吐量。

我看到兩個選項。您可以使用Hadoop streaming將您的大文件按原樣映射到您的C++可執行文件。由於這將通過標準輸入發送您的數據,因此它自然會進行流媒體和緩衝。您的第一個地圖任務必須將數據分解爲更小的記錄以供進一步處理。其他任務然後在較小的記錄上運行。

如果你真的不能分解它,讓你的地圖減少作業的文件名。第一個映射器獲取一些文件名,通過映射器C++可執行文件運行它們,並將它們存儲在更多文件中。 reducer被賦予了輸出文件的所有名稱,並重復使用reducer C++可執行文件。這不會耗盡內存,但會很慢。除了並行性問題之外,您不會將減少的作業調度到已有數據的節點上,從而導致非本地HDFS讀取。

+0

謝謝。關於非本地HDFS讀取 - 是否沒有辦法定義自定義輸入格式,該格式可以理解記錄實際上是指向HDFS中包含實際數據的文件名的指針,並且可以提供有關數據局部性的所需信息? (在我看來,處理文件名列表必須是一個相對常見的用例 - 我很驚訝沒有更好的支持......) – 2010-10-27 09:06:46

+0

我沒有看到一個簡單的方法來做到這一點。當您編寫HDFS文件時,它們會遍佈各處的節點,因此不能保證所有在一個輸入中命名的文件都在同一個數據節點上。 – 2010-10-27 16:03:54

+0

非常感謝Spike-這對我來說是一個非常有幫助的討論。最後一個快速問題 - 我從上面瞭解到,由於來自一個輸入分割的所有數據都會映射到一個映射,因此如果輸入分割在HDFS中包含多個文件名,則定義數據局部性是個問題。但是如果每個輸入分割都被限制爲只包含一個文件名呢?難道你不能把輸入分割的數據局部性的缺省定義覆蓋爲所引用的文件的缺省定義嗎?還是有一個原因,這將是一個壞主意? – 2010-10-29 07:51:03