disable table失敗,運維人員該如何處理?
相信每一個維護hbase集群的運維人員一定碰到過disable失敗,陷入無窮的"Region has been PENDING_CLOSE for too long..."狀態(tài),此時沒有什么好的辦法處理。經(jīng)常需要重啟集群。
這個問題產生的原因非常討厭,經(jīng)過一段時間的分析和驗證,得到了根本原因。要理解它,必須從disable的原理說起:
- disable線程是一個DisableTableHandler類,我們看它的handleDisableTable()方法,在while循環(huán)中先獲取table的regions列表,然后調用BulkDisabler的bulkAssign()方法,等待bulkAssign()返回為true時則結束
- 在bulkAssign()方法中啟動線程池,然后等待線程池超時,超時時間由hbase.bulk.assignment.waiton.empty.rit控制
- 在每個線程中,先從regions collection中得到regions列表,然后通知rs來處理該region,并且把該region放入RIT列表中,表示該region正在進行處理
- rs處理完region以后,將該region狀態(tài)在zk上置為closing,此時master得到通知
- master將這個region從RIT列表中刪除,并從regions列表中刪除。
注意以上最后一步,當master把它從RIT中刪除以后,還有短暫的時間這個region還在regions列表中,此時另一個線程拿到了這個region,并且此時這個region不處于RIT狀態(tài)保護,于是另一個線程開始重復以上過程,而前一個線程己經(jīng)把它從collection中刪除了,于是后一個線程再也無法完成closing事件。直到RIT超時(默認30秒)。
于是有兩個修改辦法:
1、縮短hbase.bulk.assignment.waiton.empty.rit這個時間(默認10分鐘,it's too long...),讓它重新進行一輪disable,此時會先把RIT的region都處理掉再繼續(xù),這樣多幾次嘗試總會成功的。
2、修改代碼:(https://issues.apache.org/jira/secure/attachment/12487669/HBASE-4064_branch90V2.patch)
- Index: src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
- ===================================================================
- --- src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1150529)
- +++ src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy)
- @@ -767,14 +767,15 @@
- * @param regionInfo
- */
- public void regionOffline(final HRegionInfo regionInfo) {
- + // remove the region plan as well just in case.
- + clearRegionPlan(regionInfo);
- + setOffline(regionInfo);
- +
- synchronized(this.regionsInTransition) {
- if (this.regionsInTransition.remove(regionInfo.getEncodedName()) != null) {
- this.regionsInTransition.notifyAll();
- }
- }
- - // remove the region plan as well just in case.
- - clearRegionPlan(regionInfo);
- - setOffline(regionInfo);
- }
即在以上步驟5時,先從regions列表中刪除,再清除它的RIT狀態(tài)。
方法2己經(jīng)測試成功,方法1更簡單,各位被這個問題困擾的同學可以一試。
原文鏈接:koven2049.iteye.com