2013-03-27 103 views
1

我目前正在嘗試編寫一個map-reduce作業,其中輸入數據不在HDFS中,並且無法加載到HDFS中,這主要是因爲使用數據的程序無法使用HDFS中的數據,要將其複製到HDFS中,每個節點至少需要1TB。節點 - 本地地圖減少工作

所以我有4個目錄在我的集羣中的每個節點。理想情況下,我希望我的映射器只接收這4個本地目錄的路徑並使用file:/// var/mydata/...之類的東西讀取它們,然後1個映射器可以處理每個目錄。即總共16個Mappers。

但是爲了能夠做到這一點,我需要確保每個節點準確地有4個映射器,並且確切地說有4個映射器被分配了該機器本地的路徑。這些路徑是靜態的,因此可以硬編碼到我的fileinputformat和recordreader中,但是如何保證給定的分割結束於具有已知主機名的給定節點。如果它是在HDFS中,我可以使用FileInputFormat中的一個變量設置isSplittable爲false,並且hadoop會照顧它,但由於所有數據都是本地數據,因此會導致問題。

基本上我只需要能夠在我的集羣中的每個節點上抓取本地目錄結構一次,在這些目錄中處理SSTables集合併發出行(在映射器上),並減少結果(在減少步驟)爲HDFS進一步批量處理。

我注意到inputSplits提供了一個getLocations函數,但我相信這並不能保證執行的局部性,只是優化它,而且如果我嘗試在每個映射器中嘗試使用file:/// some_path,我都需要確保確切的局部性否則我可能會重複讀取一些目錄,而其他的則根本不會。

任何幫助將不勝感激。

回答

0

我看到有三種方法可以做到這一點。

1.)簡單地將數據加載到HDFS,你不想它做。但值得嘗試,因爲它對未來的處理將有用

2.)您可以使用NLineInputFormat。使用每個節點中的輸入文件的URL創建四個不同的文件。

file://192.168.2.3/usr/rags/data/DFile1.xyz 
....... 

將這些文件加載​​到HDFS和這些文件的編寫程序訪問使用這些URL中的數據的數據和處理數據。如果您使用1行NLineInputFormat。您將處理16個映射器,每個映射處理一個專用文件。這裏唯一的問題是,一個節點上的數據可能在另一個節點上處理的可能性很高,但是不會有任何重複的處理。3.您可以通過加載上述四個方法來進一步優化上述方法文件與URL分開。在加載任何這些文件時,您可以刪除其他三個節點,以確保文件完全進入數據文件本地存在的節點。加載時選擇複製爲1,以便塊不會被複制。該過程將增加地圖處理本地文件的地圖在很高程度上的可能性。

乾杯 抹布

+0

謝謝你的建議,1是不行的,這需要保持更新,因此數據只爲一天左右有用,因爲我讀的文件是一個活躍的一部分數據庫的數據將更加陳舊。 2很有趣,NLineInputFormat聽起來像是答案的一部分,但你指出並不能保證局部性。 3。聽起來似乎是合理的,但是你的意思是刪除其他3個節點,如果這就是你的意思,我不能讓部分集羣離線,集羣也需要能夠響應其他工作,這必須是考慮可能的運行時間的後臺任務。 – feldoh 2013-03-27 14:06:00

+0

嗨菲爾多,你讓我對。部分集羣脫機。現在我明白這是不可能的,因爲它是一個生產集羣。 – Rags 2013-03-28 12:07:33

+0

使用上述方法時,確保它在本地運行的一種方法是檢查映射中的文件位置,如果它是遠程拋出異常以使任務失敗。作業追蹤器將嘗試,直到任務成功,這意味着它在本地找到文件。但這是粗糙的方法。爲了使作業繼續下去,您可能需要將地圖任務的最大嘗試次數增加到很高的數字。 – Rags 2013-03-28 12:15:49