對Map的結果進行排序并傳輸到Reduce進行處理 Map的結果并不是直接存放到硬盤,而是利用緩存做一些預排序處理 Map會調用Combiner,壓縮,按key進行分區(qū)、排序等,盡量減少結果的大小 每個Map完成后都會通知Task,然后Reduce就可以進行處理
當Map程序開始產生結果的時候,并不是直接寫到文件的,而是利用緩存做一些排序方面的預處理操作
每個Map任務都有一個循環(huán)內存緩沖區(qū)(默認100MB),當緩存的內容達到80%時,后臺線程開始將內容寫到文件,此時Map任務可以繼續(xù)輸出結果,但如果緩沖區(qū)滿了,Map任務則需要等待
寫文件使用round-robin方式。在寫入文件之前,先將數據按照Reduce進行分區(qū)。對于每一個分區(qū),都會在內存中根據key進行排序,如果配置了Combiner,則排序后執(zhí)行Combiner(Combine之后可以減少寫入文件和傳輸的數據)
每次結果達到緩沖區(qū)的閥值時,都會創(chuàng)建一個文件,在Map結束時,可能會產生大量的文件。在Map完成前,會將這些文件進行合并和排序。如果文件的數量超過3個,則合并后會再次運行Combiner(1、2個文件就沒有必要了)
如果配置了壓縮,則最終寫入的文件會先進行壓縮,這樣可以減少寫入和傳輸的數據
一旦Map完成,則通知任務管理器,此時Reduce就可以開始復制結果數據
Map的結果文件都存放到運行Map任務的機器的本地硬盤中
如果Map的結果很少,則直接放到內存,否則寫入文件中
同時后臺線程將這些文件進行合并和排序到一個更大的文件中(如果文件是壓縮的,則需要先解壓)
當所有的Map結果都被復制和合并后,就會調用Reduce方法
Reduce結果會寫入到HDFS中
一般的原則是給shuffle分配盡可能多的內存,但前提是要保證Map、Reduce任務有足夠的內存
對于Map,主要就是避免把文件寫入磁盤,例如使用Combiner,增大io.sort.mb的值
對于Reduce,主要是把Map的結果盡可能地保存到內存中,同樣也是要避免把中間結果寫入磁盤。默認情況下,所有的內存都是分配給Reduce方法的,如果Reduce方法不怎么消耗內存,可以mapred.inmem.merge.threshold設成0,mapred.job.reduce.input.buffer.percent設成1.0
在任務監(jiān)控中可通過Spilled records counter來監(jiān)控寫入磁盤的數,但這個值是包括map和reduce的
對于IO方面,可以Map的結果可以使用壓縮,同時增大buffer size(io.file.buffer.size,默認4kb)
屬性 | 默認值 | 描述 |
---|---|---|
io.sort.mb | 100 | 映射輸出分類時所使用緩沖區(qū)的大小. |
io.sort.record.percent | 0.05 | 剩余空間用于映射輸出自身記錄.在1.X發(fā)布后去除此屬性.隨機代碼用于使用映射所有內存并記錄信息. |
io.sort.spill.percent | 0.80 | 針對映射輸出內存緩沖和記錄索引的閾值使用比例. |
io.sort.factor | 10 | 文件分類時合并流的最大數量。此屬性也用于reduce。通常把數字設為100. |
min.num.spills.for.combine | 3 | 組合運行所需最小溢出文件數目. |
mapred.compress.map.output | false | 壓縮映射輸出. |
mapred.map.output.compression.codec | DefaultCodec | 映射輸出所需的壓縮解編碼器. |
mapred.reduce.parallel.copies | 5 | 用于向reducer傳送映射輸出的線程數目. |
mapred.reduce.copy.backoff | 300 | 時間的最大數量,以秒為單位,這段時間內若reducer失敗則會反復嘗試傳輸 |
io.sort.factor | 10 | 組合運行所需最大溢出文件數目. |
mapred.job.shuffle.input.buffer.percent | 0.70 | 隨機復制階段映射輸出緩沖器的堆棧大小比例 |
mapred.job.shuffle.merge.percent | 0.66 | 用于啟動合并輸出進程和磁盤傳輸的映射輸出緩沖器的閥值使用比例 |
mapred.inmem.merge.threshold | 1000 | 用于啟動合并輸出和磁盤傳輸進程的映射輸出的閥值數目。小于等于0意味著沒有門檻,而溢出行為由 mapred.job.shuffle.merge.percent單獨管理. |
mapred.job.reduce.input.buffer.percent | 0.0 | 用于減少內存映射輸出的堆棧大小比例,內存中映射大小不得超出此值。若reducer需要較少內存則可以提高該值. |
更多建議: