HBase Meta 元信息表修復實踐

作者:vivo 互聯網大數據團隊 - Huang Guihu、Chen Shengzun

HBase是一款開源高可靠、高可擴展性、高性能的分佈式非關係型數據庫,廣泛應用於大數據處理、實時計算、數據存儲和檢索等領域。在分佈式集羣中,硬件故障是一種常態,硬件故障可能導致節點或者集羣級別服務中斷、meta表損壞、RIT、Region空洞、重疊等問題,如何快速修復故障恢復業務尤其重要,本文章主要是圍繞HBase meta表常見的故障以及對應解決方案進行描述。

一、背景

相信做過HBase開發、運維相關工作的朋友多多少少都有這樣感受,HBase作爲分佈式非關係型數據庫中的佼佼者不僅穩定、性能高、安裝擴容等運維也非常簡單,但是HBase缺乏成熟監控系統對故障排查極不友好。如果缺乏對HBase全面瞭解在應對日常故障經常束手無策,小編們作爲運維大大小小20+個HBase集羣涉及1.x~2.x等版本,經歷過meta表損壞無法正常上線、Region重疊、Region空洞、權限丟失等線上問題毒打,也帶着各種各樣問題從HBase源碼中尋求正確答案,本文是小編們多次故障中總結出的meta表常見解決方案。

二、HBase meta 元信息表

HBase meta表又稱爲catalog表是一張特殊的HBase表,它存儲了HBase集羣所有Region和其對應的RegionServer信息,元信息表的數據正確性對於HBase集羣的正常運行至關重要,因此需要保證元信息表的數據正確是集羣穩定運行的必要條件。如果meta表出現數據不一致將會導致RIT(Region In Transition)甚至出現由於HMaster 無法正常初始化導致集羣無法正常啓動,由此可見meta表在HBase集羣中重要性,下面我們圍繞meta表結構、數據格式、啓動流程進行解析它(本文主要圍繞HBase 2.4.8版本,也會穿插HBase 1.x版本)。

2.1 meta 表結構

meta表主要包括info、table、rep_barrier三個列族分別記錄Region信息、表狀態:

圖片

2.2 meta 表加載流程

通過上述meta表結構我們對該表有一個整體認識,做過HBase運維的朋友相信都有這種經驗有一些集羣啓動比較快、有一些集羣啓動比較慢,甚至有時候由於操作不當集羣重啓時候一直卡在meta表加載無法繼續執行後續流程。如果我們對meta表加載流程有一個整體瞭解之後我們將對每一個集羣啓動時間多多少少都有一個心理預期,以下是meta表加載相關流程:

圖片

通過以上meta表加載流程圖我們很好找到爲什麼有一些集羣啓動比較慢、有一些集羣啓動失敗原因了,下面我們針對兩類場景進行分析:

  • 集羣啓動慢:

通常新集羣或者表數量比較少集羣往往啓動速度比較快,表數量比較多的集羣往往啓動相對慢很多,甚至有一些集羣啓動HMaster需要15~30分鐘,有時候集羣啓動時間比較長讓人不免懷疑是不是集羣出現問題了,爲什麼那麼長時間無法進入正常狀態呢?在整個加載流程中出現兩個耗時比較長地方。

預加載所有表描述符:需要把HBase數據目錄全部掃描一遍並解析出.tabledesc目錄下面數據文件存放HMaster 內存中,如果表數量比較多(超過10000張表)這一過程往往需要十來分鐘,如果我們看HMaster 頁面出現“Pre-loading table descriptors”字樣時說明該集羣處於預加載階段我們只需耐心等待即可,因爲還沒有到meta表加載階段。

上線業務表Region:meta表數據大小通常在幾十M到幾百M之間Region打開時間比較快(秒級),集羣啓動階段需要檢查並上線Offline Region,如果想加快打開速度可以適當調整hbase.master.executor.openregion.threads(默認值爲5)值。

  • 集羣啓動失敗:

meta表上線失敗:當default資源組的HRegionServer掛掉之後,重啓後機器的startcode變化之後,meta的數據分片找不到打開節點,導致集羣啓動失敗。

三、如何修復 meta 表

