1. 程式人生 > >MapReduce Map數 reduce數設定

MapReduce Map數 reduce數設定

JobConf.setNumMapTasks(n)是有意義的,結合block size會具體影響到map任務的個數,詳見FileInputFormat.getSplits原始碼。假設沒有設定mapred.min.split.size,預設為1的情況下,針對每個檔案會按照min (totalsize[所有檔案總大小]/mapnum[jobconf設定的mapnum], blocksize)為大小來拆分,並不是說檔案小於block size就不去拆分。 


2.http://hadoop.hadoopor.com/thread-238-1-1.html 
不知道你是要提高整個叢集的map/reduce任務數,還是單個節點可並行執行的map/reduce任務數?對於前者是一般只設置reduce任務數,而map任務數是由Splits個數決定的; 對於後者,是可以在配置中設定的,分別為:mapred.tasktracker.map.tasks.maximum 
mapred.tasktracker.reduce.tasks.maximum 

另外,還有個引數mapred.jobtracker.taskScheduler.maxRunningTasksPerJob,用來控制一個job最大並行tasks數,這個是指在叢集最大並行數。 

3.我的理解
:具體看FileInputFormat.java的程式碼 
map tasks的個數只要是看splitSize,一個檔案根據splitSize分成多少份就有多少個map tasks。而splitSize的計算(看FileInputFormat的原始碼):splitSize = Math.max(minSize, Math.min(maxSize, blockSize));而 
minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job));即是某種格式的檔案的最小分割size(如看原始碼sequenceFile是2000)和整個job配置的最小分割size(即mapred-default.xml中mapred.min.split.size的值)之間的較大的那個 
maxSize是mapred.max.split.size(mapred-default.xml中竟然沒有,我試了一下,在mapred-site.xml中配置覆蓋也沒有用,具體用法參照
http://osdir.com/ml/mahout-user.lucene.apache.org/2010-01/msg00231.html
用引數配置: hadoop jar /root/mahout-core-0.2.job org.apache.mahout.clustering.lda.LDADriver -Dmapred.max.split.size=900...),如果不配置,預設值是long型別的最大值。(mapred.max.split.size不推薦配置(試)) 
blockSize是即hdfs-default.xml中dfs.block.size的值,可在hdf-site.xml中覆蓋.這個值必須是512的倍數,如果想要數量更多的map的tasks的個數,可以把dfs.block.size設得小一點,512,1024等等,反正上面的公式保證了即使你這個blocksize設得比某種格式的檔案的最小分割size要小,最後還是選者這種格式的最小分割size,如果blocksize比它大,則選用blocksize作為splitSize的大小. 

總結
:如果想要多一點的map tasks,(1)可以設定dfs.block.size小一點,sequenceFile推薦2048。。。(試)在eclipse執行時,dfs.block.size是由eclipse中mapreduce的設定(dfs.block.size)生效的,而不是hadoop的conf中的配置檔案,但是如果用終端hadoop jar命令跑的話,應該是由hadoop的conf中的配置檔案決定生效的 
(2)推薦: 可以分成多個sequenceFile來作為輸入(把上層目錄作為輸入路徑即可,上層目錄下包括的必為清一色的sequenceFile),輸入路徑 "./"或指定上層目錄檔名 

reduce task的個數: 

可通過job.setNumReduceTasks(n);設定。多個reduce task的話就會有多個reduce結果,part-r-00000, part-r-00001, ...part-r-0000n 

  • 增加task的數量,一方面增加了系統的開銷,另一方面增加了負載平衡和減小了任務失敗的代價;
  • map task的數量即mapred.map.tasks的引數值,使用者不能直接設定這個引數。Input Split的大小,決定了一個Job擁有多少個map。預設input split的大小是64M(與dfs.block.size的預設值相同)。然而,如果輸入的資料量巨大,那麼預設的64M的block會有幾萬甚至幾十萬的Map Task,叢集的網路傳輸會很大,最嚴重的是給Job Tracker的排程、佇列、記憶體都會帶來很大壓力。mapred.min.split.size這個配置項決定了每個 Input Split的最小值,使用者可以修改這個引數,從而改變map task的數量。
  • 一個恰當的map並行度是大約每個節點10-100map,且最好每個map的執行時間至少一分鐘。
  •  reduce task的數量由mapred.reduce.tasks這個引數設定,預設值是1。
  • 合適的reduce task數量是0.95或者0.75*( nodes * mapred.tasktracker.reduce.tasks.maximum), 其中,mapred.tasktracker.tasks.reduce.maximum的數量一般設定為各節點cpu core數量,即能同時計算的slot數量。對於0.95,當map結束時,所有的reduce能夠立即啟動;對於1.75,較快的節點結束第一輪reduce後,可以開始第二輪的reduce任務,從而提高負載均衡

由Hive來執行相關的查詢

Hadoop中預設的mapred.tasktracker.map.tasks.maximum設定是2

也即:每一個tasktracker同時執行的map任務數為2

照此預設設定,查詢80天某使用者的操作日誌,耗時5mins, 45sec

經過測試,發現將mapred.tasktracker.map.tasks.maximum設定為節點的cpu cores數目或者數目減1比較合適

此時的執行效率最高,大概花費3mins, 25sec

我們現在的機器都是8核的,所以最終配置如下:

<property>
    <name>mapred.tasktracker.map.tasks.maximum</name>
    <value>8</value>
    <description>The maximum number of map tasks that will be run
    simultaneously by a task tracker.
    </description>
< /property>

而對於mapred.map.tasks(每個job的map任務數)值,hadoop預設值也為2

可以在執行hive前,通過set mapred.map.tasks=24來設定

但由於使用hive,會操作多個input檔案,所以hive預設會把map的任務數設定成輸入的檔案數目

即使你通過set設定了數目,也不起作用…