1. 程式人生 > >Hadoop MapReduce Job效能調優——Map和Reduce個數

Hadoop MapReduce Job效能調優——Map和Reduce個數

 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任務,從而提高負載均衡。
  • 對一 個job的map數和reduce數的設定對一個job的執行是非常重要的,並且非常簡單。以下是一些

    設 置這幾個值的經驗總結:

    • 如果job的每個map或者 reduce task的執行時間都只有30-40秒鐘,那麼就減少該job的map或者reduce數,每一個task(map|reduce)的setup和加入到 排程器中進行排程,這個中間的過程可能都要花費幾秒鐘,所以如果每個task都非常快就跑完了,就會在task的開始和結束的時候浪費太多的時間。JVM 的reuse方式也可以解決 這個問題。
    • 如 果某個input的檔案 非常的大,比如 1TB,可以考慮將hdfs上的每個block size設大,比如設成256MB或者512MB,這樣map和reduce的資料 可以減小。而且使用者還可以通過命令 
      hadoop distcp -Ddfs.block.size=$[256*1024*1024] /path/to/inputdata /path/to/inputdata-with-largeblocks的方式來將已經存在咋hdfs上的資料進行大塊化。然後刪除掉原先的檔案。
    • 只 要每個task都執行至少30-40秒鐘,就可以考慮將mapper數擴大,比如叢集的map slots為100個,那麼就不要將一個job的mapper設成101,這樣前100個map能夠並行完成,而最後一個map要在前100個 mapper結束後才開始,因此在reduce開始執行前,map階段的時間幾乎就要翻倍。
    • 儘量不要執行太多的reduce task。對大多數job來說,最好rduce的個數最多和叢集中的reduce持平,或者比叢集的 reduce slots小。這個對於小叢集而言,尤其重要。