Hadoop性能調優、YARN的內存和CPU配置

轉自: https://blog.csdn.net/tototuzuoquan/article/details/80671128html

 

轉: 
https://blog.csdn.net/dehu_zhou/article/details/52808752 
https://blog.csdn.net/dxl342/article/details/52840455java

Hadoop爲用戶做業提供了多種可配置的參數,以容許用戶根據做業特色調整這些參數值使做業運行效率達到最優。node

一 應用程序編寫規範

1.設置Combiner

對於一大批MapReduce程序,若是能夠設置一個Combiner,那麼對於提升做業性能是十分有幫助的。Combiner可減小Map Task中間輸出的結果,從而減小各個Reduce Task的遠程拷貝數據量,最終表現爲Map Task和Reduce Task執行時間縮短。python

2. 選擇合理的Writable類型

在MapReduce模型中,Map Task和Reduce Task的輸入和輸出類型均爲Writable。Hadoop自己已經提供了不少Writable實現,包括IntWritable、FloatWritable。爲應用程序處理的數據選擇合適的Writable類型可大大提高性能。好比處理整數類型數據時,直接採用IntWritable比先以Text類型讀入在轉換爲整數類型要高效。若是輸出整數的大部分可用一個或兩個字節保存,那麼直接採用VIntWritable或者VLongWritable,它們採用了變長整型的編碼方式,能夠大大減小輸出數據量。算法

二 做業級別參數調優

1.規劃合理的任務數目

在Hadoop中,每一個Map Task處理一個Input Split。Input Split的劃分方式是由用戶自定義的InputFormat決定的,默認狀況下,有如下三個參數決定。 
mapred.min.split.size :Input Split的最小值 默認值1 
mapred.max.split.szie: Input Split的最大值 
dfs.block.size:HDFS 中一個block大小 默認值64MB 
golsize:它是用戶指望的Input Split數目=totalSize/numSplits ,其中totalSize爲文件的總大小;numSplits爲用戶設定的Map Task個數,默認狀況下是1. 
splitSize = max{minSize,min{goalSize,blockSize}} 若是想讓InputSize尺寸大於block尺寸,直接增大配置參數mpared.min.split.size便可。緩存

2.增長輸入文件的副本數

若是一個做業並行執行的任務數目很是多,那麼這些任務共同的輸入文件可能成爲瓶頸。爲防止多個任務並行讀取一個文件內容形成瓶頸,用戶可根據須要增長輸入文件的副本數目。網絡

3.啓動推測執行機制

推測執行是Hadoop對「拖後腿」的任務的一種優化機制,當一個做業的某些任務運行速度明顯慢於同做業的其餘任務時,Hadoop會在另外一個節點上爲「慢任務」啓動一個備份任務,這樣兩個任務同時處理一份數據,而Hadoop最終會將優先完成的那個任務的結果做爲最終結果,並將另外一個任務殺掉。多線程

4.設置失敗容忍度

Hadoop運行設置任務級別和做業級別的失敗容忍度。做業級別的失敗容忍度是指Hadoop容許每一個做業有必定比例的任務運行失敗,這部分任務對應的輸入數據將被忽略; 
任務級別的失敗容忍度是指Hadoop容許任務失敗後再在另外節點上嘗試運行,若是一個任務通過若干次嘗試運行後仍然運行失敗,那麼Hadoop纔會最終認爲該任務運行失敗。 
用戶應該根據應用程序的特色設置合理的失敗容忍度,以儘快讓做業運行完成和避免不必的資源浪費。架構

5.適當打開JVM重用功能

爲了實現任務隔離,Hadoop將每一個任務放到一個單獨的JVM中執行,而對於執行時間較短的任務,JVM啓動和關閉的時間將佔用很大比例時間,爲此,用戶能夠啓用JVM重用功能,這樣一個JVM可連續啓動多個同類型的任務。併發

6.設置任務超時時間

若是一個任務在必定的時間內未彙報進度,則TaskTracker會主動將其殺死,從而在另外一個節點上從新啓動執行。用戶可根據實際須要配置任務超時時間。

7.合理使用DistributedCache

