Hadoop:數據壓縮、Yarn、企業優化

一、Hadoop數據壓縮

1.1 概述

壓縮技術能夠有效減少底層存儲系統(HDFS)讀寫字節數。壓縮提供了網絡帶寬和磁盤空間的效率。在運行MR程序時,IO操作、網絡數據傳輸、ShuffleMerge要花大量的時間,尤其是數據規模很大和工作負載密集的情況下,因此,使用數據壓縮顯得非常重要。

鑑於磁盤IO和網絡帶寬是Hadoop的寶貴資源,數據壓縮對於節省資源、最小化磁盤IO和網絡傳輸資源非常有幫助。可以在任意MapReduce階段啓動壓縮。不過,儘管壓縮和解壓操作的CPU開銷不高,其性能的提升和資源的節省並非沒有代價。

1.2 壓縮策略和原則

壓縮是提供Hadoop運行效率的一種優化策略。通過對MapperReducer運行過程中的數據進行壓縮,以減少磁盤IO,提供MR程序運行速度。

注意: 採用壓縮技術減少了磁盤IO,但同時增加了CPU運算負擔。所以,壓縮特性運用得當能提高性能,但運用不當也可能降低性能。

壓縮基本原則:

  1. 運算密集的job,少用壓縮
  2. IO密集的job,多用壓縮

1.3 MR支持的壓縮編碼

壓縮格式 hadoop自帶? 算法 文件擴展名 是否可切分 換成壓縮格式後,原來的程序是否需要修改
DEFLATE 是,直接使用 DEFLATE .deflate 和文本處理一樣,不需要修改
Gzip 是,直接使用 DEFLATE .gz 和文本處理一樣,不需要修改
bzip2 是,直接使用 bzip2 .bz2 和文本處理一樣,不需要修改
LZO 否,需要安裝 LZO .lzo 和文本處理一樣,不需要修改
Snappy 否,需要安裝 Snappy .snappy 和文本處理一樣,不需要修改

爲了支持多種壓縮/解壓縮算法,Hadoop引入了編碼/解碼器,如下表所示:

壓縮格式 對應的編碼/解碼器
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.LzopCodec
Snappy org.apache.hadoop.io.compress.SnappyCodec

壓縮性能的比較:

壓縮算法 原始文件大小 壓縮文件大小 壓縮速度 解壓速度
gzip 8.3GB 1.8GB 2.9GB 58MB/s
bzip2 8.3GB 1.1GB 2.4MB/s 9.5MB/s
LZO 8.3GB 2.9GB 49.3MB/s 74.6MB/s

1.4 壓縮方式選擇

①Gzip壓縮

優點 :壓縮率比較高,而且壓縮/解壓速度也比較快; Hadoop本身支持,在應用中處理Gzip格式的文件就和直接處理文本一樣;大部分Linux系統都自帶Gzip命令,使用方便

缺點:不支持split

應用場景:當每個文件壓縮後130M以內的(一個塊大小以內的),都可以考慮用Gzip壓縮格式,例如將一天或者一個小時的日子壓縮成一個Gzip文件

②Bzip2壓縮

優點:支持Split,具有很高的壓縮率,比Gzip壓縮率都高; Hadoop本身自帶,使用方便

缺點:壓縮/解壓速度慢

應用場景:適合對速度要求不高,但需要較高的壓縮率的時候;或者輸出之後的數據比較大,處理之後的數據需要壓縮存檔減少磁盤空間並且以後數據用得比較少的情況;或者對單個很大的文本文件想壓縮減少存儲空間,同時又需要支持Split,而且兼容之前的應用程序的情況

③Lzo壓縮

優點:壓縮/解壓速度也比較快,合理的壓縮率;支持Split, 是Hadoop中最流行的壓縮格式;可以在Linux系統下安裝lzop命令,使用方便。

缺點:壓縮率比Gzip要低一些; Hadoop本身不支持,需要安裝;在應用中對Lzo格式的文件需要做一些特殊處理(爲了支持Split需要建索引,還需要指定InputFormatLzo格式)。

應用場景:一個很大的文本文件,壓縮之後還大於200M以上的可以考慮,而且單個文件越大,Lzo優點越越明顯。

④Snappy壓縮

優點:高速壓縮速度和合理的壓縮率

缺點:不支持Split;壓縮率比Gzip要低; Hadoop本身不支持, 需要安裝

