Hive動態分區導致的Jobtracker Hang

昨天下午有20多分鐘Hadoop平臺無法跑HiveJobtracker的頁面也打不開,hadoop job –listhang住沒有響應,過了10分鐘後恢復了,查看gc日誌發現Jobtracker沒有進行full gc,查看這段時間的Job日誌發現一個可疑的Hive SQL: Insert into table t(dt) as select xxx,dt from txx,是一個用了動態分區的查詢.這個查詢和Jobtracker Hang住有什麼關係呢?

熟悉Jobtracker的都知道,在進行Job初始化時EagerTaskInitializationListener會鎖住JobInProgress然後進行InitTask,細節請各位查看代碼,這裏有一步就是需要向hdfs寫入初始數據並flush,而FairschedulerUpdate Thread在更新資源池的資源時是在持有JobTrackerFairscheduler的獨佔鎖然後再去計算每個資源池的資源情況,而計算running_map/running_reduce的時候要去獲取相應的JobInProgress鎖,各位讀者可能不明白,我爲啥要講這塊呢,問題就出現在這裏.

Hive在處理動態分區的時候,主要經歷這麼幾個步驟tablescan->filesink->movetask

在進行filesink的時候是根據記錄來處理的,會起Npart)個record writer然後開始處理動態分區字段,即這裏的dt,如果dt是連續的那麼打開一個block開始寫,否則關閉當前block,打開新dirblock繼續寫,這裏如果dt是不連續的出現並且記錄數量巨大的情況下會產生大量的文件,導致hdfs的負載標高,和當時的hdfs的監控是匹配的:

當時的集羣負載:

wKiom1Mr3syTM-zOAAMWZ6-2LOo698.jpg

當時產生的文件數:

wKioL1Mr3rOSDZwoAANEo5qPywU667.jpg

進而導致JobInProgress被鎖住,從而JobTracker被鎖住,導致JobTracker Hang住了!

那怎麼解決呢?利用distributeby dt把相同的dt排列到一起再進行filesink就不會造成大量的小文件產生了.

update:雖然Hive0.13(https://issues.apache.org/jira/browse/HIVE-6455)提供了參數來解決這個問題,但是又引入了bug(https://issues.apache.org/jira/browse/HIVE-8151),因此0.13建議還是使用distribute by的方式來解決這個問題;

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