這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)如何解決JobTracker Heap的OOM問題,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
我們提供的服務(wù)有:成都網(wǎng)站設(shè)計、做網(wǎng)站、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、平泉ssl等。為1000多家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的平泉網(wǎng)站制作公司
引子
最近新上了9107渠道的實(shí)驗(yàn)。
從實(shí)驗(yàn)方法上,相比于之前的9105渠道只是簡單地對過去6小時的正例數(shù)據(jù)進(jìn)行翻倍,9107則以當(dāng)前時間為基準(zhǔn),使用指數(shù)函數(shù)對合并后訓(xùn)練數(shù)據(jù)中的正例進(jìn)行增益。
從具體的實(shí)現(xiàn)而言,為了實(shí)現(xiàn)的簡單,實(shí)驗(yàn)的ETL部分依舊沿用Hadoop進(jìn)行ETL合并處理,但后續(xù)的Sampling和Filtering則采用python單機(jī)實(shí)現(xiàn)。經(jīng)過流程和數(shù)據(jù)測試無誤后上線,但結(jié)果老集群的JobTracher總是在跑了70多個Job之后就報出Heap OOM異常(java.lang.OutOfMemoryError: Java heap space)。
解決過程
直接google
在statckoverflow中有人建議調(diào)整HADOOP_CLIENT_OPT,通過增大其Xmx解決該問題,經(jīng)過嘗試后發(fā)現(xiàn)無效果。
突然發(fā)現(xiàn)java_pidxxxxx.hprof文件,搜索相關(guān)資料,發(fā)現(xiàn)Eclipse中的MAT工具,分析可能為JT的問題
hprof為當(dāng)虛擬機(jī)中發(fā)生OOM錯誤時,自動對Heap進(jìn)行轉(zhuǎn)儲生成的二進(jìn)制文件。在啟動進(jìn)程時,可以通過添加參數(shù)-XX:+HeapDumpOnOutOfMemoryError開啟該功能。
MAT(Memory Analyzer)為Eclipse中一分析hprof文件的工具,可以通過Eclipse中的'Install New Software'進(jìn)行集成。需要注意的一點(diǎn)是,當(dāng)生成的hprof文件過大的時候,需要適當(dāng)增大eclipse的啟動Xmx,其配置文件為安裝目錄下的eclipse.ini。
通過MAT打開生成的hprof文件,如下圖所示,會給出幾條Problem Suspect,在本文中,說明是由于JobTracker的占用內(nèi)存過大導(dǎo)致的OOM。
但是之前JobTracker穩(wěn)定運(yùn)行了好長時間,很少發(fā)生過該種現(xiàn)象,所以繼續(xù)嘗試使用MAT進(jìn)行進(jìn)一步的分析。通過對'dominator tree'一項進(jìn)行分析發(fā)現(xiàn),JobTracker中絕大部分的內(nèi)存都是由JobInProgress占用的,其結(jié)果如下圖所示。
至此,問題算是已經(jīng)定位出來,但是之前的JobTracker跑了上千的Job也從來沒有發(fā)生過該種問題,為什么這次只跑了70+個Job就發(fā)生了這種情況。
翻閱"Hadoop技術(shù)內(nèi)幕",了解JobTracker的主要作用
google搜索并沒有這方面很好地解答,就找了"Hadoop技術(shù)內(nèi)幕"一書中關(guān)于JobTracker的一章節(jié)進(jìn)行學(xué)習(xí)。有一點(diǎn)特別引起了我的注意,原來JobTracker在啟動的時候會啟動一些重要的線程和服務(wù),其中有一個retireJobsThread線程。
對于retireJobsThread線程而言,它可以清理長時間駐留在內(nèi)存的已經(jīng)運(yùn)行結(jié)束的Job信息(即JobInProgress對象的信息)。而將JobInProgress對象保存在內(nèi)存中,則是為了方便外部對歷史的Job信息進(jìn)行查詢。但由于JobInProgress對象會占用過多的內(nèi)存,所以當(dāng)Job同時滿足條件a,b或是a,c時,就會被標(biāo)志為過期的作業(yè)。
Job已經(jīng)完成,即狀態(tài)為SUCCEEDED,F(xiàn)AILED或KILLED
Job完成時間距離當(dāng)前已經(jīng)24小時(可以通過mapred.jobtracker.retirejob.interval調(diào)整)
Job擁有者已完成的Job數(shù)量大于100(可以通過mapred.jobtracker.completeuserjobs.maximum調(diào)整)
顯然正是由于Job的retire機(jī)制,避免了JobTracker占用內(nèi)存的無線膨脹。雖然解決了JobTracker占用內(nèi)存的無限膨脹問題,但是為什么之前的JobTracker就能維護(hù)100個JobInProgress,而現(xiàn)在就不可以了呢?9105和9107渠道到底差到了什么地方了呢?
突然間,想到了是不是由于ETL Job占用的內(nèi)存信息過大,導(dǎo)致當(dāng)前2G的HeapSize放不下這100條JobInProgress信息呢。于是,將hadoop-env.sh中的HADOOP_HEAPSIZE從2000調(diào)整到了4000,問題神奇的就沒有再出現(xiàn)過。那么究竟是為什么ETL Job會比Sampling Job和Filtering Job占用更多的內(nèi)存呢?于是就有了最后一步...
實(shí)際實(shí)驗(yàn)測試,使用jmap生成hprof文件,分析與預(yù)期的結(jié)果
在集群平穩(wěn)的運(yùn)行了100+個Job之后,使用jmap工具dump出來了一份JobTracker的hprof文件。再次使用MAT對其進(jìn)行分析,結(jié)果如下圖所示:
由圖可以看出以下幾點(diǎn):
JobTracker的內(nèi)存占用一直保持在1.7G左右
針對于JobInProgress占用內(nèi)存過大的原因,完全是由于其需要調(diào)度的TaskInProgress過多(一般為2K-3K個),從而比Sampling和Filtering耗費(fèi)掉更多的內(nèi)存
至此,問題解決,確實(shí)是因?yàn)?107渠道只保留了9105渠道的ETL Job,導(dǎo)致多個ETL JobInPregress累計占用內(nèi)存遠(yuǎn)大于之前的9105實(shí)驗(yàn),從而造成JobTracker一直產(chǎn)生OOM錯誤。
心得總結(jié)
說起來,問題的解決多多少少還是存在一定的偶然性,歸根結(jié)底還是在于對Hadoop平臺一些基礎(chǔ)組件的底層實(shí)現(xiàn)不熟悉,從而導(dǎo)致問題定位慢,走了不少的彎路
MAT確實(shí)是一個特別強(qiáng)大的工具,針對于JVM的OOM錯誤而言,通過使用MAT能夠非常方便的定位問題的根結(jié)。后續(xù)對MAT的學(xué)習(xí)使用還需要進(jìn)一步的加強(qiáng)。
對于正常運(yùn)行中的java進(jìn)程,可以使用jmap的jmap -dump:format=b,file=xx pid命令生成hprof文件,從而分析某一時刻進(jìn)程中內(nèi)存的詳細(xì)使用情況
上述就是小編為大家分享的如何解決JobTracker Heap的OOM問題了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。