應用場景:當MapReduce作業的Map輸出的數據比較大的時候,作爲MapReduce的中間數據的壓縮格式;或者作爲一個MapReduce作業的輸出和另外一個MapReduce作業的輸入

1.5 壓縮位置選擇

在這裏插入圖片描述

1.6 壓縮參數配置

要在Hadoop中啓用壓縮,可以配置如下參數:

參數 默認值 階段 建議
io.compression.codecs(在core-site.xml中配置) org.apache.hadoop.io.compress.DefaultCodec,
org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.BZip2Codec
輸入壓縮 Hadoop使用文件擴展名判斷是否支持某種編解碼器
mapreduce.map.output.compress(在mapred-site.xml中配置) false mapper輸出 這個參數設爲true啓用壓縮
mapreduce.map.output.compress.codec(在mapred-site.xml中配置) org.apache.hadoop.io.compress.DefaultCodec mapper輸出 這個參數設爲true啓用壓縮
mapreduce.output.fileoutputformat.compress(在mapred-site.xml中配置 false reducer輸出 這個參數設爲true啓用壓縮
mapreduce.output.fileoutputformat.compress.codec(在mapred-site.xml中配置) org.apache.hadoop.io.compress. DefaultCodec reducer輸出 使用標準工具或者編解碼器,如gzip和bzip2
mapreduce.output.fileoutputformat.compress.type(在mapred-site.xml中配置) RECORD reducer輸出 SequenceFile輸出使用的壓縮類型:NONE和BLOCK

1.7 壓縮實操案例

在驅動類Driver進行配置設置(具體參數見上):

public class WordCountDriver {

	public static void main(String[] args) throws Exception {

		Configuration configuration = new Configuration();

		// 開啓map端輸出壓縮
		configuration.setBoolean("mapreduce.map.output.compress", true);
		// 設置map端輸出壓縮方式
		configuration.setClass("mapreduce.map.output.compress.codec", BZip2Codec.class, 
			CompressionCodec.class);
			
		Job job = Job.getInstance(configuration);
		......
	}
}

二、Yarn資源調度

Yarn架構見:Hadoop概述

2.1 Yarn的工作機制

在這裏插入圖片描述

  1. MR程序提交到客戶端所在的節點
  2. YarnRunnerResourceManager申請一個ApplicationResourceManager將應用程序的資源路徑返回給YarnRunner,然後將運行所需資源提交到HDFS
  3. 程序提交完畢後,申請運行mrAppMaster
  4. ResourceManager將用戶的請求初始化成一個Task
  5. 其中一個NodeManager領取到Task任務,該NodeManager創建容器Container併產生MRAppmaster
  6. ContainerHDFS上拷貝資源到本地,MRAppmasterResourceManager申請運行MapTask資源
  7. RM將運行MapTask任務分配給另外兩個NodeManager,另兩個NodeManager分別領取任務並創建容器
  8. MR向兩個接收到任務的NodeManager發送程序啓動腳本,這兩個NodeManager分別啓動MapTaskMapTask對數據分區排序
  9. MrAppMaster等待所有MapTask運行完畢後,向RM申請容器,運行ReduceTask
  10. ReduceTaskMapTask獲取相應分區的數據
  11. 程序運行完畢後,MR會向RM申請註銷自己

2.2 資源調度器

目前,Hadoop作業調度器主要有三種:FIFOCapacity SchedulerFair SchedulerHadoop2.7.2默認的資源調度器是Capacity Scheduler

具體設置詳見:yarn-default.xml文件:

<property>
    <description>The class to use as the resource scheduler.</description>
    <name>yarn.resourcemanager.scheduler.class</name>
	<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
  1. 先進先出調度器(FIFO)
    在這裏插入圖片描述
  2. 容量調度器(Capacity Scheduler)
    在這裏插入圖片描述
  3. 公平調度器(Fair Scheduler)
    在這裏插入圖片描述

2.3 任務的推測執行

一個作業由若干個Map任務和Reduce任務構成。因硬件老化、軟件Bug等,某些任務可能運行非常慢。

思考:系統中有99%的Map任務都完成了,只有少數幾個Map老是進度很慢,完不成,怎麼辦?

推測執行機制: 發現拖後腿的任務,比如某個任務運行速度遠慢於任務平均速度。爲拖後腿任務啓動一個備份任務,同時運行。誰先運行完,則採用誰的結果。

執行推測任務的前提條件:

  1. 每個Task只能有一個備份任務
  2. 當前Job已完成的Task必須不小於5%
  3. 開啓推測執行參數設置。mapred-site.xml文件中默認是打開的
<property>
  	<name>mapreduce.map.speculative</name>
  	<value>true</value>
  	<description>If true, then multiple instances of some map tasks may be executed in parallel.</description>
</property>

<property>
  	<name>mapreduce.reduce.speculative</name>
  	<value>true</value>
  	<description>If true, then multiple instances of some reduce tasks may be executed in parallel.</description>
</property>

不能啓用推測執行機制情況:

  1. 任務間存在嚴重的負載傾斜
  2. 特殊任務,比如任務向數據庫中寫數據

三、企業優化

3.1 MapReduce 跑的慢的原因

①計算機性能

CPU、內存、磁盤健康、網絡

②I/O操作優化

  1. 數據傾斜
  2. MapReduce數設置不合理
  3. Map運行時間太長,導致Reduce等待過久
  4. 小文件過多
  5. 大量的不可分塊的超大文件
  6. Spil次數過多
  7. Merge次數過多等

3.2 MapReduce優化方法

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

①數據輸入

合併小文件:在執行MR任務前將小文件進行合併,大量的小文件會產生大量的Map任務,增大Map任務裝載次數,而任務的裝載比較耗時,從而導致MR運行較慢。

採用Combine TextInputFormat來作爲輸入,解決輸入端大量小文件場景

②Map階段

  1. 減少溢寫Spill次數:通過調整io.sort.mbsort.spill,percent參數值,增大觸發Spill的內存上限,減少Spill次數,從而減少磁盤IO
  2. 減少合併Merge次數:通過調整io.sort.factor參數,增大Merge的文件數目,減少Merge的次數,從而縮短MR的處理時間
  3. Map之後,不影響業務邏輯的前提下,先進行Combiner處理,減少IO

③Reduce階段

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

④IO傳輸

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

⑤數據傾斜問題

數據傾斜現象:

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

減少數據傾斜的方法:

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

⑥常用的調優參數

資源相關參數(配置在mapred-default.xml):

配置參數 參數說明
mapreduce.map.memory.mb 一個MapTask可使用的資源上限(單位:MB),默認爲1024。如果MapTask實際使用的資源量超過該值,則會被強制殺死
mapreduce.reduce.memory.mb 一個ReduceTask可使用的資源上限(單位:MB),默認爲1024。如果ReduceTask實際使用的資源量超過該值,則會被強制殺死
mapreduce.map.cpu.vcores 每個MapTask可使用的最多cpu core數目,默認值: 1
mapreduce.reduce.cpu.vcores 每個ReduceTask可使用的最多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

YARN配置(yarn-default.xml):

配置參數 配置參數
yarn.scheduler.minimum-allocation-mb 給應用程序Container分配的最小內存,默認值:1024
yarn.scheduler.maximum-allocation-mb 給應用程序Container分配的最大內存,默認值:8192
yarn.scheduler.maximum-allocation-mb 每個Container申請的最小CPU核數,默認值:1
yarn.scheduler.maximum-allocation-vcores 每個Container申請的最大CPU核數,默認值:32
yarn.nodemanager.resource.memory-mb 給Containers分配的最大物理內存,默認值:8192

Shuffle性能優化(mapred-default.xml):

配置參數 參數說明
mapreduce.task.io.sort.mb Shuffle的環形緩衝區大小,默認100m
mapreduce.map.sort.spill.percent 環形緩衝區溢出的閾值,默認80%

容錯相關參數(MapReduce性能優化):

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

3.3 HDFS小文件優化方法

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

  1. Hadoop Archive
    是一個高效地將小文件放入HDFS塊中的文件存檔工具,它能夠將多個小文件打包成-一個HAR文件,這樣就減少了NameNode的內存使用。
  2. Sequence File
    Sequence File由一系列的二進制key/value組成,如果key爲文件名,value爲文件內容,則可以將大批小文件合併成一個大文件。
  3. CombineFilelnputFormat
    CombineFileInputFormat是一種新的InputFormat, 用於將多個文件合併成一個單獨的Split,另外,它會考慮數據的存儲位置。
  4. 開啓JVM重用.
    對於大量小文件Job,可以開啓JVM重用會減少45%運行時間。

    JVM重用原理: 一個Map運行在一個JVM上,開啓重用的話,該MapJVM上運行完畢後,JVM繼續運行其他Map

    具體設置: mapreduce.job.jvm.numtasks值在10-20之間。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章