HBase運維|HBase2.x修復工具HBCK2介紹

1. 背景

在瞭解HBCK2之前,建議先了解一下啥是HBCK。HBCK是HBase1.x中的命令,到了HBase2.x中,HBCK命令不適用,且它的寫功能(-fix)已刪除,它雖然還可以報告HBase2.x集羣的狀態,但是由於它不瞭解HBase2.x集羣內部的工作原理,因此其評估將不準確。因此,如果你正在使用HBase2.x,那麼對HBCK2應該需要了解一些,即使你不經常用到。

2. 獲取HBCK2

HBCK2已經被剝離出HBase成爲了一個單獨的項目,如果你想要使用這個工具,需要根據自己HBase的版本,編譯源碼。其GitHub地址爲:https://github.com/apache/hbase-operator-tools.git

默認HBase的版本是2.1.6,可以在父pom.xml文件裏修改成你需要的版本,我們線上集羣的版本是cdh-6.3.1-hbase2.1.0,與默認版本接近,因此我就使用默認的版本。

項目根目錄下運行打包命令:

mvn clean install -DskipTests

編譯成功後的截圖:

Base-hbck2的target目錄下可以找到我們最後需要的jar

把該jar包上傳到集羣隨便一個目錄下。

3. 測試命令是否可以正常使用

開始使用HBCK2的命令,最直接的使用方式:

./bin/hbase hbck -j <jar包地址> <命令>

使用HBCK2禁用啓用測試表。

運行禁用表命令:

hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar setTableState leo_test DISABLED


  • hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar 指定jar包的方式使用HBCK2命令

  • setTableState 改變表狀態的命令

  • leo_test 表名

  • DISABLED 禁用狀態

看圖,表的狀態已經被更改爲DISABLED

運行啓用表命令:

hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar setTableState leo_test ENABLED

看圖,表的狀態已經被更改爲ENABLED

有個疑問就是,表狀態被更改爲DISABLED,這張表的region依然是online狀態,表依然可以被正常查詢。

以上操作順利執行,就可以證明我們的HBCK2命令被安裝成功了。

4. Procedure簡介

HBase2集羣幾乎所有的操作都是通過procedure進行的,因此,HBCK2的工作實際就是修復各種不正常的procedure。

一個procedure是由一系列的操作組成,一旦完成,要麼成功,要麼失敗(ROLL BACK),不存在中間狀態,所以,procedure是支持事物的。

procedure執行的每一步都會以log的形式持久化在HBase的MasterProcWals目錄下,這樣master重啓時也能通過日誌來恢復之前的狀態且繼續執行。

對於運維而言最重要的一點就是procedure在執行過程中會拿好幾把鎖, 這個在處理問題時是很重要的,因爲一旦鎖沒有釋放,再做任何操作也只能是卡住等鎖。

  • IdLock:procedure級別的鎖,保證一個procedure不會被多個線程同時執行。

  • 資源鎖:對HBase的內部資源進行加鎖,不同的procedure加鎖的粒度不同,目前有region/table/namespace/region server級別的鎖。

舉例來說,假設我assign一個region,那麼procedure在執行的時候就需要對這個region進行加鎖,這樣如果有別的人想要unassign這個region,或者drop這個region所在的table,都需要等最早的assignment結束後釋放鎖了才能執行。這樣防止有不一致的情況出現。

5. HBCK2核心功能介紹

5.1 bypass [OPTIONS]

bypass可以將一個或多個卡住的procedure進行釋放。

原理是,在procedure的類裏有一個bypass的flag,每次執行時會檢查這個flag是否爲true,如果爲true則直接返回null,這樣procedure就會被認爲執行成功。

而bypass就是把這個procedure對象中的這個flag設爲true。這樣stuck的procedure就能夠不再執行,後續的修復才能繼續。

返回值爲true則是成功,false是失敗。

參數解析:

-o,--overide

在執行bypass之前先會嘗試去拿idLock,如果procedure還在運行就會超時返回null,但是設置了這個參數,即使拿不到idLock也會去將procedure的bypass flag設爲true。

-r, --recursive