通常狀況下,獲得外部文件有兩種方法:一種是外部文件與應用程序jar包一塊兒放到客戶端,當提交做業時由客戶端上傳到HDFS的一個目錄下,而後經過Distributed Cache分發到各個節點上;另外一種方法是事先將外部文件直接放到HDFS上,從效率上講,第二種方法更高效。第二種方法不只節省了客戶端上傳文件的時間,還隱含着告訴DistributedCache:」請將文件下載到各個節點的pubic級別共享目錄中」,這樣,後續全部的做業可重用已經下載好的文件,沒必要重複下載。

8.跳過壞記錄

Hadoop爲用戶提供了跳過壞記錄的功能,當一條或幾條壞數據記錄致使任務運行失敗時,Hadoop可自動識別並跳過這些壞記錄。

9.提升做業優先級

全部Hadoop做業調度器進行任務調度時均會考慮做業優先級這一因素。做業的優先級越高,它可以獲取的資源(slot數目)也越多。Hadoop提供了5種做業優先級,分別爲VERY_HIGH、 HIGH、 NORMAL、 LOW、 VERY_LOW。 
注:在生產環境中,管理員已經按照做業重要程度對做業進行了分級,不一樣重要程度的做業容許配置的優先級不一樣,用戶能夠擅自進行調整。

10.合理控制Reduce Task的啓動時機

若是Reduce Task啓動過早,則可能因爲Reduce Task長時間佔用Reduce slot資源形成」slot Hoarding」現象,從而下降資源利用率;反之,若是Reduce Task啓動過晚,則會致使Reduce Task獲取資源延遲,增長了做業的運行時間。

三 任務級別參數調優

hadoop任務級別參數調優分兩個方面: Map Task和Reduce Task。

1.Map Task調優

map運行階段分爲:Read、Map、Collect、Spill、Merge五個階段。
map 任務執行會產生中間數據,但這些中間結果並無直接IO到磁盤上,而是先存儲在緩存(buffer)中,並在緩存中進行一些預排序來優化整個map的性能,存儲map中間數據的緩存默認大小爲100M,由io.sort.mb 參數指定。這個大小能夠根據須要調整。當map任務產生了很是大的中間數據時能夠適當調大該參數,使緩存能容納更多的map中間數據,而不至於大頻率的IO磁盤,當系統性能的瓶頸在磁盤IO的速度上,能夠適當的調大此參數來減小頻繁的IO帶來的性能障礙。
因爲map任務運行時中間結果首先存儲在緩存中,默認當緩存的使用量達到80%(或0.8)的時候就開始寫入磁盤,這個過程叫作spill(也叫溢出),進行spill的緩存大小能夠經過io.sort.spill.percent 參數調整,這個參數能夠影響spill的頻率。進而能夠影響IO的頻率。
當map任務計算成功完成以後,若是map任務有輸出,則會產生多個spill。接下來map必須將些spill進行合併,這個過程叫作merge, merge過程是並行處理spill的,每次並行多少個spill是由參數io.sort.factor指定的默認爲10個。可是當spill的數量很是大的時候,merge一次並行運行的spill仍然爲10個,這樣仍然會頻繁的IO處理,所以適當的調大每次並行處理的spill數有利於減小merge數所以能夠影響map的性能。
當map輸出中間結果的時候也能夠配置壓縮。
  • 1
  • 2
  • 3
  • 4
  • 5

這裏寫圖片描述

2. Reduce Task調優

reduce 運行階段分爲shuflle(copy) merge sort   reduce write五個階段。
shuffle 階段爲reduce 全面拷貝map任務成功結束以後產生的中間結果,若是上面map任務採用了壓縮的方式,那麼reduce 將map任務中間結果拷貝過來後首先進行解壓縮,這一切是在reduce的緩存中作的,固然也會佔用一部分cpu。爲了優化reduce的執行時間,reduce也不是等到全部的map數據都拷貝過來的時候纔開始運行reduce任務,而是當job執行完第一個map任務時開始運行的。reduce 在shuffle階段 其實是從不一樣的而且已經完成的map上去下載屬於本身的數據,因爲map任務數不少,全部這個copy過程是並行的,既同時有許多個reduce取拷貝map,這個並行的線程是經過mapred.reduce.parallel.copies 參數指定,默認爲5個,也就是說不管map的任務數是多少個,默認狀況下一次只能有5個reduce的線程去拷貝map任務的執行結果。因此當map任務數不少的狀況下能夠適當的調整該參數,這樣可讓reduce快速的得到運行數據來完成任務。
reduce線程在下載map數據的時候也可能由於各類各樣的緣由(網絡緣由、系統緣由等),存儲該map數據所在的datannode 發生了故障,這種狀況下reduce任務將得不到該datanode上的數據了,同時該 download thread 會嘗試從別的datanode下載,能夠經過mapred.reduce.copy.backoff (默認爲30秒)來調整下載線程的下載時間,若是網絡很差的集羣能夠經過增長該參數的值來增長下載時間,以避免由於下載時間過長reduce將該線程判斷爲下載失敗。
reduce 下載線程在map結果下載到本地時,因爲是多線程並行下載,因此也須要對下載回來的數據進行merge,因此map階段設置的io.sort.factor 也一樣會影響這個reduce的。
同map同樣 該緩衝區大小也不是等到徹底被佔滿的時候才寫入磁盤而是默認當完成0.66的時候就開始寫磁盤操做,該參數是經過mapred.job.shuffle.merge.percent 指定的。
當reduce 開始進行計算的時候經過mapred.job.reduce.input.buffer.percent 來指定須要多少的內存百分比來做爲reduce讀已經sort好的數據的buffer百分比,該值默認爲0。Hadoop假設用戶的reduce()函數須要全部的JVM內存,所以執行reduce()函數前要釋放全部內存。若是設置了該值,可將部分文件保存在內存中(沒必要寫到磁盤上)。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

