hadoop作業調優引數整理及原理

2022-08-22 01:15:11 字數 4432 閱讀 7252

標籤(空格分隔): hadoop

![image.png-128.1kb][1]
1當map task開始運算,並產生中間資料時,其產生的中間結果並非直接就簡單的寫入磁碟。這中間的過程比較複雜,並且利用到了記憶體buffer(後續會將hadoop 裡常用的記憶體作為buffer的各個使用點做陳述)來進行已經產生的部分結果的快取,並在記憶體buffer中進行一些預排序來優化整個map的效能。如上圖所示,每乙個map都會對應存在乙個記憶體buffer(mapoutputbuffer,即上圖的buffer in memory),map會將已經產生的部分結果先寫入到該buffer中,這個buffer預設是100mb大小,但是這個大小是可以根據job提交時的引數設定來調整的,線上目前設定為300m.

該引數即為:mapreduce.task.io.sort.mb。

當map的產生資料非常大時,並且把mapreduce.task.io.sort.mb調大,那麼map在整個計算過程中spill的次數就勢必會降低,map task對磁碟的操作就會變少,如果map tasks的瓶頸在磁碟上,這樣調整就會大大提高map的計算效能。

2.map在執行過程中,不停的向該buffer中寫入已有的計算結果,但是該buffer並不一定能將全部的map輸出快取下來,當map輸出超出一定閾值(比如100m),那麼map就必須將該buffer中的資料寫入到磁碟中去,這個過程在mapreduce中叫做spill。map並不是要等到將該buffer全部寫滿時才進行spill,因為如果全部寫滿了再去寫spill,勢必會造成map的計算部分等待buffer釋放空間的情況。所以,map其實是當buffer被寫滿到一定程度(比如80%)時,就開始進行spill。

這個閾值也是由乙個job的配置引數來控制,

即mapreduce.map.sort.spill.percent,預設為0.80或80%。這個引數同樣也是影響spill頻繁程度,進而影響map task執行週期對磁碟的讀寫頻率的。但非特殊情況下,通常不需要人為的調整。調整mapreduce.task.io.sort.mb對使用者來說更加方便。

3.當map task的計算部分全部完成後,如果map有輸出,就會生成乙個或者多個spill檔案,這些檔案就是map的輸出結果。map在正常退出之前(cleanup),需要將這些spill合併(merge)成乙個,所以map在結束之前還有乙個merge的過程。merge的過程中,有乙個引數可以調整這個過程的行為,該引數為:mapreduce.task.io.sort.factor。該引數預設為10。它表示當merge spill檔案時,最多能有多少並行的stream向merge檔案中寫入。比如如果map產生的資料非常的大,產生的spill檔案大於10,而mapreduce.task.io.sort.factor使用的是預設的10,那麼當map計算完成做merge時,就沒有辦法一次將所有的spill檔案merge成乙個,而是會分多次,每次最多10個stream。這也就是說,當map的中間結果非常大,調大mapreduce.task.io.sort.factor,有利於減少merge次數,進而減少map對磁碟的讀寫頻率,有可能達到優化作業的目的。

4.當job指定了combiner的時候,我們都知道map階段結束後會在map端根據combiner定義的函式將map結果進行合併。執行combiner函式的時機有可能會是merge完成之前,或者之後,這個時機可以由乙個引數控制,即mapreduce.map.combine.minspills(default 3),當job中設定了combiner,並且spill數大於等於3的時候,那麼combiner函式就會在merge產生結果檔案之前執行。通過這樣的方式,就可以在spill非常多需要merge,並且很多資料需要做conbine的時候,減少寫入到磁碟檔案的資料數量,同樣是為了減少對磁碟的讀寫頻率,有可能達到優化作業的目的。

5.減少中間結果讀寫進出磁碟的方法不止這些,還有就是壓縮。也就是說map的中間,無論是spill的時候,還是最後merge產生的結果檔案,都是可以壓縮的。壓縮的好處在於,通過壓縮減少寫入讀出磁碟的資料量。對中間結果非常大,磁碟速度成為map執行瓶頸的job,尤其有用。控制map中間結果是否使用壓縮的引數為:mapreduce.map.output.compress(true/false)。 將這個引數設定為true時,那麼map在寫中間結果時,就會將資料壓縮後再寫入磁碟,讀結果時也會採用先解壓後讀取資料。這樣做的後果就是:寫入磁碟的 中間結果資料量會變少,但是cpu會消耗一些用來壓縮和解壓。所以這種方式通常適合job中間結果非常大,瓶頸不在cpu,而是在磁碟的讀寫的情況。說的 直白一些就是用cpu換io。根據觀察,通常大部分的作業cpu都不是瓶頸,除非運算邏輯異常複雜。所以對中間結果採用壓縮通常來說是有收益的。以下是一 個wordcount中間結果採用壓縮和不採用壓縮產生的map中間結果本地磁碟讀寫的資料量對比:

map中間結果不壓縮:

map中間結果壓縮:

可以看出,同樣的job,同樣的資料,在採用壓縮的情況下,map中間結果能縮小將近10倍,如果map的瓶頸在磁碟,那麼job的效能提公升將會非常可觀。

當採用map中間結果壓縮的情況下,使用者還可以選擇壓縮時採用哪種壓縮格式進行壓縮,現在hadoop支援的壓縮格式有:gzipcodec,lzocodec,bzip2codec,lzmacodec等壓縮格式。通常來說,想要達到比較平衡的cpu和磁碟壓縮比,lzocodec比較適合。但也要取決於job的具體情況。使用者若想要自行選擇中間結果的壓縮演算法,可以設定配置引數:mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.defaultcodec或者其他使用者自行選擇的壓縮方式。當然壓縮選項需要hadoop 包本身支援,社群版需要支援壓縮的話需要使用者自行編譯。見

map side相關引數調優

選項型別

預設值描述

mapreduce.task.io.sort.mb

int100

快取map中間結果的buffer大小(mb)

io.sort.record.percent

float

0.5io.sort.mb中用來儲存map output記錄邊界的百分比,其他快取用來儲存資料

io.sort.spill.percent mapreduce.map.sort.spill.percent

float

0.8map開始做spill操作的閾值

io.sort.factor mapreduce.task.io.sort.factor

int10

map 端做merge操作時同時操作的stream數上限。

min.num.spill.for.combine

int3

combiner函式執行的最小spill數

mapred.compress.map.output

boolean

false

map中間結果是否採用壓縮

mapred.map.output.compression.codec

class name

org.apache.hadoop.io.

compress.defaultcodec

map中間結果的壓縮格式

壓縮格式可選

reduce side相關引數調優

選項型別

預設值描述

mapred.reduce.parallel.copies

int5

mapred.reduce.copy.backoff

int300

io.sort.factor

int10

map 端做merge操作時同時操作的stream數上限。

mapred.job.shuffle.input.buffer.percent

float

0.7用來快取shuffle資料的reduce task heap百分比

mapred.job.shuffle.merge.percent

float

0.66

快取的記憶體中多少百分比後開始做merge操作

mapred.job.reduce.input.buffer.percent

float

0.00

sort完成後reduce計算階段用來快取資料的百分比

**

Hadoop引數調優

1 要注意namenode和datanode的通訊,有乙個引數可以提公升他們通訊的順暢度 即20logn,n為集群大小 2 注意把hdfs的namenode 檔案edits 日誌檔案 和fsimage 映象檔案 配置在不同目錄下。可以提公升namenode效能 3 基準測試 測試hdfs的寫 讀效能...

hadoop 引數調優重點引數

yarn的引數調優,必調引數 28 yarn.nodemanager.resource.memory mb 預設為8192。每個節點可分配多少物理記憶體給yarn使用,考慮到節點上還 可能有其他程序需要申請記憶體,該值設定為物理記憶體總數 1.3比較合適,例如128g記憶體的節點可以分配100g 3...

hadoop的引數調優

1,在hdfs site.xml 中配置多目錄,提前配置好,以免以後要配置時,需要重啟集群。2,namenode 有乙個工作執行緒池,用來處理不同的datanode的併發心跳和客戶端訪問併發請求。配置dfs.namenode.handler.count 20 log2 cluster size 比如...