由於HBase集羣狀態主要是通過meta表去維護,如果meta表出現了損壞或錯誤,將會導致HBase集羣的不可用和麪臨數據丟失風險。我們知道meta表數據一致性非常重要那麼什麼情況會出現數據不一致呢?(HBase 2.4.8修復命令參考hbase-operator-tools工具)。

  • RegionServer宕機或異常:當RegionServer宕機或異常時,meta表中存儲的Region和RegionServer信息可能會出現錯誤或丟失。

  • 數據損壞或錯誤:當meta表中的數據損壞或錯誤時,可能會導致HBase集羣的不可用和數據丟失。

  • 非法操作:當對meta表進行非法操作時,例如刪除或修改meta表中的數據,可能會導致meta表出現錯誤或丟失。

meta表故障只是一直比較籠統的說法,我們可以根據類型可以大致分爲長時間RIT、Region空洞、Region重疊、表描述文件丟失、meta表hdfs路徑爲空、meta表數據丟失等,下面我分別對這些類型故障進行分析並進行修復:

3.1 RIT

RIT(Region In Transition)是指HBase集羣中正在進行狀態轉換,以下操作都會引起HBase集羣中Region的狀態發生變化,例如RegionServer宕機、Region正在進行拆分、合併等操作,Region狀態主要是包括以下十二種狀態以及轉化圖:

圖片

圖片

爲了更加清晰Region狀態裝換我們根據操作類型可以分爲assign、unassign、split、merge,如果操作過程出現RegionServer宕機或異常、數據損壞或錯誤都會出現RIT,RIT雖然是在HBase運維中經常遇見的問題,但是如果清楚底層邏輯將會比較容易處理RIT問題,HBase集羣都具備RIT修復能力大部分情況都不需要手工介入都能正常恢復,出現長時間RIT才需要人工介入處理,那什麼是長時間RIT?爲什麼會出現長時間RIT呢?

如果用過HBase 1.x和HBase 2.x版本明顯感覺HBase 2.x比較少出現RIT,其實Region的操作主要是通過AssignmentManager類進行Region轉移,對比兩個版本代碼我們發現hbase.assignment.maximum.attempts參數(assign重試次數)在兩個版本的默認值不一樣,HBase 2.4.8重試次數爲最大整數Integer.MAX_VALUE(而HBase 1.x中該值默認爲10),這就是爲什麼在HBase 2.x中比較少出現長時間RIT原因。

圖片

RIT處理方法:

  1. 建刪大表都會出現RIT主要是由於Region數量比較多集羣壓力比較大導致assign、unassign響應時間過長導致,針對這類問題一般不需要人工介入HBase可以自愈。

  2. 如果集羣版本爲1.x可以適當調整hbase.assignment.maximum.attempts值增加重試次數,如FAILED_OPEN、FAILED_CLOSE通常都可以自愈,或者手工執行assign命令一個個Region分配上線(如果Region比較多切換HMaster 修復)。

  3. 如果出現Region分配失敗,不存在RegionServer時候,手工assign都沒辦法恢復,如Region被分配到bogus.example.com,1,1節點只能通過切換HMaster 恢復。

問題思考:

爲什麼Region手工介入都不能正常上線切換HMaster 就能恢復呢?(參考HMaster 啓動流程TransitRegionStateProcedure、HMaster 類源碼)

3.2 Region 空洞

我們創建HBase表時如果細心去分析Region規律會奇怪發現Region startkey和endkey屬於左閉右開的連續區間,如果突然這些區間少了一塊(如下圖)將會出現什麼問題呢?

圖片

出現上面情況就是我們常說的Region出現空洞,如果用HBase hbck工具檢查會看到這樣錯誤信息ERROR: There is a hole in the region chain between 01 and 02.  You need to create a new .regioninfo and region dir in hdfs to plug the hole,HBase集羣出現空洞往往是沒辦法自愈需要人工干預才能恢復正常,既然我們知道少了一個Region我們如果把空白區間的Region補回去不就可以了嗎?正常做法是先把空白的Region補充回去,並檢查meta表信息是否正確,最後再上線Region,如果這一系列操作都通過手工去實現不僅僅容易出錯操作時間也很長,下面分別介紹一下不同版本HBase修復方法,其實不同版本處理方法雖然有一點差異但是處理流程都一樣。

圖片

Region空洞處理方法:

**(1)HBase 1.x修復方法  **

  1. HBase hbck –fixHdfsHoles:在hdfs上創建空Region文件路徑

  2. HBase hbck -fixMeta:修復該Region所在meta表數據

  3. HBase hbck –fixAssignments:上線修復之後Region

  4. 或者HBase hbck –repairHoles相當於(fixHdfsHoles、fixMeta、fixAssignments)幾個組合起來

(2)HBase 2.4.8修復方法(參考後面hbase-operator-tools工具)

由於HBase 2.4.8沒有提供相關的命令去添加Region目錄操作方面相對麻煩一點,其實HBase 2.4.8裏面很多工具類都提供創建Region方法,hbase-server-2.4.8-test包中HBaseTestingUtility類都提供了操作Region相關的入口,下面我們的解決方法主要是圍繞該方法進行恢復。

  1. extraRegionsInMeta -fix:首先把meta表中hdfs目錄不存在記錄先刪除

  2. HBaseTestingUtility.createLocalHRegion:創建hdfs文件路徑保證Region連續性

  3. addFsRegionsMissingInMeta:再往meta表添加新建Region信息(添加成功之後會返還Region id

  4. assigns:最後把新加入Region上線

3.3 Region 重疊

既然Region會出現空洞那麼會不會存在這種情況,相同的startkey、endkey出現多個呢?答案是肯定的如果多個Region startkey、endkey是一樣的Region,那麼我們將這種情況稱作Region重疊。Region重疊在HBase中比較難模擬同時也是比較難處理的一種問題。如果我們做hbck檢查時候出現這種日誌ERROR: Multiple regions have the same startkey: 02

圖片

另外一種重疊Region跟相鄰的分片其中一個或兩個的rowkey範圍有交集,這類問題統稱overlap問題,針對這個比較難的場景我們通過自研工具模擬overlap問題復現並一鍵修復overlap(摺疊)和hole(空洞)問題。

overlap問題模擬功能

Region重疊問題實際就是兩個不同Region,rowkey的範圍有交集,比如Region01的startkey和endkey是(01,03),同時另外一個Region02的範圍是(01,02),這樣兩個Region出現了交集(01,02),hbck檢測就會報overlap問題。

重疊問題在生產環境只有在Region分裂和機器同時掛掉情況下,纔會出現overlap問題,出現條件比較苛刻,復現問題比較困難,能夠復現問題對後續修復和故障演練都很重要,overlap問題復現原理:

圖片

overlap 問題復現

1)生成一個rowkey範圍重疊的Region分片:

java -jar -Drepair.tableName=migrate:test_hole2 -Dfix.operator=createRegion -DRegion.startkey=06 -DRegion.endkey=07   hbase-meta-tool-0.0.1.jar

2) 將overlap問題Region移動到表目錄下:

sudo -uhdfs hdfs dfs -mv /tmp/.tmp/data/migrate/test_hole2/c8662e08f6ae705237e390029161f58f /hbase/data/migrate/test_hole2

3) 刪除正常的表migrate:test_hole2的meta表信息:

java -jar -Drepair.tableName=migrate:test_hole2 -Dfix.operator=delete  hbase-meta-tool-0.0.1.jar

4)重構overlap問題表元數據信息:

java -jar -Drepair.tableName=migrate:test_hole2 -Dfix.operator=fixFromHdfs  hbase-meta-tool-0.0.1.jar

5) 重啓集羣后hbck報告Region重疊c8662e08f6ae705237e390029161f58f,成功復現重疊問題

圖片

方法一:一鍵修復overlap(重疊)和hole(空洞)

適用於摺疊數量不超過64個情況下,利用自研工具 hbase-meta-tool可以將相鄰Region有rowkey交集的範圍合併,有空洞缺失範圍生成新的Region,這樣就能修復問題,問題修復原理如圖:

圖片

1)修復集羣的重疊與空洞問題:

java -jar  -Dfix.operator= fixOverlapAndHole hbase-meta-tool-0.0.1.jar

方法二:大規模摺疊修復

適用大規模摺疊超過幾千個或者上萬個情況修復服務器端報異常,採取一下修復手段

1)一鍵清除有摺疊問題表的元數據:

java -jar -Drepair.tableName=migrate:test1 -Dzookeeper.address=zkAddress -Dfix.operator=delete     hbase-meta-tool-0.0.1.jar

2)備份原始表數據:

hdfs dfs -mv /hbase/data/migrate/test/ /back

3)刪除原始表和導入備份數據每個Region分片:

hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /back/test/region01-regionN  migrate:test1

3.4 meta 表數據修復

HBase線上集羣我們可能會遇到下面棘手問題:

  • coprocessor配置錯誤的表,找不到協處理器路徑,加載Region過程中找不到jar,導致集羣反覆掛掉,drop命令也刪除不掉;

  • HBase meta表元數錯誤,startcode不對,上線過程中找不到服務器的表,表始終不能上線。

我們要在保證不影響集羣其他表服務的情況下,單獨不停服修復問題表。

問題表的meta數據修復

1)假設表migrate:test1有問題,可以一鍵刪除問題表元數據:

java -jar -Drepair.tableName=migrate:test1 -Dfix.operator=delete  hbase-meta-tool-0.0.1.jar

2)讀取hdfs表的.regioninfo文件夾內容,一鍵重構正確的元數據:

java -jar -Drepair.tableName=migrate:test1 -Dfix.operator=fixFromHdfs  hbase-meta-tool-0.0.1.jar

3.5 meta 損壞

上述5種情況都是在meta表正常上線的前提下面修復,如果meta表數據損壞無法上線我們應該怎麼修復呢?通常我們都會想到重建meta表再把Region信息寫入meta表,如果集羣處於下線狀態HBase shell或者HBase api通常是無法執行create建表。

我們分析meta表初始化類InitMetaProcedure發現meta表創建流程大致分兩步走:

1)創建Region目錄已經.tabledesc文件

2)分配Region並上線。

InitMetaProcedure核心源碼:

InitMetaProcedure

protected Flow executeFromState(MasterProcedureEnv env, InitMetaState state) throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {
    try {
      switch (state) {
        case INIT_META_WRITE_FS_LAYOUT:
          Configuration conf = env.getMasterConfiguration();
          Path rootDir = CommonFSUtils.getRootDir(conf);
          TableDescriptor td = writeFsLayout(rootDir, conf);
          env.getMasterServices().getTableDescriptors().update(td, true);
          setNextState(InitMetaState.INIT_META_ASSIGN_META);
          return Flow.HAS_MORE_STATE;
        case INIT_META_ASSIGN_META:
          addChildProcedure(env.getAssignmentManager().createAssignProcedures(Arrays.asList(RegionInfoBuilder.FIRST_META_RegionINFO)));
          return Flow.NO_MORE_STATE;
        default:
          throw new UnsupportedOperationException("unhandled state=" + state);
      }
    } catch (IOException e) {
}
private static TableDescriptor writeFsLayout(Path rootDir, Configuration conf) throws IOException {
    LOG.info("BOOTSTRAP: creating hbase:meta region");
    FileSystem fs = rootDir.getFileSystem(conf);
    Path tableDir = CommonFSUtils.getTableDir(rootDir, TableName.META_TABLE_NAME);
    if (fs.exists(tableDir) && !fs.delete(tableDir, true)) {
      LOG.warn("Can not delete partial created meta table, continue...");
    }
    TableDescriptor metaDescriptor = FSTableDescriptors.tryUpdateAndGetMetaTableDescriptor(conf, fs, rootDir);
    HRegion.createHRegion(RegionInfoBuilder.FIRST_META_RegionINFO, rootDir, conf, metaDescriptor, null).close();
    return metaDescriptor;
}

我們可以參照InitMetaProcedure代碼邏輯編寫相應工具進行建表上線操作,meta表上線之後我們只需要把每張表Region信息寫入meta並對所有Region進行assign上線即可恢復集羣正常狀態。通過以上流程我們發現meta表修復流程也並非那麼複雜,但是如果生產環境表數量比較多或者個別大表Region數成千上萬那麼手工添加就變的非常耗時,我們下面介紹一直相對比較簡單的解決方法(HBase 1.x hbck工具、HBase 2.x hbase-operator-tools),下面我們看一下離線修復處理流程。

圖片

**HBase 1.x修復方法 **

  • 停止HBase集羣

  • sudo -u hbase hbase org.apache.hadoop.hbase.

    util.hbck.OfflineMetaRepair -fix

  • 重啓集羣完成修復。

HBase 2.4.8修復方法(hbase-operator-tools工具)

1)根據hdfs路徑自動生成meta表

  • 停止HBase集羣

  • sudo -u hbase hbase org.apache.hbase.

    hbck1.OfflineMetaRepair -fix

  • 重啓集羣完成修復。

