MapReduce中的map做兩層for循環,效率特別低?

輸入文件格式如:

1.5-10,2.6-11,3.1-6
1.2-9,2.7-10
1.3-6,3.9-13
2.8-13,3.9-15

對應的輸出文件結果是:

1,2 5-10,6-11;2-9,7-10
1,3 5-10,1-6;3-6,9-13
2,3 6-11,1-6;8-13,9-15

我自己目前的代碼是:

public static class TokenizerMapper
extends Mapper&{
private String temp[];
private Text keyout = new Text();
private Text valueout =new Text();
public void map(LongWritable key, Text value, Context context
) throws IOException, InterruptedException {
temp=value.toString().split("\,");
System.out.println(temp.length);
// System.out.println(temp[0]);
for(int i=0;i&<=temp.length-2;i++){ String temp1[]; temp1=temp[i].toString().split("\."); System.out.println(temp1.length); String ikey = temp1[0]; String ivalue = temp1[1]; for(int j=i+1;j&<=temp.length-1;j++){ String temp2[]; temp2=temp[j].toString().split("\."); String jkey = temp2[0]; String jvalue = temp2[1]; keyout.set(ikey+","+jkey); valueout.set(ivalue+","+jvalue); context.write(keyout,valueout); } }

在有9個計算結點的集群上跑,輸入文件大小為63M,目前跑了43min都沒有跑完,求問大家有什麼可以優化的策略和方法,把時間降下來。

----------------------------------------------------------------------------------

更新:跑了5小時都沒跑完!

63M是18個文件的總大小,我後來有分析了下輸入數據,定義1.5-10為一個單位,文件中有的一行會有3000多個單位,然後拆分的話,就是3000平方對的key和value,我個人覺得可能是鍵值對個數太多,然後本身拆分代價就高,又要shuffle排序,可能效率不會高。

求教是不是因為這樣的問題,怎樣修改演算法比較好?

我把輸入文件載到雲盤裡了,請大家幫忙看一看。代碼也放在裡面了

鏈接:http://pan.baidu.com/s/1hrcgBbu 密碼:h002


謝邀。

對mr了解不多,但做過兩年多集群計算中間件的技術支持,幫你想幾個troubleshooting點吧。

對於這種集群計算的環境,你的問題一上來就把注意力集中在應用層代碼上了,而且也不是從時間複雜度出發的。你在懷疑是不是兩層循環效率就低,這多少有些猜的意思。要不得。

所以你看下面幾點你有沒有試過?

1,不到七十兆的輸入文件,用單機跑都能分分鐘搞定。所以首先請你把九台計算節點降為一台,最好與管理幾點為同一台試試。這樣可以排除區域網硬體、防火牆、共享文件系統(比如hdfs或gpfs)配置不良造成的影響。

2,由於輸入數據較小,所以降為單計算節點,並配置只使用一個mapper,這樣你就只有一個進程需要分析了。好,分析效率應該使用profiler工具而不是猜。我不是特別熟悉java,不知道有沒有java的profiler,但你至少可以用log啊!在你的mapper類的主task函數的入口和出口合拿一次系統時間,寫到/tmp里一個log文件里,文本格式,一行一個1970時間值,然後寫一腳本累加一下,看看系統停留在mapper里的時間與job總時間怎麼比。

3,如果上述已經可以排除mapper的問題了,然後你要重點檢查網路和dfs。同樣的,寫個測試程序在你的dfs里讀寫一下大文件,再在本地磁碟上讀寫同樣大的文件。dfs是可以稍慢一點但如果成倍的慢就是問題了。至於網路,這個就稍微複雜難說了,要不你搞個ftp server再在不同機器上下載個大文件測測速度??

4,如果所有矛頭都指向你的mapper(我預感這可能性不大),那你就好好算算大O吧,不要看著二層循環就覺得一定是n方的。

最後擴展的說一句,不要覺得九台機器就算是擁有集群計算的威力了:)我支持過的客戶,一般cluster少於一千台機器人家都不好意思開ticket~呵呵我意思是說,要想再快些,你倒是加機器啊


謝邀

雖然不懂這事件模型的物理意義,但是從輸出看這個運算處理量不小,你還一行3000個所說的單位。

感覺不是map reduce的問題。要不要考慮設計下新的演算法,先降低時間複雜度,設計完後再抽象出map和reduce。

還可以從處理邏輯中抽象出多線程處理邏輯,我構想了下覺得可以。

然而,code寫得不咋的。像一年前的我,還可以優化和改進。說不定寫好一點就能跑完了。

最後,要不要考慮用Spark。嘿嘿嘿~


mapper 輸出太多,一行有重複 key 1,1,2,2的話,key = "1,1" 或者 "2,2" 等都會輸出。可以在mapper 過濾掉。


  1. 你做split的次數太多了,完全可以每一段只做一次
  2. 你在處理每一個value的時候,創建了很多新的對象,也許創建與銷毀對象佔用了大量的時間。嘗試復用這些對象。


掃了一眼沒看懂這數據是個什麼規律……我就不接著看了

這點輸入數據,你單線程跑也跑不了多久啊,一般mr這麼出問題肯定是程序寫的有問題,可以考慮一下是不是mapper膨脹了很多,然後剛好又在reducer數據傾斜了。當然集群剛好有些機器在抽風也是有可能的。。。

PS: split里的,不用轉義


1.mapper數量:試試加reducer數量, 因為一般情況下mapper數量是按照reducer數量分配的, 你這麼小的輸入文件說不定只給你一個Mapper.

2.mapper沒必要寫這麼多,盡量用combiner

3.=。=檢查下機器上是不是有別的進程在跑,如果是你之前的程序的話強行kill掉。

4.要養成寫注釋的習慣

5.能排個版么?


43min! OMG! My intuition tell me that a for loop must not exit.

So first test in terminal: head -10 input | ./mapper | ./reducer

If it failed, you got it, the code has bug.

If not, no way.

Thanks.


推薦閱讀:

spark的shuffle和Hadoop的shuffle(mapreduce)的區別和關係是什麼?
研一學生~突然搞起了Big Data。在學Hadoop中,突然意識到只會用工具是遠遠不夠的,很想搞懂立面的演算法和思想。請教達人們指點分散式存儲與運算的主要思想與演算法?
Hadoop和Hadoop2有很大的區別么?
如何入門分散式計算?

TAG:分散式計算 | Java編程 | MapReduce |