MapReduce優化----幾點根本設置

在編寫MapReduce應用程序時,除了最基本的Map模塊、Reduce模塊和驅動方法之外,用戶還可以通過一些技巧優化作業以提高其性能。對用戶來說,合理地在MapReduce作業中對程序進行優化,可以極大地提高作業的性能,減少作業執行時間。我們從以下幾個方法分析MapReduce作業的優化方法。

1    選擇Mapper的數量

Hadoop平臺在處理大量小文件時性能比較遜色,主要由於生成的每個分片都是一整個文件,Map操作時只會處理很少的輸入數據,但是會產生很多Map任務,每個Map任務的運行都包括產生、調度和結束時間,大量的Map任務會造成一定的性能損失。可以通過任務Java虛擬機(JVM)重用來解決這個問題,默認每JVM只運行一個任務,使用JVM重用後一個JVM可以順序執行多個任務,減少了啓動時間。控制JVM的屬性是mapred.job.reuse.jvm.num.tasks,它指定作業每個JVM運行的任務的最大數量,默認爲1。可以通過JonConf的setNumTasksToExecutePerJvm()方法設置,若設置爲-1則說明統一作業中共享一個JVM任務的數量不受限制。


如果輸入的文件過大,還可以通過將HDFS上的塊大小增大,比如增加到256M或512M,以減少Mapper數量,可以通過運行參數(-Ddfs.block.size = $[256*1024*1024])將塊大小增大到256M。

2    選擇Reducer的數量

在Hadoop中默認是運行一個Reducer,所有的Reduce任務都會放到單一的Reducer去執行,效率非常低下。爲了提高性能,可以適當增大Reducer的數量。

最優的Reducer數量取決於集羣中可用的Reducer任務槽的數目。Reducer任務槽的數目是集羣中節點個數與mapred.tasktracker.reduce.tasks.maximum(默認爲2)的乘積,也可以通過MapReduce的用戶界面獲得。

一個普遍的做法是將Reducer數量設置爲比Reducer任務槽數目稍微小一些,這會給Reducer任務留有餘地,同時將使得Reducer能夠在同一波中完成任務,並在Reducer階段充分使用集羣。


Reducer的數量由mapred.reduce.tasks屬性設置,通常在MapReduce作業的驅動方法中通過setNumReduceTasks(n)調用方法動態設置Reducer的數目爲n。

3    使用Combiner函數

Combiner過程是一個可選的優化過程,如果這個過程適合你的作業,Combiner實例會在每個運行Map任務的節點上運行,它會接收本節點上Mapper實例的輸出作爲輸入,然後Combiner的輸出會被髮送到Reducer,而不是發送Mapper的輸出。

Combiner是一個“迷你Reduce”過程,它是用Reducer接口來定義的,只對本節點生成的數據進行規約。爲了直觀理解Combiner的作用,使用WordCount程序進行說明。在該程序中Map任務會生成很多(“word”,1)對,如果同一分片中“Cat”出現了5次,則會生成5個(“Cat”,1)對被髮送至Reducer。通過使用Combiner,這5個key/value對會被規約爲一個(“Cat”,5)發送至Reducer。Combiner過程會針對輸入反覆運行,但不會影響最終結果。運行Combiner的意義在於使Map輸出更緊湊,從而大大減少了Shuffle過程所需的帶寬,並加速了作業的執行。

通過setCombinerClass(Class<? extends Reducer> theClass)方法使用Combiner過程,括號中指定了Combiner所使用的類,如果用戶的Reduce函數可交換並可組合(比如WordCount的Reduce函數),則可以直接在驅動方法中添加如下代碼:conf.setCombinerClass(Reduce.class);否則用戶必須編寫一個第三方類作爲作業的Combiner。

4    壓縮Map的輸出

在Map任務完成後對將要溢寫入磁盤的數據進行壓縮是一種很好的優化方法,它能夠使數據寫入磁盤的速度更快,節省磁盤空間,減少需要傳送到Reducer的數據量,以達到減少MapReduce作業執行時間的目的。Hadoop支持的壓縮格式及相關信息如表1所示。

                   表1  Hadoop支持的壓縮格式 
壓縮格式  工具 算法    文件擴展名 Hadoop壓縮編碼/解碼器 
DEFLATE 無 DEFLATE    .deflate Org.apache.hadoop.io.compress.DefaultCodec 
Gzip gzip DEFLATE    .gz         Org.apache.hadoop.io.compress.GzipCodec 
bzip2 bzip2 bzip2    .bz2         Org.apache.hadoop.io.compress.BZip2Codec 
LZO lzop LZO    .lzo         Com.hadoop.compression.lzo.LzopCodec

    在使用Map輸出壓縮時需要考慮壓縮格式的速度最優與空間最優的協調。通常來說,Gzip壓縮在空間/時間處理上相對平衡;bzip2壓縮比gzip更有效,但速度較慢;LZO壓縮[19]使用速度最優算法,但壓縮效率稍低。我們需要根據MapReduce作業以及輸入數據的不同進行選擇。 
    MapReduce應用程序的驅動方法中加入如下所示代碼便可以啓用gzip格式來壓縮Map的輸出結果。 
    conf.setCompressMapOutput(true); 
    conf.setMapOutputCompressorClass(GzipCodec.class);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章