故障描述
1.1發生背景
很久很久以前,有一天,我在HBase中新建了一張表 “XXX: XXX _EXCEPTION_LIST_INFO”,同時HBase在處理大量更新操作。然後在DROP掉表XXX: XXX_EXCEPTION_LIST_INFO時,HBase Master就宕機。
之後通過CM重新啓動後HBase服務,服務重啓後發生如下兩個錯誤,導致HBase集羣無法正常恢復:(1)HMaster節點自動Active失敗;(2)大量Region出現offline和RIT。
1.2現象描述
HA HMaster節點啓動了,過一段時間Active HBase Master節點自動失敗(大概3~5分鐘)。因為集羣採用了HA高可用,因此Standby HBase Master節點自動切換為Active。再過差不多相同時間,該節點也自動失敗。
查看Master節點的日誌報錯如下
Master Web UI上顯示處於RIT的Region
Master狀態頁告警信息:
故障分析處理
1.Master的日誌報錯:Timeout 300000ms waiting for namespace table to be assigned.表示namespace表未分配,並且超過設置的時間閾值。在HBase的設計中,Master啓動時首先分配meta表,然後再分配其它表。系統表hbase:namespace和其它用户表分配時同等對待,並沒有先分配系統表再分配用户表,如果一個集羣region非常多,默認300000ms(5分鐘)還分配不到namespace表,此時需要修改hbase.master.namespace.init.timeout超時時間。
2.根據此時情況,通過CM在“hbase-site.xml的HBase服務高級配置代碼段(安全閥)”中增加以下配置:
即增加namespace表分配超時時間為1天。
修改完成之後重啓HBase服務,這裏選擇滾動重啓HBase時RegionServer無法重啓,所以選擇完成重啓HBase服務。
3.重啓完成後,Master依然告警:Found regions staying in transition state for a duration longer than the configured threshold in HBase.,但服務並未宕掉,Master告警提示的原因是在HBase Master啓動時,檢測到有Region長時間處於RIT狀態(超過閾值)。
查看Master日誌如下
大量Region處於PENDING_OPEN狀態,Master檢測到RIT,
查看Zookeeper中的/hbase/region-in-transition,也可以看到大量的Region。
説明:每次HBase Master對Region的一個OPEN或一個CLOSE操作都會向Master 的RIT列表中插入一條記錄,因為Master對Region的操作要保持原子性。Region的 OPEN和 CLOSE是通過HBase Master和 RegionServer 協助來完成的。為了滿足這些操作的協調、回滾、一致性,HBase Master採用了 RIT 機制並結合Zookeeper 中znode狀態來保證操作的安全和一致性。
Region有以下幾種狀態:
4.經確認HBase未使用replication後,選擇重建Znode的方式進行測試:
a.停止HBase服務
b.使用hbase zkcli命令進入ZK客户端
c.執行rmr /hbase清除/hbase
d.重啓HBase服務,此時/hbase會重新生成
5.但是重啓完之後問題依然存在,再次查看Master日誌發現如下信息:
6.查看RegionServer的日誌,可以看到頻繁出現以下錯誤:
由上可以看出索引表的Region is not online,查看RegionServer Web UI發現RPC線程一直處於Initializing Region的Replaying edits階段,並且在等待一個小時時間後依然未完成。因此分析原因為Phoenix索引表的Region不能online,導致數據表的Region構建進程卡住,但是這些構建進程佔用了openregion線程(默認3個),導致索引表不能正常openregion,產生死鎖。
因此需要調整hbase.regionserver.executor.openregion.threads參數以增加openregion線程數。
7.通過CM在“hbase-site.xml的HBase服務高級配置代碼段(安全閥)”中增加以下配置:
即增加Region分配線程數至200個,然後再次重啓HBase服務
重啓HBase服務, HBase Master仍有告警信息,但在Active Master Web UI上可以看到上線的Region數量在增加,同時RIT中的Region數量在減少。稍等片刻後HBase服務恢復正常。
經測試HBase可以正常提供服務,數據無丟失。
處理結論
1.HBase Master在啓動時會首先分配meta表的Region,然後再分配其它表。namespace表和user表分配時同等對待,並沒有先分配系統表再分配用户表,如果一個集羣Region非常多,默認300000ms(5分鐘)有可能還分配不到namespace表,此時拋出異常:Failed to become active master java.io.IOException: Timedout 300000ms waiting for namespace table to be assigned。此時需要調整參數hbase.master.namespace.init.timeout增加超時時間。
2.分佈式死鎖發生在使用Phoenix(4.14.1)構建二級索引,並且數據表、二級索引表的Region數量適中的集羣中。當RegionServer打開Phoenix數據表的一個Region時,它將為該Region執行WAL重播,並重新構建二級索引表,而數據表的Region分配依賴於二級索引表。默認情況下每個RS上只有一個線程池,包含三個openregion線程。而二級索引表和數據表共用同一個線程池。因此,當Phoenix數據表的Region的這些重建進程佔用了openregion線程時,二級索引表就只能進入隊列等候,其Region就不能online。這就是死鎖發生的原因。
解決方式可以在hbase-site.xml中修改以下參數:
1)設置hbase.master.startup.retainassign為false(默認為true)
2)增加hbase.regionserver.executor.openregion.threads 的值(默認為3),然後重啓集羣解決。
如果還是出現同樣問題,可以調優以下分配管理器參數,以匹配Region的數量,從而加快分配速度:
參考鏈接:
https://issues.apache.org/jira/browse/PHOENIX-3072
https://issues.apache.org/jira/browse/HBASE-16095