在bypass一個procedure時也會將這個procedure的所有子procedure進行遞歸bypass時。例如我們bypass一個對table schema修改的procedure,就需要加上-r參數,才能把這個操作的所有子procedure都bypass掉。

-w, --lockWait

上面提到的等到idLock的超時時間配置,默認爲1ms。

5.2 assigns [OPTIONS]

將一個或多個region再次隨機assign到別的機器上,返回值時創建的pid則爲成功,-1則爲失敗。

參數解析:

-o, --override

這裏的override跟bypass的override不同,因爲assign本身就會創建一個新的procedure,所以肯定是不涉及到拿idLock的,但是這裏涉及到資源鎖的問題。因爲之前卡住的資源鎖即使在bypass後也不會釋放(用於fence, 防止更多未知的錯誤操作),所以需要加一個-o去手動釋放這個資源鎖。

下面,我們實際運行一下這個命令,感受其作用。

 hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar assigns -o leo_test,,1588902855503.596a8c918380a9fb55ed64ecf716ecd6.


  • leo_test,,1588902855503.596a8c918380a9fb55ed64ecf716ecd6. 這個是我測試表,leo_test的一個region的encoded_name

命令執行的結果是:

返回值爲-1,說明命令運行失敗。

十有八九是我的region name指定錯了,重新運行如下命令。

hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar assigns -o 596a8c918380a9fb55ed64ecf716ecd6

命令執行的結果是:

可以看到,成功返回了此次procedure的ID,觀察HBase自帶的監控界面。

HBCK2的命令提交成功後,監控界面會顯示此次操作的記錄,裏面可以查看命令運行的詳細狀態。

查看錶的監控界面,發現我們操作的region依然在72那臺機器上,看起來好像沒有任何變化。不知道是不是由於我們測試的表只有一個region的緣故,於是,我又測試了一張有17個region的表。

除了master有這樣的日誌之外,還是沒有任何效果。

暫時實在搞不明白這條命令的具體效果,以後再慢慢研究吧,接着來看下一個核心功能。

5.3 unassigns [OPTIONS]

將一個或多個region unassign,返回值是創建的pid則爲成功,-1則爲失敗。

參數解析:

-o,--override,與assigns的一致

5.4 setTableState

可能的table狀態, ENABLED, DISABLED, DISABLING, ENABLING;

在table的狀態和所有的region狀態不一致時可以用這個命令進行修復。

5.5 serverCrashProcedures

手動schedule一個或多個serverCrashProcedure, 如果有serverCrashProcedure沒有執行成功,但是procedure log已經丟失了,那麼可以利用這個命令進行修復。返回值爲創建的pid則爲成功,-1則爲失敗。

patch在HBASE-21393[3],目前這個功能在release版本還沒有。

看樣子應該能用,可現在就是不知道咋用。

6. 利用HBCK2來查找集羣的問題

6.1 canary tool

模擬用戶的讀寫請求,去訪問集羣上的表。當我們需要檢查集羣meta上記錄的region assignment跟實際region server上打開的region是否一致時,可以使用這個命令去檢查:

hbase canary -f false -t 6000000

nohup hbase canary -f false -t 6000000 > /data/leo_jie/hbase.log 2>&1 &

這個命令會向meta上的記錄的每個region發送一個get請求,將-f設爲false是爲了不在遇到第一個錯誤時退出,-t則是這個命令的超時時間,我們設成了6000秒。在執行完成以後可以通過grep ERROR來找到那些有問題的region。

需要注意的是因爲是模擬客戶端發送的get請求,最好將HBase的客戶端超時時間和超時次數配的小一些,否則會很慢。

PS: canary 本身也很適合用來作爲集羣可用性的監控,有興趣的同學可以去了解一下。

 cat /data/leo_jie/hbase.log | grep ERROR

grep ERROR 來發現是否有異常信息。

6.2 頁面狀態

其實大部分的信息都會在master的頁面上展示出來,我們來詳細的介紹一下:

可以檢查當前所有沒有執行完的procedure以及所有資源鎖,當我們想要assign或者unassign一個region時,需要先去檢查下是有別的procedure已經佔有了這個資源鎖,如果是的話需要先將那個procedure bypass掉,或者等待那個procedure釋放鎖。

可以看到EXCLUSIVE的lock只有region級別的,圖中紅框圈出來的就是佔有這個鎖的procedure id以及它的parent procedure id, 由此我們知道如果想要重新assign/unassign這個region,那麼一定要bypass這個procedure。

同理,當Locks這塊沒有任何EXLUSIVE鎖時,我們可以放心的去執行操作而不用擔心被卡住。

以上內容節選自,HBase指南 | HBase 2.0之修復工具HBCK2運維指南,因爲我在本地測試的時候,沒有重現這種鎖佔用的情況。

6.3 OPENING/CLOSING region的查找

branch-2.0 上最容易出現的問題就是region卡在了OPENNING/CLOSING狀態,一般處於這兩種狀態的region都會在rit的隊列中,可以通過點擊頁面上的鏈接拿到所有的region以及對應的procedure id。

可以看到現在有17個region處在transition中,我們可以點擊紅框圈住的這個鏈接,會展示所有的region。

因爲我們最後是希望通過HBCK2來進行處理,那麼最好是可以複製粘貼需要處理的region或者procedure, 所以可以點擊圈出的這兩個按鈕,會以text形式展示所有region或者所有procedure。

以上內容依舊是節選,因爲沒遇到RIT的情況,同時,我們也不希望遇見。😄

6.4 Master的日誌

stuck的region會打印以下日誌:

WARN [ProcExecTimeout] org.apache.hadoop.hbase.master.assignment.AssignmentManager: STUCK Region-In-Transition rit=OPENING, location=c4-hadoop-tst-st99.bj,42900,1542148656901, table=test_modify, region=8d81f74b324d0503c3fc87f34e9a17cb

7. 解決問題

定位到問題之後,我們需要解決問題。

7.1 解決region卡在OPENING/CLOSING 狀態

首先找到這些region對應的pid, 然後執行bypass, 檢查是否鎖都釋放了,如果釋放了就再assign一遍,如果需要close,就再unassign一次。

7.2 對table的修改有問題如何回退

找到這個修改的root procedure, bypass -or來bypass所有相關的procedure, 利用table unset來重置meta,因爲bypass之後資源鎖還是沒有釋放,所以需要手動加上override參數再去全部assigns一遍

7.3 Master起不來

日誌裏一般會有這個:

WARN org.apache.hadoop.hbase.master.HMaster: hbase:meta,,1.1588230740 is NOT online; state={1588230740 state=CLOSING, ts=1538456302300, server=ve1017.example.org,22101,1538449648131}; ServerCrashProcedures=true. Master startup cannot progress, in holding-pattern until region onlined.

手動去assign一下meta表即可,hbase:meta表的encoded name是一個時間戳,比如上面日誌的encoded name就是1588230740

另外hbase:namespace表沒有online也會造成這個問題,同樣需要我們去手動assign一下

7.4 table卡在disabling狀態

因爲要求是所有region都disabled, 那麼解決辦法可以是手動把沒有closed的region根據case1來解決。如果所有region都已經是closed狀態了,那麼我可以利用setTableState手動將表的狀態設爲DISABLED。之後再drop都是安全的了。

8. 總體的解決思路

其實HBase-2.x版本的運維思路很簡單,因爲使用了procedure,集羣出現meta跟regionserver不一致的狀態是很少的,一般都是有procedure出問題了。那麼我們主要就是看怎麼解決這個有問題的procedure。

如果是table/namespace級別的修改,因爲設計到很多region的鎖,如果需要bypass的話需要找到root procedure然後使用bypass -or.

如果只是region級別的問題,則bypass -o即可。

bypass之後檢查locks的頁面,看看是不是鎖都釋放了,如果沒有鎖了則根據需求進行assign或者unassign,或者對table的屬性進行還原。

9. 參考鏈接

文中很多解決問題的思路參考了一下博客,後續實踐中如果遇到此類問題,將會進行更加詳細的分析和總結,然後補充文檔。

  • https://yq.aliyun.com/articles/683107/

本文分享自微信公衆號 - HBase工作筆記(HBase-Notes)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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