2)單表修復方法

  • 刪除zookeeper中HBase根目錄

  • 刪除HMaster 、RegionServer所在hdfs WALs目錄

  • 重啓集羣此時meta沒有數據,集羣無法進入正常狀態

  • 執行添加Region命令把hbase:namespace、hbase:quota、hbase:rsgroup、hbase:acl四字表添加到集羣,添加完成之後日誌將會打印assigns後面跟隨這幾張表的Region,需要記錄下這些Region以便下一步assign操作。

sudo -u hbase hbase --config /etc/hbase/conf hbck -j hbase-tools.jar addFsRegionsMissingInMeta hbase:namespace hbase:quota hbase:rsgroup hbase:acl
  • 把上一步添加打印Region上線
sudo -u hbase hbase --config /etc/hbase/conf hbck -j  hbase-hbck2.jar assigns regionid
  • 業務表上線(只需要重複4-5步驟把業務表逐步上線)

注意事項

(如果業務表Region比較多第5不assign不能把Region全部上線成功,需要把表現disable再enable就可以正常上線)

備註:hbase-operator-tools OfflineMetaRepair工具存在以下幾個bug需要修復。

1、HBaseFsck createNewMeta方法創建meta表缺少.tabledesc文件

修改前:

TableDescriptor td = new FSTableDescriptors(getConf()).get(TableName.META_TABLE_NAME);

修改後:

FileSystem fs = rootdir.getFileSystem(conf);
TableDescriptor metaDescriptor = FSTableDescriptors.tryUpdateAndGetMetaTableDescriptor(getConf(), fs, rootdir);

2、HBaseFsck generatePuts默認Region狀態爲CLOSED因爲HMaster 重啓時候只上線OFFLINE狀態Region(如果爲CLOSED需要手工一個個Region上線工作量非常龐大)

修改前:

addRegionStateToPut(p, org.apache.hadoop.hbase.master.RegionState.State.CLOSED);

修改後:

addRegionStateToPut(p, org.apache.hadoop.hbase.master.RegionState.State.OFFLINE);

缺點

1)離線修復需要停止集羣服務,停止時長根據修復時間而定(大概在10-15分鐘左右)。

2)如果其中存在Region重疊、空洞等問題需要手工處理完成再執行OfflineMetaRepair離線修復命令。

四、hbase-operator-tools工具

hbase-operator-tools是HBase中的一組工具,用於協助HBase管理員管理和維護HBase集羣。hbase-operator-tools提供了一系列工具,包括備份和恢復工具、Region管理工具、數據壓縮和移動工具等,可以幫助管理員更好地管理HBase集羣,提高集羣的穩定性和可靠性。需要編譯源碼之後纔可以使用,源碼git地址。常見命令如下:

圖片

五、總結

HBase meta表的數據正確性對於HBase集羣的正常運行至關重要,如何保證meta表數據正確以及數據損壞之後快速修復變的極爲重要,如果對meta沒有全面認識每次集羣出現故障將會措手無策。本文主要是圍繞meta表結構加載流程、常見問題以及相關的修復方法分析,針對以上修復方法我們可以粗略分爲以下兩大類:

  • 在線修復:meta表可以正常通過hbck、自研工具進行meta表數據修復保證數據完整性。

  • 離線修復:meta表無法正常上線根據hdfs中Region信息重構meta表恢復HBase服務。

如果集羣規模比較大離線修復時間比較長集羣需要長時間停止服務,大部分情況業務是不能容忍可以結合實際情況進行表級別修復(除非meta表文件損壞不能正常上線),建議定時對集羣做hbck檢查一旦出現元信息不一致情況儘快修復避免問題擴散(如元信已經錯亂做集羣重啓錯亂Region將會由於assign失敗導致其他Region無法正常上線),如果定時巡檢發現有業務表出現元信息錯亂情況直接重meta表把該表信息刪除並根據根據hdfs路徑信息重新把Region加回meta表(addFsRegions-

MissingInMeta命令可以根據hdfs路徑把Region正確添加到meta表)。

參考文章:

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