![](/img/trans.png)
[英]Hadoop Mapreduce MultipleInputs cannot load the mapper classes
[英]What is the control flow of Hadoop mapper with MultipleInputs?
目標:實施Reduce Side Join
我的代碼中目前有Job Chaining(兩個工作)。 現在我想在reduce端實現另一項工作。 我必須接受多個輸入:
Input #1:
前一個減速器的輸出。
Input #2:
來自HDFS的新文件以實現連接。
看到了一些有關如何使用MultipleInputs.addInputhPath(job, Path, InputFormat.class, Mapper.class);
因此,我知道我必須使用兩次,一次用於Input #1
,一次用於Input #2
。
Question 1:
然后,如果我使用兩個單獨的映射器和一個reducer,哪個映射器將首先執行(或者將並行執行)? 如何在化簡器端檢查哪個映射器發出了<key, value>
對?
Question 2:
如果我使用單個映射器和單個reducer,控制流程將是什么?
Question 3:
更多的hack,即不使用MultipleInputs
使用DistributedCache
在reducer的setup()
方法中加載Input #2
是否可以(在性能方面)? 並將前一個減速器的輸出作為作業的唯一輸入。
Note:
Input #2
文件的大小非常小。
答案1:
如果有可用的插槽,則兩個Map
任務應並行運行。 單個插槽的存在可能會導致它們按順序運行(可能會發生交錯),但這不是正常情況。 如果Mapper序列有一些配置,我不知道這一點。
我再次懷疑是否有任何api
可以用來識別哪個Mapper發出了<key, value>
。 確切地說,由於不同的地圖可能發出相同的key
,因此僅需要標識value
即可。 通常,這是通過在輸出值上添加前綴標簽並在reducer中解析這些標簽來實現的。 例如:
if(value.toString.startsWith("Input#1")){ //processing code }
查看此博客文章 ,其中包含所有必需的技巧和竅門。 請注意,所有這些示例均使用舊的mapred
api。 但是邏輯在任何情況下都是相同的。
答案2:
如果沒有MultipleInputs
,則必須在Map
使用可用的Context
對象標識傳入對的文件名。 例如:
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String fileName = ((FileSplit) context.getInputSplit()).getPath().getName();
//............
}
然后,只需在適當的標簽前添加值以輸出值即可,其余與答案1相同。
答案三:
這很棘手。 當要添加到緩存中的文件很小時,使用DistributedCache
進行連接可以提高性能。 這可能是由於該作業現在以較少的Map
任務運行的事實。 但這會對大文件產生不利影響。 難題是要知道有多少字節被認為是DistributedCache
小。
由於您提到Input#2文件非常小,因此這應該是您最合適的解決方案。
注意:這篇文章的許多評論都是基於(一點)觀點的。 期待專家的投入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.