參數:io.sort.mb(default 100)
當map task開始運算,併產生中間數據時,其產生的中間結果並非直接就簡單的寫入磁盤。
而是會利用到了內存buffer來進行已經產生的部分結果的緩存,
並在內存buffer中進行一些預排序來優化整個map的性能。
每一個map都會對應存在一個內存buffer,map會將已經產生的部分結果先寫入到該buffer中,
這個buffer默認是100MB大小,
但是這個大小是可以根據job提交時的參數設定來調整的,
當map的產生數據非常大時,並且把io.sort.mb調大,
那麼map在整個計算過程中spill的次數就勢必會降低,
map task對磁盤的操作就會變少,
如果map tasks的瓶頸在磁盤上,這樣調整就會大大提高map的計算性能。
參數:o.sort.spill.percent(default 0.80,也就是80%)
map在運行過程中,不停的向該buffer中寫入已有的計算結果,
但是該buffer並不一定能將全部的map輸出緩存下來,
當map輸出超出一定閾值(比如100M),那麼map就必須將該buffer中的數據寫入到磁盤中去,
這個過程在mapreduce中叫做spill。
map並不是要等到將該buffer全部寫滿時才進行spill,
因爲如果全部寫滿了再去寫spill,勢必會造成map的計算部分等待buffer釋放空間的情況。
所以,map其實是當buffer被寫滿到一定程度(比如80%)時,就開始進行spill。
這個閾值也是由一個job的配置參數來控制,
這個參數同樣也是影響spill頻繁程度,進而影響map task運行週期對磁盤的讀寫頻率的。
但非特殊情況下,通常不需要人爲的調整。調整io.sort.mb對用戶來說更加方便。
參數:io.sort.factor
當map task的計算部分全部完成後,如果map有輸出,就會生成一個或者多個spill文件,這些文件就是map的輸出結果。
map在正常退出之前,需要將這些spill合併(merge)成一個,所以map在結束之前還有一個merge的過程。
merge的過程中,有一個參數可以調整這個過程的行爲,該參數爲:io.sort.factor。
該參數默認爲10。它表示當merge spill文件時,最多能有多少並行的stream向merge文件中寫入。
比如如果map產生的數據非常的大,產生的spill文件大於10,而io.sort.factor使用的是默認的10,
那麼當map計算完成做merge時,就沒有辦法一次將所有的spill文件merge成一個,而是會分多次,每次最多10個stream。
這也就是說,當map的中間結果非常大,調大io.sort.factor,
有利於減少merge次數,進而減少map對磁盤的讀寫頻率,有可能達到優化作業的目的。
參數:min.num.spill.for.combine(default 3)
當job指定了combiner的時候,我們都知道map介紹後會在map端根據combiner定義的函數將map結果進行合併。
運行combiner函數的時機有可能會是merge完成之前,或者之後,這個時機可以由一個參數控制,
即min.num.spill.for.combine(default 3),當job中設定了combiner,並且spill數最少有3個的時候,
那麼combiner函數就會在merge產生結果文件之前運行。
通過這樣的方式,就可以在spill非常多需要merge,並且很多數據需要做conbine的時候,
減少寫入到磁盤文件的數據數量,同樣是爲了減少對磁盤的讀寫頻率,有可能達到優化作業的目的。
參數:mapred.compress.map.output(default false)
減少中間結果讀寫進出磁盤的方法不止這些,還有就是壓縮。
也就是說map的中間,無論是spill的時候,還是最後merge產生的結果文件,都是可以壓縮的。
壓縮的好處在於,通過壓縮減少寫入讀出磁盤的數據量。
對中間結果非常大,磁盤速度成爲map執行瓶頸的job,尤其有用。
控制map中間結果是否使用壓縮的參數爲:mapred.compress.map.output(true/false)。
將這個參數設置爲true時,那麼map在寫中間結果時,就會將數據壓縮後再寫入磁盤,讀結果時也會採用先解壓後讀取數據。
這樣做的後果就是:寫入磁盤的中間結果數據量會變少,但是cpu會消耗一些用來壓縮和解壓。
所以這種方式通常適合job中間結果非常大,瓶頸不在cpu,而是在磁盤的讀寫的情況。
說的直白一些就是用cpu換IO。
根據觀察,通常大部分的作業cpu都不是瓶頸,除非運算邏輯異常複雜。所以對中間結果採用壓縮通常來說是有收益的。
參數:mapred.map.output.compression.codec( default org.apache.hadoop.io.compress.DefaultCodec)
當採用map中間結果壓縮的情況下,用戶還可以選擇壓縮時採用哪種壓縮格式進行壓縮,
現在hadoop支持的壓縮格式有:GzipCodec,LzoCodec,BZip2Codec,LzmaCodec等壓縮格式。
通常來說,想要達到比較平衡的cpu和磁盤壓縮比,LzoCodec比較適合。但也要取決於job的具體情況。
用戶若想要自行選擇中間結果的壓縮算法,
可以設置配置參數:mapred.map.output.compression.codec=org.apache.hadoop.io.compress.DefaultCodec或者其他用戶自行選擇的壓縮方式
轉載來源: