天天看點

HBase Meta 元資訊表修複實踐

作者:閃念基因

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資訊、表狀态:

HBase Meta 元資訊表修複實踐

2.2 meta 表加載流程

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

HBase 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狀态主要是包括以下十二種狀态以及轉化圖:

HBase Meta 元資訊表修複實踐
HBase Meta 元資訊表修複實踐

為了更加清晰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原因。

HBase Meta 元資訊表修複實踐

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屬于左閉右開的連續區間,如果突然這些區間少了一塊(如下圖)将會出現什麼問題呢?

HBase Meta 元資訊表修複實踐

出現上面情況就是我們常說的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修複方法,其實不同版本處理方法雖然有一點差異但是處理流程都一樣。

HBase Meta 元資訊表修複實踐

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

HBase Meta 元資訊表修複實踐

另外一種重疊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問題複現原理:

HBase Meta 元資訊表修複實踐

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           
HBase Meta 元資訊表修複實踐

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,成功複現重疊問題

HBase Meta 元資訊表修複實踐

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

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

HBase Meta 元資訊表修複實踐

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 Meta 元資訊表修複實踐

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表的資料正确性對于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表)。

參考文章:

  • Apache HBase ™ Reference Guide
  • Apache HBase HBCK2 Tool
  • Appendix C: hbck In Depth

作者:vivo 網際網路大資料團隊 - Huang Guihu、Chen Shengzun

來源-微信公衆号:vivo網際網路技術

出處:https://mp.weixin.qq.com/s/KBp5FFI5ylDRiKsHYJTN7w