這裏寫圖片描述

總之,Map Task和Reduce Task調優的一個原則就是減小數據的傳輸量、儘可能使用內存、減小磁盤IO的次數、增大任務並行數,除此以外還有根據本身集羣及網絡的實際狀況來調優。
  • 1

三 管理員角度調優

管理員負責爲用戶做業提供一個高效的運行環境。管理員須要從全局出發,經過調整一些關鍵參數提升系統的吞吐率和性能。整體上來看,管理員需從硬件選擇、操做系統參數調優、JVM參數調優和Hadoop參數調優等四個角度入手,爲Hadoop用戶提供一個高效的做業運行環境。
  • 1

硬件選擇 
Hadoop自身架構的基本特色決定了其硬件配置的選項。Hadoop採用了Master/Slave架構,其中,master維護了全局元數據信息,重要性遠遠大於slave。在較低Hadoop版本中,master存在單點故障問題,所以,master的配置應遠遠好於各個slave。

操做系統參數調優

1.增大同時打開的文件描述符和網絡鏈接上限

使用ulimit命令將容許同時打開的文件描述符數目上限增大至一個合適的值。同時調整內核參數net.core.somaxconn網絡鏈接數目至一個足夠大的值。

補充:net.core.somaxconn的做用 
net.core.somaxconn是Linux中的一個kernel參數,表示socket監聽(listen)的backlog上限。什麼是backlog呢?backlog就是socket的監聽隊列,當一個請求(request)還沒有被處理或創建時,它會進入backlog。而socket server能夠一次性處理backlog中的全部請求,處理後的請求再也不位於監聽隊列中。當server處理請求較慢,以致於監聽隊列被填滿後,新來的請求會被拒絕。在Hadoop 1.0中,參數ipc.server.listen.queue.size控制了服務端socket的監聽隊列長度,即backlog長度,默認值是128。而Linux的參數net.core.somaxconn默認值一樣爲128。當服務端繁忙時,如NameNode或JobTracker,128是遠遠不夠的。這樣就須要增大backlog,例如咱們的3000臺集羣就將ipc.server.listen.queue.size設成了32768,爲了使得整個參數達到預期效果,一樣須要將kernel參數net.core.somaxconn設成一個大於等於32768的值。
  • 1
  • 2
  • 3
  • 4

2.關閉swap分區

避免使用swap分區,提供程序的執行效率。
除此以外,設置合理的預讀取緩衝區的大小、文件系統選擇與配置及I/O調度器選擇等
  • 1
  • 2

JVM參數調優 
因爲Hadoop中的每一個服務和任務均會運行在一個單獨的JVM中,所以,JVM的一些重要參數也會影響Hadoop性能。管理員可經過調整JVM FLAGS和JVM垃圾回收機制提升Hadoop性能。

Hadoop參數調優

1.合理規劃資源

