我目前正在嘗試編寫一個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,我都需要確保確切的局部性否則我可能會重複讀取一些目錄,而其他的則根本不會。
任何幫助將不勝感激。
謝謝你的建議,1是不行的,這需要保持更新,因此數據只爲一天左右有用,因爲我讀的文件是一個活躍的一部分數據庫的數據將更加陳舊。 2很有趣,NLineInputFormat聽起來像是答案的一部分,但你指出並不能保證局部性。 3。聽起來似乎是合理的,但是你的意思是刪除其他3個節點,如果這就是你的意思,我不能讓部分集羣離線,集羣也需要能夠響應其他工作,這必須是考慮可能的運行時間的後臺任務。 – feldoh 2013-03-27 14:06:00
嗨菲爾多,你讓我對。部分集羣脫機。現在我明白這是不可能的,因爲它是一個生產集羣。 – Rags 2013-03-28 12:07:33
使用上述方法時,確保它在本地運行的一種方法是檢查映射中的文件位置,如果它是遠程拋出異常以使任務失敗。作業追蹤器將嘗試,直到任務成功,這意味着它在本地找到文件。但這是粗糙的方法。爲了使作業繼續下去,您可能需要將地圖任務的最大嘗試次數增加到很高的數字。 – Rags 2013-03-28 12:15:49