1. 引言
Dr. Elephant 由 LinkedIn 于 2016 年 4 月份開(kāi)源拘哨,是一個(gè) Hadoop 和 Spark 的性能監(jiān)控和調(diào)優(yōu)工具镶殷。Dr. Elephant 能自動(dòng)化收集所有指標(biāo),進(jìn)行數(shù)據(jù)分析恋拷,并以簡(jiǎn)單易用的方式進(jìn)行呈現(xiàn)准给。Dr. Elephant 的目標(biāo)是提高開(kāi)發(fā)人員的開(kāi)發(fā)效率和增加集群任務(wù)調(diào)試的高效性。Dr. Elephant 支持對(duì) Hadoop 和 Spark 任務(wù)進(jìn)行可插拔式描滔、配置化以及基于規(guī)則的啟發(fā)式j(luò)ob性能分析棒妨,并且根據(jù)分析結(jié)果給出合適的建議來(lái)指導(dǎo)如何調(diào)優(yōu)使任務(wù)更有效率。
2. 概述
下面是 Dr.Elephant 的界面展示含长。
Dashboard 按時(shí)間的由近到遠(yuǎn)展示出 Job 的診斷結(jié)果券腔。下面的 Tab:Mapper Data Skew 等都對(duì)應(yīng)到一條規(guī)則。藍(lán)色表示規(guī)則診斷通過(guò)拘泞,其他顏色表示有問(wèn)題纷纫。 Dr.Elephant 將診斷結(jié)果做了分級(jí),分別對(duì)應(yīng)不同的顏色陪腌。
Dr.Elephant 還提供了 job 的搜索和比較辱魁,界面如下圖
針對(duì)單個(gè) job 還可以看到 performance 的歷史曲線(xiàn)圖。
優(yōu)化建議诗鸭。
3. 系統(tǒng)架構(gòu)
Dr. Elephant 的系統(tǒng)架構(gòu)如下圖染簇。主要包括三個(gè)部分:
- 數(shù)據(jù)采集:數(shù)據(jù)源為 Job History
- 診斷和建議:內(nèi)置診斷系統(tǒng)
-
存儲(chǔ)和展示:MySQL 和 WebUI
drelephant-arch.png
4. 優(yōu)化建議
下面是一些常規(guī)優(yōu)化建議。
1. Tuning Each Step is Important
對(duì)于Pig任務(wù)來(lái)說(shuō)强岸,如果使用默認(rèn)參數(shù)來(lái)設(shè)置reducer的數(shù)量锻弓,這對(duì)任務(wù)的性能可能是致命的。一般來(lái)說(shuō)蝌箍,對(duì)每個(gè)Pig任務(wù)青灼,都花一些時(shí)間來(lái)調(diào)優(yōu)參數(shù)PARALLEL是非常值得做的暴心。例如:
memberFeaturesGrouped = GROUP memberFeatures BY memberId PARALLEL 90;
2. File Count vs. Block Count
由于 NameNode 的內(nèi)存中要保存文件的 metadata,所以大文件要優(yōu)于小文件杂拨。
3. Java Task Memory Management
map/reduce task 默認(rèn)會(huì)分配 2G 內(nèi)存专普。對(duì)于 Java job,2G 內(nèi)存會(huì)被拆分為 1G heap 和 0.5 ~ 1G non-heap扳躬。然而這對(duì)于某些 job 來(lái)說(shuō)并不是足夠的脆诉。下面是一些能夠減少內(nèi)存使用的技巧。
UseCompressedOops
32 系統(tǒng)的 JVM 使用 32bit 的無(wú)符號(hào)整型來(lái)定位內(nèi)存區(qū)域贷币,最大可表示的堆空間為 2^32 击胜,也就是 4G。64 位的 JVM 使用 64bit 的無(wú)符號(hào) long 型來(lái)表示內(nèi)存位置役纹,最大可以表示的內(nèi)存堆大小為 2^64偶摔。使用 long 代替 int,導(dǎo)致需要的內(nèi)存增大促脉。最新的 JVM 支持在使用時(shí)添加選項(xiàng) CompressedOops辰斋,在一些情況下使用 32bit 的空間代替 64bit 空間來(lái)保存內(nèi)存定位信息,這樣也可以在一定程度上減少內(nèi)存的使用瘸味。添加設(shè)置
Hadoop-inject.mapreduce.(map|reduce).java.opts=-Xmx1G -XX:+UseCompressedOops
UseCompressedStrings
這樣會(huì)將 String 類(lèi)型轉(zhuǎn)換為壓縮的 byte[] 型宫仗。如果 String 類(lèi)型變量使用的比較多,這樣會(huì)節(jié)省非常多的內(nèi)存旁仿。設(shè)置:添加 -XX:+UseCompressedStrings
到配置項(xiàng) mapreduce.(map|reduce).java.opts
藕夫。
4. Mapper time too short
出現(xiàn)這類(lèi)警告,有可能存在以下三種情況:
- A large number of mappers
- Short mapper avg runtime
- Small file size
5. 常見(jiàn)參數(shù)的優(yōu)化
1. Mapper 相關(guān)
mapreduce.input.fileinputformat.split.minsize
map 輸入的文件塊的大小的最小值枯冈。增加這個(gè)參數(shù)的值就可以減少 mapper 的數(shù)量毅贮。
mapreduce.input.fileinputformat.split.maxsize
當(dāng)使用 CombineFileInputFormat 或者 MultiFileInputFormat 時(shí),map 輸入的文件塊的大小的最大值尘奏。相應(yīng)的滩褥,縮小這個(gè)參數(shù)值就可以增加 mapper 的數(shù)量。值得注意的是炫加,如果使用 CombineFileInputFormat 時(shí)瑰煎,不設(shè)置最大的 split 大小,那么你的 job 會(huì)只使用一個(gè) mapper琢感。
2. Reducer 相關(guān)
mapreduce.job.reduces
對(duì)工作流性能影響最大的一個(gè)因素就是 reducer 的數(shù)量丢间。reducer 數(shù)量過(guò)少導(dǎo)致 task 執(zhí)行時(shí)間過(guò)長(zhǎng);數(shù)量過(guò)多同樣會(huì)導(dǎo)致問(wèn)題驹针。reducer 數(shù)量調(diào)整不是一個(gè)簡(jiǎn)單的事兒烘挫,下面是一些建議:
- reducer 數(shù)量多意味著 NameNode 上更多的文件。過(guò)多的文件可能造成 NameNode 掛掉。如果 reduce 的輸出小于 512M 時(shí)饮六,盡量使用較少的 reducer其垄。
- reducer 數(shù)量多意味著每個(gè) reducer 處理數(shù)據(jù)的時(shí)間更短。如果使用的reducer數(shù)量過(guò)少卤橄,每個(gè)reducer作業(yè)消耗的時(shí)間會(huì)顯著增加绿满。reducer運(yùn)行速度變快,就能處理更多的任務(wù)窟扑。
mapreduce.job.reduce.slowstart.completedmaps
這個(gè)參數(shù)是 reducer 開(kāi)始執(zhí)行前喇颁,至少有多少比例的 mapper 必須執(zhí)行結(jié)束,默認(rèn)值是 80%嚎货。但是 對(duì)于很多特定的 job橘霎,80% 不是最好的。下面是一些參數(shù)調(diào)整的參考殖属。
- 每個(gè) reducer 接收數(shù)據(jù)多少
- 剩下的 map 需要花費(fèi)的時(shí)間
如果 map 的輸出數(shù)據(jù)量比較大姐叁,一般建議 reducer 提前開(kāi)始執(zhí)行以處理數(shù)據(jù);反之 reducer 可以稍晚執(zhí)行洗显。一個(gè)估算的方法是先計(jì)算 shuffle 時(shí)間:所有的 map 執(zhí)行完到第一個(gè) reduce 開(kāi)始執(zhí)行中間的時(shí)間外潜,然后 reducers 比較理想的執(zhí)行時(shí)間是最后一個(gè) map 結(jié)束時(shí)間減去 shuffle 時(shí)間。
3. Compression
mapreduce.map.output.compress
將該參數(shù)設(shè)置為 True 可以將 map 輸出的數(shù)據(jù)進(jìn)行壓縮挠唆,從而可以減少節(jié)點(diǎn)之間的數(shù)據(jù)傳輸量处窥。然而需要注意的是壓縮和解壓的時(shí)間要小于數(shù)據(jù)在節(jié)點(diǎn)之間的傳輸時(shí)間。如果 map 輸出數(shù)據(jù)量很大玄组,或者屬于比較容易壓縮的類(lèi)型碧库,這個(gè)參數(shù)設(shè)置為 True 則很有必要;反之設(shè)置為 False 則可以減少 CPU 的工作量巧勤。
4. Memory
mapreduce.(map|reduce).memory.mb
默認(rèn) 2G,1G heap + 0.5~1G non-heap弄匕。一些情況下這個(gè)內(nèi)存大小是不夠用的颅悉。
5. Advanced
controlling the number of spills / io.sort.record.percent
mapreduce.(map|reduce).speculative
將這個(gè)參數(shù)設(shè)置為 false 可以避免相同的 map 或者 reduce task 并發(fā)執(zhí)行。