設置合理的槽位數目
在Hadoop中,計算資源是用槽位表示的。slot分爲兩種:Map  Slot和Reduce Slot。每種slot表明必定量的資源,且同種slot是同質的,也就是說,同種slot表明的資源量是相同的。管理員須要根據實際須要爲TaskTracker配置必定數目的Map Slot和Reduce Slot數目,從而限制每一個TaskTracker上併發執行的Map Task和Reduce Task的數目。
編寫健康監測腳本
Hadoop容許管理員爲每一個TaskTracker配置一個節點健康情況監測腳本。TaskTracker中包含一個專門的線程週期性執行該腳本,並將腳本執行結果經過心跳機制彙報給JobTracker。一旦JobTracker發現某個TaskTracker的當前情況爲「不健康」,則會將其加入黑名單,今後再也不爲它分配任務。
  • 1
  • 2
  • 3
  • 4

2. 調整心跳配置

調整心跳的間隔 因根據本身集羣的規模適度的調整心跳間隔
啓用帶外心跳   爲了減小任務分配延遲,Hadoop引入了帶外心跳。帶外心跳不一樣於常規心跳,它是任務運行結束或者任務運行失敗時觸發的,可以在出現空閒資源時第一時間通知JobTracker,以便它可以迅速爲空閒資源分配新的任務。

除此以外,還包括磁盤塊配置、設置合理的RPC Handler和HTTP線程數目、慎用黑名單機制、啓用批量任務調度、選擇合適的壓縮算法、啓用預讀取機制等。
注:當一個集羣的規模較小時,若是必定數量的節點被頻繁的加入系統黑名單中,則會大大下降集羣的吞吐率和計算能力。
  • 1
  • 2
  • 3
  • 4
  • 5

四:YARN的內存和CPU配置

Hadoop YARN同時支持內存和CPU兩種資源的調度,本文介紹如何配置YARN對內存和CPU的使用。

YARN做爲一個資源調度器,應該考慮到集羣裏面每一臺機子的計算資源,而後根據application申請的資源進行分配Container。Container是YARN裏面資源分配的基本單位,具備必定的內存以及CPU資源。

在YARN集羣中,平衡內存、CPU、磁盤的資源的很重要的,根據經驗,每兩個container使用一塊磁盤以及一個CPU核的時候可使集羣的資源獲得一個比較好的利用。

一、內存配置

關於 內存 相關的配置能夠參考hortonwork公司的文檔 Determine HDP Memory Configuration Settings (https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.1.1/bk_installing_manually_book/content/rpm-chap1-11.html)來配置你的集羣。

YARN以及MAPREDUCE全部可用的內存資源應該要除去系統運行須要的以及其餘的hadoop的一些程序,總共保留的內存=系統內存+HBASE內存。

能夠參考下面的表格肯定應該保留的內存: 
這裏寫圖片描述

計算每臺機子最多能夠擁有多少個container,可使用下面的公式: 
containers = min (2*CORES, 1.8*DISKS, (Total available RAM) / MIN_CONTAINER_SIZE) 
說明:

CORES 爲機器CPU核數
DISKS 爲機器上掛載的磁盤個數
Total available RAM 爲機器總內存 MIN_CONTAINER_SIZE 是指container最小的容量大小,這須要根據具體狀況去設置,能夠參考下面的表格
  • 1
  • 2
  • 3
  • 4

這裏寫圖片描述

每一個container的平均使用內存大小計算方式爲:

RAM-per-container = max(MIN_CONTAINER_SIZE, (Total Available RAM) / containers))

經過上面的計算,YARN以及MAPREDUCE能夠這樣配置: 
這裏寫圖片描述

舉個例子:對於128G內存、32核CPU的機器,掛載了7個磁盤,根據上面的說明,系統保留內存爲24G,不適應HBase狀況下,系統剩餘可用內存爲104G,計算containers值以下:

containers = min (2*32, 1.8* 7 , (128-24)/2) = min (64, 12.6 , 51) = 13

計算RAM-per-container值以下:

RAM-per-container = max (2, (124-24)/13) = max (2, 8) = 8

這樣集羣中下面的參數配置值以下: 
這裏寫圖片描述

你也可使用腳本 yarn-utils.py (https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.1.1/bk_installing_manually_book/content/rpm-chap1-9.html)來計算上面的值:

python yarn-utils.py -c 32 -m 128 -d 7 -k False
  • 1

返回結果以下:

