MapReduce初窺·二
依然在看MapReduce運行過程中宏觀的東西,拋開某個具體模塊的細節,在上一篇文章之後,做一些補充,可能會有重複。
一些術語:
- job:我們提交的一個工作單元就是一次job。它包括輸入數據、MapReduce程序、配置信息
- task:一個job會被分成若干個task來執行,即任務,這些任務運行在集群的節點上,並通過YARN來進行調度。分為2類任務,map、reduce
- input split:輸入分片。MapReduce 的輸入數據劃分成等長的小數據塊,稱為輸入分片,每個輸入分片構建一個map任務
針對上一篇文章要補充的點:
input split與HDFS一個block的大小:
HDFS的一個塊的大小,默認是128MB,比磁碟的塊要大很多,磁碟一般在512B。設計地這麼大是為了最小化定址開銷(如果塊足夠大,從磁碟傳輸數據的時間會明顯大於定位它花費的時間,這樣就很好)。這裡還有一個特點,這個128MB不一定是真正佔用的大小,即,如果一個128MB的快里只放了一個1MB的文件,它只會佔用1MB的磁碟大小。
那麼input split的大小為什麼推薦和HDFS的一個一樣大呢,因為如果一個分片跨越2個數據塊,那麼必然有一部分數據通過網路傳輸到map 任務執行的節點,這樣效率低。如果只有一個塊,map任務會被發往該節點,這樣就完全可以利用本地磁碟進行讀取,效率較高。
map與reduce的結果放哪兒:
map的輸入來自於HDFS,輸出則是寫入本地硬碟的。因為這個輸出只是中間結果,一般還要餵給reduce任務,而寫入HDFS就要走網路,會小題大做,而且一旦job結束,map的輸出結果就會被刪除。
如果運行map任務的節點失敗了,且此時map的中間結果還沒有餵給reduce,那麼Hadoop將在另一個節點上重新運行該map任務。
reduce任務不具有數據本地化的優勢,單個reduce任務的輸入輸出通常來自於所有map任務的輸出,經過網路發送到運行reduce任務的節點,在reduce端合併。
reduce的輸出通常存儲在HDFS上,以實現可靠存儲。第一個replica存儲在本地節點上,其他replica會存儲在其他節點。
如果沒有reduce任務,則map的結果輸出到HDFS,這一般是唯一的非本地節點數據傳輸。
Sort與Shuffle:
如果只有一個reduce任務,各個map的輸出,都會通過網路傳送過來,然後sort,根據key排序。
當有多個reduce任務時,每個map任務就會針對輸出進行分區,partition,為每個reduce任務建立一個分區,每個分區中有很多鍵值對,且,每個鍵對應的鍵值對,都在同一個分區中——
即如果是溫度統計,以年份為key,可以按照年代來分區,一個分區可能就包含50~59年的所有鍵值對,且其他的分區不會再含有50~59的鍵值對了。
partition和reduce的個數是一一對應的,而Shuffle的過程,就是把每個map任務將自己的每個partition通過網路傳給reduce節點。
Shuffle和Sort的過程是同時的。
Combiner函數:
為了盡量避免map和reduce任務之間的數據傳輸,combiner出現了,它可以讓用戶指定對每個map的輸出做一次combiner,而combiner的輸出,成為reduce的輸入。combiner的調用與否、調用次數,不會影響reduce的輸出
但不是所有的任務都適合選擇combiner函數的,比如這2種任務:
- 求最大值
- 求均值
明顯求最大值適合用Combiner、均值不適合。
希望對你有幫助。
推薦閱讀: