Hadoop企業級優化總結

覺得有幫助的,請多多支持博主,點贊關注哦~

Hadoop企業級優化

一、MapReduce 跑的慢的原因

Mapreduce 程序效率的瓶頸在於兩點:

  1. 計算機性能
    1. CPU
    2. 內存
    3. 磁盤健康
    4. 網絡
  2. I/O 操作優化
    1. 數據傾斜
    2. map 和 reduce 數設置不合理
    3. map 運行時間太長,導致 reduce 等待過久
    4. 小文件過多
    5. 大量的不可分塊的超大文件
    6. spill 次數過多
    7. merge 次數過多等。

二、MapReduce 優化方法

MapReduce 優化方法主要從六個方面考慮:數據輸入、Map 階段、Reduce 階段、IO 傳輸、數據傾斜問題和常用的調優參數。

1、數據輸入

  1. 合併小文件:在執行 mr 任務前將小文件進行合併,大量的小文件會產生大量的map 任務,增大 map 任務裝載次數,而任務的裝載比較耗時,從而導致 mr 運行較慢。
  2. 採用 CombineTextInputFormat 來作爲輸入,解決輸入端大量小文件場景。

2、Map 階段

  1. 減少溢寫(spill)次數:通過調整 io.sort.mb 及 sort.spill.percent 參數值,增大觸發spill 的內存上限,減少 spill 次數,從而減少磁盤 IO。
  2. 減少合併(merge)次數:通過調整 io.sort.factor 參數,增大 merge 的文件數目,減少 merge 的次數,從而縮短 mr 處理時間。
  3. 在 map 之後,不影響業務邏輯前提下,先進行 combine 處理,減少 I/O

3、Reduce 階段

  1. 合理設置 map 和 reduce 數:兩個都不能設置太少,也不能設置太多。太少,會導 致 task 等待,延長處理時間;太多,會導致map、reduce 任務間競爭資源,造成處理超時 等錯誤。
  2. 設置 map、reduce 共存:調整 slowstart.completedmaps 參數,使 map 運行到一定程度後,reduce 也開始運行,減少 reduce 的等待時間。
  3. 規避使用 reduce:因爲 reduce 在用於連接數據集的時候將會產生大量的網絡消耗。
  4. 合理設置 reduce 端的 buffer:默認情況下,數據達到一個閾值的時候,buffer 中的數據就會寫入磁盤,然後 reduce 會從磁盤中獲得所有的數據。也就是說,buffer 和 reduce是沒有直接關聯的,中間多個一個寫磁盤->讀磁盤的過程,既然有這個弊端,那麼就可以通過參數來配置,使得 buffer 中的一部分數據可以直接輸送到 reduce,從而減少 IO 開銷:mapred.job.reduce.input.buffer.percent,默認爲 0.0。當值大於 0 的時候,會保留指定比例的內存讀 buffer 中的數據直接拿給 reduce 使用。這樣一來,設置 buffer 需要內存,讀取數據需要內存,reduce 計算也要內存,所以要根據作業的運行情況進行調整。

4、IO 傳輸

  1. 採用數據壓縮的方式,減少網絡 IO 的的時間。安裝 Snappy 和 LZO 壓縮編碼器。
  2. 使用 SequenceFile 二進制文件

5、數據傾斜問題

5.1、什麼是數據傾斜?

簡單來說數據傾斜就是數據的key 的分化嚴重不均,造成一部分數據很多,一部分數據很少的局面。

數據傾斜分爲兩種:

  1. 數據頻率傾斜:某一區域的數據量遠遠大於其他區域。
  2. 數據大小傾斜:部分記錄的大小遠遠大於平均值。

5.2、數據傾斜原因

  1. key分佈不均勻
  2. 業務數據本身的特性
  3. 建表時考慮不周
  4. 某些SQL語句本身就有數據傾斜

5.3、解決辦法

  • 方法 1:抽樣和範圍分區
    可以通過對原始數據進行抽樣得到的結果集來預設分區邊界值。
  • 方法 2:自定義分區partition
    基於輸出鍵的背景知識進行自定義分區。例如,如果 map 輸出鍵的單詞來源於一本書。且其中某幾個專業詞彙較多。那麼就可以自定義分區將這這些專業詞彙發送給固定的一部分reduce 實例。而將其他的都發送給剩餘的 reduce 實例。
  • 方法 3:Combine合併
    使用 Combine 可以大量地減小數據傾斜。在可能的情況下,combine 的目的就是聚合並精簡數據。
  • 方法 4:採用 Map Join,儘量避免 Reduce Join。
  • 方法 5:增加jvm內存
    通過硬件的手段來進行調優,增加jvm內存可以顯著的提高運行效率。

6、常用的調優參數

6.1、資源相關參數

6.1.1、以下參數是在用戶自己的 mr 應用程序中配置就可以生效(mapred-default.xml)
配置參數 參數說明
mapreduce.map.memory.mb 一個 Map Task 可使用的資源上限(單位:MB),默認爲 1024。如果 Map Task 實際使用的資源量超過該值,則會被強制殺死。
mapreduce.reduce.memory.mb 一個 Reduce Task 可使用的資源上限(單位:MB),默認爲 1024。如果 Reduce Task實際使用的資源量超過該值,則會被強制殺死。
mapreduce.map.cpu.vcores 每個 Map task 可使用的最多 cpu core 數目,默認值: 1
mapreduce.reduce.cpu.vcores 每個 Reduce task 可使用的最多 cpu core 數目,默認值: 1
mapreduce.reduce.shuffle.parallelcopies 每個 reduce 去 map 中拿數據的並行數。默認值是 5
mapreduce.reduce.shuffle.merge.percent buffer 中的數據達到多少比例開始寫入磁盤。默認值 0.66
mapreduce.reduce.shuffle.input.buffer.percent buffer 大小佔 reduce 可用內存的比例。默認值 0.7
mapreduce.reduce.input.buffer.percent 指定多少比例的內存用來存放 buffer 中的數據,默認值是 0.0
6.1.2、應該在 yarn 啓動之前就配置在服務器的配置文件中才能生效(yarn-default.xml)
配置參數 參數說明
yarn.scheduler.minimum-allocation-mb 1024 給應用程序 container 分配的最小內存
yarn.scheduler.maximum-allocation-mb 8192 給應用程序 container 分配的最大內存
yarn.scheduler.minimum-allocation-vcores 1 每個 container 申請的最小 CPU 核數
yarn.scheduler.maximum-allocation-vcores 32 每個 container 申請的最大 CPU 核數
yarn.nodemanager.resource.memory-mb 8192 給 containers 分配的最大物理內存
6.1.3、shuffle 性能優化的關鍵參數,應在 yarn 啓動之前就配置好(mapred-default.xml)
配置參數 參數說明
mapreduce.task.io.sort.mb 100 shuffle 的環形緩衝區大小,默認 100m
mapreduce.map.sort.spill.percent 0.8 環形緩衝區溢出的閾值,默認 80%

6.2、容錯相關參數(mapreduce 性能優化)

配置參數 參數說明
mapreduce.map.maxattempts 每個 Map Task 最大重試次數,一旦重試參數超過該值,則認爲 Map Task 運行失敗,默認值:4。
mapreduce.reduce.maxattempts 每個 Reduce Task 最大重試次數,一旦重試參數超過該值,則認爲 Map Task 運行失敗,默認值:4。
mapreduce.task.timeout Task 超時時間,經常需要設置的一個參數,該參數表達的意思爲:如果一個 task 在一定時間內沒有任何進入,即不會讀取新的數據,也沒有輸出數據,則認爲該 task處於 block 狀態,可能是卡住了,也許永遠會卡主,爲了防止因爲用戶程序永遠 block 住不退出,則強制設置了一個該超時時間(單位毫秒),默認是 600000。如果你的程序對每條輸入數據的處理時間過長(比如會訪問數據庫,通過網絡拉取數據等),建議將該參數調大,該 參 數 過 小 常 出 現 的 錯 誤 提 示 是“AttemptID:attempt_14267829456721_123456_m_000224_0 Timed out after 300 secsContainer killed by theApplicationMaster.”。

三、HDFS 小文件優化方法

Hadoop設計就是適合大文件,不適合小文件,應該儘量避免大量小文件,不生成小文件。
如果有很多小文件的話,可以使用CombineTextInputFormat進行切片,將大量的小文件打包成一個文件。
最終的大文件會根據maxInputSplitSize、minInputSplitSize的不同而不同,假如沒有設定min和max,則指定的所有小文件都會被打包到同一個文件中。
同時,開啓uber模式,可以對這些小文件對應的小任務進行優化,使多個小文件公用一個JVM,節省一些資源。
還可以進行archive文件歸檔,Sequence File或Map File。
總之,處理就是要將小文件進行合併,讓他們不小,或者佔用資源少。當然最好不要生成小文件。

1、HDFS 小文件弊端

HDFS 上每個文件都要在 namenode 上建立一個索引,這個索引的大小約爲 150byte,這樣當小文件比較多的時候,就會產生很多的索引文件,一方面會大量佔用 namenode 的內存空間,另一方面就是索引文件過大是的索引速度變慢。

2、解決方案

2.1、Hadoop Archive

Hadoop Archive是一個高效地將小文件放入 HDFS 塊中的文件存檔工具,它能夠將多個小文件打包成
一個 HAR 文件,這樣就減少了 namenode 的內存使用。

2.2、Sequence file

sequence file 由一系列的二進制 key/value 組成,如果 key 爲文件名,value 爲文件內容,則可以將大批小文件合併成一個大文件。

2.3、CombineFileInputFormat

CombineFileInputFormat 是一種新的 inputformat,用於將多個文件合併成一個單獨的split,另外,它會考慮數據的存儲位置。

2.4開啓 JVM 重用

對於大量小文件 Job,可以開啓 JVM 重用會減少 45%運行時間。
JVM 重用理解:一個 map 運行一個 jvm,重用的話,在一個 map 在 jvm 上運行完畢後,jvm 繼續運行其他 map。
具體設置:mapreduce.job.jvm.numtasks 值在 10-20 之間。

覺得有幫助的,請多多支持博主,點贊關注哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章