MapReduce任務引數調優
http://blog.javachen.com/2014/06/24/tuning-in-mapreduce/
本文主要記錄Hadoop 2.x版本中MapReduce引數調優,不涉及Yarn的調優。
Hadoop的預設配置檔案(以cdh5.0.1為例):
說明:
在hadoop2中有些引數名稱過時了,例如原來的
mapred.reduce.tasks
改名為mapreduce.job.reduces
了,當然,這兩個引數你都可以使用,只是第一個引數過時了。
1. 作業系統調優
- 增大開啟檔案資料和網路連線上限,調整核心引數
net.core.somaxconn
,提高讀寫速度和網路頻寬使用率 - 適當調整
epoll的檔案描述符
關閉swap
。如果程序記憶體不足,系統會將記憶體中的部分資料暫時寫入磁碟,當需要時再將磁碟上的資料動態換置到記憶體中,這樣會降低程序執行效率- 增加
預讀快取區
大小。預讀可以減少磁碟尋道次數和I/O等待時間 - 設定
openfile
2. Hdfs引數調優
2.1 core-default.xml:
hadoop.tmp.dir
:
- 預設值: /tmp
- 說明: 儘量手動配置這個選項,否則的話都預設存在了裡系統的預設臨時檔案/tmp裡。並且手動配置的時候,如果伺服器是多磁碟的,每個磁碟都設定一個臨時檔案目錄,這樣便於mapreduce或者hdfs等使用的時候提高磁碟IO效率。
fs.trash.interval
- 預設值: 0
- 說明: 這個是開啟hdfs檔案刪除自動轉移到垃圾箱的選項,值為垃圾箱檔案清除時間。一般開啟這個會比較好,以防錯誤刪除重要檔案。單位是分鐘。
io.file.buffer.size
:
- 預設值:4096
- 說明:SequenceFiles在讀寫中可以使用的快取大小,可減少 I/O 次數。在大型的 Hadoop cluster,建議可設定為 65536 到 131072。
2.2 hdfs-default.xml:
dfs.blocksize
:
- 預設值:134217728
- 說明: 這個就是hdfs裡一個檔案塊的大小了,CDH5中預設128M。太大的話會有較少map同時計算,太小的話也浪費可用map個數資源,而且檔案太小namenode就浪費記憶體多。根據需要進行設定。
dfs.namenode.handler.count
:
- 預設值:10
- 說明:設定 namenode server threads 的數量,這些 threads 會用 RPC 跟其他的 datanodes 溝通。當 datanodes 數量太多時會發現很容易出現 RPC timeout,解決方法是提升網路速度或提高這個值,但要注意的是 thread 數量多也表示 namenode 消耗的記憶體也隨著增加
3. MapReduce引數調優
mapred.reduce.tasks
(mapreduce.job.reduces
):
- 預設值:1
- 說明:預設啟動的reduce數。通過該引數可以手動修改reduce的個數。
mapreduce.task.io.sort.factor
:
- 預設值:10
- 說明:Reduce Task中合併小檔案時,一次合併的檔案資料,每次合併的時候選擇最小的前10進行合併。
mapreduce.task.io.sort.mb
:
- 預設值:100
- 說明: Map Task緩衝區所佔記憶體大小。
mapred.child.java.opts
:
- 預設值:-Xmx200m
- 說明:jvm啟動的子執行緒可以使用的最大記憶體。建議值
-XX:-UseGCOverheadLimit -Xms512m -Xmx2048m -verbose:gc -Xloggc:/tmp/@[email protected]
mapreduce.jobtracker.handler.count
:
- 預設值:10
- 說明:JobTracker可以啟動的執行緒數,一般為tasktracker節點的4%。
mapreduce.reduce.shuffle.parallelcopies
:
- 預設值:5
- 說明:reuduce shuffle階段並行傳輸資料的數量。這裡改為10。叢集大可以增大。
mapreduce.tasktracker.http.threads
:
- 預設值:40
- 說明:map和reduce是通過http進行資料傳輸的,這個是設定傳輸的並行執行緒數。
mapreduce.map.output.compress
:
- 預設值:false
- 說明: map輸出是否進行壓縮,如果壓縮就會多耗cpu,但是減少傳輸時間,如果不壓縮,就需要較多的傳輸頻寬。配合 mapreduce.map.output.compress.codec使用,預設是 org.apache.hadoop.io.compress.DefaultCodec,可以根據需要設定資料壓縮方式。
mapreduce.reduce.shuffle.merge.percent
:
- 預設值: 0.66
- 說明:reduce歸併接收map的輸出資料可佔用的記憶體配置百分比。類似mapreduce.reduce.shuffle.input.buffer.percen屬性。
mapreduce.reduce.shuffle.memory.limit.percent
:
- 預設值: 0.25
- 說明:一個單一的shuffle的最大記憶體使用限制。
mapreduce.jobtracker.handler.count
:
- 預設值: 10
- 說明:可併發處理來自tasktracker的RPC請求數,預設值10。
mapred.job.reuse.jvm.num.tasks
(mapreduce.job.jvm.numtasks
):
- 預設值: 1
- 說明:一個jvm可連續啟動多個同類型任務,預設值1,若為-1表示不受限制。
mapreduce.tasktracker.tasks.reduce.maximum
:
- 預設值: 2
- 說明:一個tasktracker併發執行的reduce數,建議為cpu核數
4. 系統優化
4.1 避免排序
對於一些不需要排序的應用,比如hash join或者limit n,可以將排序變為可選環節,這樣可以帶來一些好處:
- 在Map Collect階段,不再需要同時比較partition和key,只需要比較partition,並可以使用更快的計數排序(O(n))代替快速排序(O(NlgN))
- 在Map Combine階段,不再需要進行歸併排序,只需要按照位元組合併資料塊即可。
- 去掉排序之後,Shuffle和Reduce可同時進行,這樣就消除了Reduce Task的屏障(所有資料拷貝完成之後才能執行reduce()函式)。
4.2 Shuffle階段內部優化
- Map端--用Netty代替Jetty
- Reduce端--批拷貝
- 將Shuffle階段從Reduce Task中獨立出來
5. 總結
在執行mapreduce任務中,經常調整的引數有:
mapred.reduce.tasks
:手動設定reduce個數mapreduce.map.output.compress
:map輸出結果是否壓縮mapreduce.map.output.compress.codec
mapreduce.output.fileoutputformat.compress
:job輸出結果是否壓縮mapreduce.output.fileoutputformat.compress.type
mapreduce.output.fileoutputformat.compress.codec