原文鏈接: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的文件描述符
上限,提高Hadoop RPC並發 關閉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參數調優
包括以下節點:
- 合理設置槽位數目
- 調整心跳配置
- 磁盤塊配置
- 設置RPC和線程數目
- 啟用批量任務調度
3.1 mapred-default.xml:
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/@taskid@.gc
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