Using cores=32 memory=128GB disks=7 hbase=False Profile: cores=32 memory=106496MB reserved=24GB usableMem=104GB disks=7 Num Container=13 Container Ram=8192MB Used Ram=104GB Unused Ram=24GB yarn.scheduler.minimum-allocation-mb=8192 yarn.scheduler.maximum-allocation-mb=106496 yarn.nodemanager.resource.memory-mb=106496 mapreduce.map.memory.mb=8192 mapreduce.map.java.opts=-Xmx6553m mapreduce.reduce.memory.mb=8192 mapreduce.reduce.java.opts=-Xmx6553m yarn.app.mapreduce.am.resource.mb=8192 yarn.app.mapreduce.am.command-opts=-Xmx6553m mapreduce.task.io.sort.mb=3276
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

對應的xml配置爲:

<property> <name>yarn.nodemanager.resource.memory-mb</name> <value>106496</value> </property> <property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>8192</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>106496</value> </property> <property> <name>yarn.app.mapreduce.am.resource.mb</name> <value>8192</value> </property> <property> <name>yarn.app.mapreduce.am.command-opts</name> <value>-Xmx6553m</value> </property>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

另外,還有一下幾個參數:

yarn.nodemanager.vmem-pmem-ratio :任務每使用1MB物理內存,最多可以使用虛擬內存量,默認是2.1。 yarn.nodemanager.pmem-check-enabled :是否啓動一個線程檢查每一個任務正使用的物理內存量,若是任務超出分配值,則直接將其殺掉,默認是true。 yarn.nodemanager.vmem-pmem-ratio :是否啓動一個線程檢查每一個任務正使用的虛擬內存量,若是任務超出分配值,則直接將其殺掉,默認是true。
  • 1
  • 2
  • 3

第一個參數的意思是當一個map任務總共分配的物理內存爲8G的時候,該任務的container最多內分配的堆內存爲6.4G,能夠分配的虛擬內存上限爲8*2.1=16.8G。另外,照這樣算下去,每一個節點上YARN能夠啓動的Map數爲104/8=13個,彷佛偏少了,這主要是和咱們掛載的磁盤數太少了有關,人爲的調整 RAM-per-container 的值爲4G或者更小的一個值是否更合理呢?固然,這個要監控集羣實際運行狀況來決定了。 
CPU配置 
YARN中目前的CPU被劃分紅虛擬CPU(CPU virtual Core),這裏的虛擬CPU是YARN本身引入的概念,初衷是,考慮到不一樣節點的CPU性能可能不一樣,每一個CPU具備的計算能力也是不同的,好比某個物理CPU的計算能力多是另一個物理CPU的2倍,這時候,你能夠經過爲第一個物理CPU多配置幾個虛擬CPU彌補這種差別。用戶提交做業時,能夠指定每一個任務須要的虛擬CPU個數。

在YARN中,CPU相關配置參數以下:

yarn.nodemanager.resource.cpu-vcores :表示該節點上YARN可以使用的虛擬CPU個數,默認是8,注意,目前推薦將該值設值爲與物理CPU核數數目相同。若是你的節點CPU核數不夠8個,則須要調減少這個值,而YARN不會智能的探測節點的物理CPU總數。 yarn.scheduler.minimum-allocation-vcores :單個任務可申請的最小虛擬CPU個數,默認是1,若是一個任務申請的CPU個數少於該數,則該對應的值改成這個數。 yarn.scheduler.maximum-allocation-vcores :單個任務可申請的最多虛擬CPU個數,默認是32。
  • 1
  • 2
  • 3

對於一個CPU核數較多的集羣來講,上面的默認配置顯然是不合適的,在個人測試集羣中,4個節點每一個機器CPU核數爲32,能夠配置爲:

<property> <name>yarn.nodemanager.resource.cpu-vcores</name> <value>32</value> </property> <property> <name>yarn.scheduler.maximum-allocation-vcores</name> <value>128</value> </property>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

總結 
根據上面的說明,個人測試集羣中集羣節點指標以下: 
每一個節點分配的物理內存、虛擬內存和CPU核數以下: 
實際生產環境中,可能不會像上面那樣設置,好比不會把全部節點的CPU核數都分配給Spark,須要保留一個核留給系統使用;另外,內存上限也會作些設置。

小結

Hadoop 性能調優是一項工程浩大的工做,它不只涉及Hadoop自己的性能調優,還涉及更底層的硬件、操做系統和Java虛擬機等系統的調優。
整體來講,提升做業運行效率須要Hadoop管理員和做業擁有者共同的努力,其中,管理員負責爲用戶提供一個高效的做業運行環境,而用戶則根
相關文章
相關標籤/搜索