Fenriswolf 程式筆記

奮利斯狼的地盤,小綿羊勿入

Hadoop 參數設定 – mapred-site.xml

本篇是介紹 mapred-site.xml 的相關設定及說明

  • JobTracker
    • mapred.job.tracker
      預設值 : local
      說明 : 設定 jobtracker 的 hostname 及 port。預設是 local,表示所有的 job 會用 local job runner 來執行,而且只有一個 mapper 及一個 reducer。在這個設定下,如果要啟動 jobtracker service 反而會出錯。一般常看到的設定是 localhost:9001。不過跟 core-site.xml 裡的 fs.default.name 一樣,會建議用 hostname 來設定。
    •  

    • mapred.job.tracker.http.address
      預設值 : 0.0.0.0:50030
      說明 : jobtracker Web UI 用的 port。除非是為了 security 的考量才會需要改 binding 的 IP/Port,不然不需要改這個值。
    •  

    • mapred.system.dir
      預設值 : ${hadoop.tmp.dir}/mapred/system
      說明 : 在 HDFS 上的資料夾,放所有 M/R jobs 相關的控制資訊,一個正在執行的 M/R job 會在這個目錄裡建立一個子目錄。
    •  

    • mapred.temp.dir
      預設值 : ${hadoop.tmp.dir}/mapred/temp
      說明 : 在 HDFS 上一個共享的資料夾,放所有 M/R 相關的暫存資料
    •  

    • mapred.local.dir
      預設值 : ${hadoop.tmp.dir}/mapred/local
      說明 : 在 tasktracer 上存放暫存資料的目錄。跟 hdfs-site.xml 裡的 dfs.data.dir 設定一樣,指定多個目錄(volumes) 可用 “," 以加快存取速度。如果有使用 distributed cache 的話,檔案也會放在這個位置。
    •  

    • mapred.hosts
      預設值 : N/A
      說明 : 跟 hdfs-site.xml 裡的 dfs.hosts 一樣。此值是指定一個檔案位置,名字可自取,例如 : /etc/hadoop/conf/mapred-hosts,並列出所有可以連結 jobtracer 的機器清單。不在清單上的機器是沒有權限的。
    •  

    • mapred.hosts.exclude
      預設值 : N/A
      說明 : 跟 hdfs-site.xml 裡的 dfs.hosts.exclude 一樣。當需要汰換或移除多台機器的 tasktracer 時會用到。一般來說,為了 data locality 的考量,一台機器上會同時起 datanode 和 tasktracer。在汰換時也需要同時停掉這些 services。所以方便起見,dfs.hosts 和 mapred.hosts 會共用同一個檔案,dfs.hosts.exclude 和 mapred.hosts.exclude 也會共用同一個檔案。
    •  

    • mapred.jobtracker.restart.recover
      預設值 : false
      說明 : 設成 true 可以讓 jobtracker 重啟的時候自動恢復之前執行到一半的 M/R jobs,可是這個功能在 Cloudera CDH3 中並無法正常運作。可以參考 Cloudera 的 Known issues JobTracker recovery does not work after a restart
    •  

    • mapred.jobtracker.completeuserjobs.maximum
      預設值 : 100
      說明 : 在 jobtracker 記憶體中保存已完成的 job 個數,並讓使用者方便在 jobtracker UI 上查詢。如果超過 100 個 jobs ,就會寫入 disk 並放到 job history 中。這個設定是依每個使用者而設的,所以使用者多而且 job 數也多的情況會造成 jobtracker 使用太多的記憶體,可能會導致常做 full GC 或 OOME。建議可以只設 10。
    •  

    • mapred.jobtracker.taskScheduler
      預設值 : org.apache.hadoop.mapred.JobQueueTaskScheduler
      說明 : 做 M/R job 排程所使用的 scheduler,這部分會在另一篇文章中討論。
    •  

    • mapred.job.tracker.handler.count
      預設值 : 10
      說明 : 設定 jobtracker server threads 的數量,這些 threads 會用 RPC 跟其他的 tasktrackers 溝通。跟 hdfs-site.xml 裡的 dfs.namenode.handler.count 一樣,設的值越高表示 jobtracker 吃的記憶體也隨著增加。在官方文件裡的建議值是全部 tasktracer 數量的 4%。以個人經驗來說,如果 jobtracker 機器配備跟 namenode 同級,那 dfs.namenode.handler.count 及 mapred.job.tracker.handler.count 的設定可用一樣,100 個 nodes 配 100 個 threads。
    •  

    • job.end.notification.url
      預設值 : N/A
      說明 : 當一個 job 執行完畢,不管成功或失敗,jobtracker 會根據這個設定送出一個 http request 通知指定的 url。例如: http://localhost:8080/jobstatus.jsp?jobId=$jobId&jobStatus=$jobStatus。$jobId 和 $jobStatus 是內建的參數,jobtracker 會把這兩個值轉成實際執行的 job id 和 status。jobstatus.jsp 是自己實作的程式,裡面可以依據傳來的 job id 再回 jobtracker 查詢更多的訊息並導入到不同的 logging system。對於做 M/R job monitoring 非常好用,不需要一直 polling jobtracker 來得知現有 job 執行的狀態。
    •  

    • mapreduce.jobtracker.keytab.file
      預設值 : N/A
      說明 : 當 core-site.xml 裡的 hadoop.security.authentication 參數設為 “kerberos" 時就要指定 keytab 的位置。例如 : /etc/hadoop/conf/mapred.keytab
    •  

    • mapreduce.jobtracker.kerberos.principal
      預設值 : N/A
      說明 : 指定 kerberos principal 名稱,這在產生 keytab 檔案時會指定,一般常用的命名規則是 mapred/_HOST@KERBEROS-REALM.COM

     

  • TaskTracker
    • mapred.task.tracker.http.address
      預設值 : 0.0.0.0:50060
      說明 : tasktracker Web UI 用的 port。除非是為了 security 的考量才會需要改 binding 的 IP/Port,不然不需要改這個值。
    •  

    • mapred.child.java.opts
      預設值 : -Xmx200m
      說明 : tasktracer 會依每個要執行的 java task 啟動獨立的 child process,這個值可以設定每個 process 的 JVM 參數。例如: 要增加 heap size 及 gc log 的話可以改成

      	-Xmx1024m -verbose:gc -Xloggc:/var/log/hadoop/task-gc-@taskid@.log 
      	

      @taskid@ 是內建的參數,tasktracer 會把這個值轉成實際執行的 task id。
      各 app 也可在 submit job 之前,依據自己的需求調整這個設定。

    •  

    • mapred.child.ulimit
      預設值 : N/A(kb)
      說明 : 設定最大的虛擬記憶體使用量。跟 mapred.child.java.opts 不太一樣,mapred.child.java.opts 所設定的 -Xmx 只是 tasktracer 所啟動的 java child process 所用的 heap size,但 mapred.child.ulimit 所設定的包括 child process 本身及其所啟動的其他 sub process 的記憶體總合。建議這個值的大小應為 mapred.child.java.opts 指定的 2~3 倍。例如: 在 mapred.child.java.opts 設定 1G,則 mapred.child.ulimit 設為 3G。
      不然,在 task 執行時期可能會出現以下的錯誤訊息,雖然看起來是 warning,但已經表示 JVM 沒啟動成功。

      2012-07-29 10:57:28,199 INFO org.apache.hadoop.mapred.JvmManager: JVM : jvm_201207291054_0001_m_1994801458 exited with exit code 134. Number of tasks it ran: 0
      2012-07-29 10:57:28,200 WARN org.apache.hadoop.mapred.TaskRunner: attempt_201207291054_0001_m_000005_3 : Child Error
      java.io.IOException: Task process exit with nonzero status of 134.
              at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:227)
          

      因為這個參數比較敏感,應該要由系統管理者指定適合的值並設為 final,也就是不允許使用者自己修改。讓這個值為空,並直接修改系統 limits.conf 也是一個解決方式。

    •  

    • tasktracker.http.threads
      預設值 : 40
      說明 : tasktracer http server 所使用的 thread 數量,主要是讓 reducer 在 shuffle 階段取得 mapper 的中間產出。這是一個全域的變數,並不能依據各自的需求做修改。一般來說,在小的 cluster 裡保持原來設定即可。越大的值所使用的記憶體也會相對增加,但效果不見得顯著。在 Apache 官網上的測試報告,2000 個 nodes 也只設定到 50 而已。
    •  

    • mapred.tasktracker.map.tasks.maximum
      預設值 : 2
      說明 : tasktracer 可同時執行的 mapper 數量。一般來說,設定的值會依 CPU core 數而定。例如: 一台機器有 8 core CPU,一個 core 跑兩個 processes,可使用的數量是 8×2-2=14 (要減掉 datanode 及 tasktracer 使用的 slot 數),則 mapper 及 reducer 數量可設為 7。要注意的是,設的值越高不見得是好事,除了 CPU utilization 之外,記憶體使用量也是考慮因素之一。假設 datanode 使用 1G,tasktracker 也用 1G,mapper 及 reducer 都用預設值 200 MB。那總記憶體使用量是 1000+1000+14×200=4800(MB)。因此要看機器的規格來決定。
    •  

    • mapred.tasktracker.reduce.tasks.maximum
      預設值 : 2
      說明 : tasktracer 可同時執行的 reducer 數量。基本的配置和 mapred.tasktracker.map.tasks.maximum 一樣。有個可以考慮的點是,在執行 M/R job 裡有許多是只有 mapper 不需要 reducer 的,例如 HBase import/export。所以可以視需求加大 mapper 的個數並減少 reducer 的個數。
    •  

    • mapred.map.max.attempts
      預設值 : 4
      說明 : 當 mapper 失敗時 tasktracer 重試此 mapper 的次數。在一個很大的 cluster 裡,mapper 或 reducer 失敗不一定是程式邏輯出錯,有可能是網路出問題造成短時間的 timeout。常遇到的狀況是重新執行一次就好了。一般來說不需要特別改這個值。
    •  

    • mapred.reduce.max.attempts
      預設值 : 4
      說明 : 同上,差別只在設的是 reducer 的重試次數
    •  

    • mapred.max.map.failures.percent
      預設值 : 0
      說明 : 設 0 表示不能有任何一個 mapper 失敗,不然整個 job 會失敗。如果在 M/R jobs 裡不需要這麼高的容錯率,允許 100 個 mapper 裡失敗 5 個也算 job 執行成功,那可以把這個值設為 5/100 = 5%。
    •  

    • mapred.max.reduce.failures.percent
      預設值 : 0
      說明 : 同上,差別只在設的是 reducer 的失敗百分比。
    •  

    • mapred.map.tasks.speculative.execution
      預設值 : true
      說明 : 決定是否開啟 mapper 的推測性執行(Speculative Execution)。一般來說,假設一個 job 有 100 個 mappers,其中 99 個很快就完成,剩最後一個非常的慢,系統還是會等到他完成整個 job 才算結束。會慢的原因可能是硬體有問題,網路不穩或程式寫的不夠好。但這不是 Hadoop 本身要處理的問題。Hadoop 能做的是,在另一個 tasktracer 上執行同樣的 mapper,先執行完的 mapper output 會傳給 reducer,比較慢而沒有執行完的 mapper 會自動被所屬的 tasktracer 殺掉。要注意的是,被殺掉的 task 數也會被計算在 mapred.reduce.max.attempts 裡。
      推測性執行並不是為了做平行運算用的,原本的 mapper 及推測性 mapper (speculative mapper) 也不會同時被執行。判斷是否會啟動另一個 speculative mapper 的理由是當原本的 mapper 執行超過某個特定時間(至少一分鐘),而且原本的 mapper 長時間沒有回報任何新的進度才會被執行。這也不是讓程式可靠度提升的正確方式,如果發現原本的程式邏輯有錯造成某些 mappers 執行較慢,應該以改程式為主。另外,如果開發者沒有想到推測性執行的可能性,可能同樣的 mapper 讀寫同一份資源造成 race condition。
      在 production 的環境會有大量的 M/R job 在執行,建議的做法是設為 false,不要讓系統消耗過多的資源去執行多餘的 mapper。由 client 來決定是否使用推測性執行會比較好。
    •  

    • mapred.reduce.tasks.speculative.execution
      預設值 : true
      說明 : 同上,差別只在設的是 reducer 的推測性執行。
    •  

    • mapred.reduce.slowstart.completed.maps
      預設值 : 0.05
      說明 : 當一個 job 裡的 mappers 數完成 5% 的時候開始執行 reducers。例如: 有 100 個 mappers 的情況,只要做完 5 個 mappers 就開始執行 reducers。
      下面討論兩個極端的狀況

      • 0: 表示 reducers 會立即執行。一般來說不會這樣設定,reducers 還是會等待 mapper 執行完。
      • 1: 會等到所有的 mappers 執行完才開始執行 reducers。這很容易因為某個 mappers 執行較慢而拖慢整個 job 的執行時間。

      client app 也可依據各自的需求修改這個參數。建議可設為 0.75,也就是 3/4 的 mappers 執行完後就執行 reducers。

    •  

    • mapred.compress.map.output
      預設值 : false
      說明 : 決定 mapper 的 output 是否要壓縮。一般來說,效能的瓶頸大部分是在 IO,而不是 CPU。所以大型的 cluster 來說最好設為 true,可以減少 mapper 的資料寫入 disk 的時間,節省暫存檔的空間,減少網路傳輸量,及把資料轉給 reducer 的時間。
    •  

    • mapred.map.output.compression.codec
      預設值 : org.apache.hadoop.io.compress.DefaultCodec
      說明 : 如果 mapred.compress.map.output 設為 true,則會用這個 codec 來執行壓縮。一般常見的壓縮格式

      • deflate: org.apache.hadoop.io.compress.DefaultCodec,已內建
      • gzip: org.apache.hadoop.io.compress.GzipCodec,已內建
      • bzip2: org.apache.hadoop.io.compress.BZip2Codec,已內建
      • lzo: com.hadoop.compression.lzo.LzoCodec,因為 lzo 是 GPL license,Apache 或 Cloudera 的版本沒有內建 ,需要自行裝 lzo package
      • snappy: org.apache.hadoop.io.compress.SnappyCodec,Cloudera 的版本已經有內建這個 codec
    •  

    • io.sort.factor
      預設值 : 10
      說明 : 當 mappers 計算完成如果有產出,就會先寫入一段 memory buffer(預設是 100 MB), buffer 達到 80% (定義在 io.sort.spill.percent 裡) 之後就會寫入 disk,並產生一個 spill file。當 mapper 寫出的資料量大就有可能產生多個 spill files。在執行完成交給 reducer 之前會先進入合併及排序的階段,多個 spill files 會合併為單一且排序過的檔案。這個值就是設定一次合併的檔案數。例如: 有 50 個 mapper spill files,預設值是 10 的情況下,就會有 5 次合併的動作並產生 5 個中介檔,然後再多一次合併動作把 5 個中介檔合併為一個。加大這個值可以有效的減少合併的次數及產生的中介檔案,不過所需的記憶體也相對變大。以 Cloudera 的建議可以在 production 環境改成 25 或 32。
    •  

    • io.sort.mb
      預設值 : 100(mb)
      說明 : 這是在 io.sort.factor 裡說明的 memory buffer,越大的值也表示所產生的 spill files 會越少。但相對的使用的記憶體會增加,大檔案做合併及排序也不見得比較快。還有一個地方要注意,假設 mapred.child.java.opts 裡定義的 heap size 為 1024 MB,io.sort.mb 是 100 MB,則 client 的 mapper 就只剩 924 MB 可以用。建議可以設到 320。使用者也可以依需求在 submit jobs 之前自行調整。
    •  

    • mapreduce.tasktracker.keytab.file
      預設值 : N/A
      說明 : 當 core-site.xml 裡的 hadoop.security.authentication 參數設為 “kerberos" 時就要指定 keytab 的位置。例如 : /etc/hadoop/conf/mapred.keytab
    •  

    • mapreduce.tasktracker.kerberos.principal
      預設值 : N/A
      說明 : 指定 kerberos principal 名稱,這在產生 keytab 檔案時會指定,一般常用的命名規則是 mapred/_HOST@KERBEROS-REALM.COM

     

 
 
執行環境
CentOS 6.2
JDK 1.6.0_31
Cloudera CDH3U3

參考資料
mapred-default.html

廣告

2012/08/06 - Posted by | Hadoop | , ,

仍無迴響。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: