Hadoop中MapTask的並行度的決定機制
在MapReduce程式的執行中,並不是MapTask越多就越好。需要考慮資料量的多少及機器的配置。如果資料量很少,可能任務啟動的時間都遠遠超過資料的處理時間。同樣可不是越少越好。
MapTask的數量根據資料分片來決定,那麼該如何切分呢?
假如我們有一個300M的檔案,它會在HDFS中被切成3塊。0-128M,128-256M,256-300M。並被放置到不同的節點上去了。在MapReduce任務中,這3個Block會被分給3個MapTask。
MapTask在任務切片時實際上也是分配一個範圍,只是這個範圍是邏輯上的概念,與block的物理劃分沒有什麼關係。但在實踐過程中如果MapTask讀取的資料不在執行的本機,則必須通過網路進行資料傳輸,對效能的影響非常大。所以常常採取的策略是就按照塊的儲存切分MapTask,使得每個MapTask儘可能讀取本機的資料,這就是資料本地化策略。
如果一個Block非常小,也可以把多個小Block交給一個MapTask。
所以MapTask的切分要看情況處理。預設的實現是按照Block大小進行切分。MapTask的切分工作由客戶端(我們寫的main方法)負責。一個切片就對應一個MapTask例項。
MapTask並行度的決定機制
一個job的map階段並行度由客戶端在提交job時決定。同時決定切片數量,收集整個job的環境資訊,檢測環境的合法性,輸入輸出路徑的合法性。
而客戶端對map階段並行度的規劃的基本邏輯為:
將待處理資料執行邏輯切片(即按照一個特定切片大小,將待處理資料劃分成邏輯上的多個split),然後每一個split分配一個mapTask並行例項處理
MapTask並行度的經驗
如果硬體配置為2*12core + 64G,恰當的map並行度是大約每個節點20-100個map,最好每個map的執行時間至少一分鐘。
如果job的每個map或者 reduce task的執行時間都只有30-40秒鐘,那麼就減少該job的map或者reduce數,每一個task(map|reduce)的setup和加入到排程器中進行排程,這個中間的過程可能都要花費幾秒鐘,所以如果每個task都非常快就跑完了,就會在task的開始和結束的時候浪費太多的時間。
配置task的JVM重用可以改善該問題:
(mapred.job.reuse.jvm.num.tasks,預設是1,表示一個JVM上最多可以順序執行的task
數目(屬於同一個Job)是1。也就是說一個task啟一個JVM)
如果input的檔案非常的大,比如1TB,可以考慮將hdfs上的每個block size設大,比如設成256MB或者512MB