HBase 運維|HBase Region 重疊問題處理

最近某應用反饋 HBase 數據插入數據後、查詢出現錯誤數據

現象如下:

有一行數據:

前面時間 T1 :插入3列

後面時間 T2 :插入1 列(通過 put 新值來更新某列數據)

scan 操作只能看到 時間點T1的 3 列數據,

get 操作只能看到時間點 T2 的 1 列最新數據

具體例子:

有一行數據 rowkey 是 591420001

時間點T1:插入數據c1-c3 共3列,注意此時 c2=2

ROW                                 COLUMN+CELL
5914200010001 column=f:c1, timestamp=1595252551656, value=1
5914200010001 column=f:c2, timestamp=1595252551656, value=2
5914200010001 column=f:c3, timestamp=1595252551656, value=3


時間點T2 插入c2值爲 2-1:

 ROW                                 COLUMN+CELL
5914200010001 column=f:c2, timestamp=1595252559734, value=2-1


正確的 scan 或者 get 應該是:

ROW                                 COLUMN+CELL
5914200010001 column=f:c1, timestamp=1595252551656, value=1
5914200010001 column=f:c2, timestamp=1595252559734, value=2-1
5914200010001 column=f:c3, timestamp=1595252551656, value=3


實際情況 scan 出來的結果:

 5914200010001                          column=f:c1, timestamp=1595252551656, value=1
5914200010001 column=f:c2, timestamp=1595252559734, value=2
5914200010001 column=f:c3, timestamp=1595252551656, value=3


get 出來的結果是:

5914200010001            column=f:c2, timestamp=1595252559734value=2-1


詳細瞭解以及現象:

剛開始懷疑會不會是使用問題,應用查詢的時候,指定了版本;後來詢問了是否設置了多版本之類的情況,答案是沒有。經過溝通詢問,發現有些 rowkey 的數據是有問題,有些是正常的,這是一個非常重要的信息,也就是說異常的Case只會發生在某些行數據中。

由此信息懷疑問題是否和 rowkey 分佈的 Region 有關係,

根據對 HBase 的瞭解,大概猜測出了 Region 很可能發生了重疊的情況。

Region 重疊

Region 重疊,英文叫做 region overlap,意思是region 範圍發生了交叉,

正常region

 ~10 10~2020~3030~40 40~


重疊region

 ~10 10~2015~25 20~3030~40 40~


如上 10~20,15~25,20~30 就發生了重疊

空洞 region

region 還有一個常見的問題,叫做 region 空洞 hole

 ~10 10~2030~40 40~


如上 20~30 就區間沒有了,也就是發生了所謂的 hole

region 空洞通常是 region 沒有 assign 成功導致

時間點 T1 的數據插入的數據從 hbase:meta 表中找到 regionA

時間點 T2 的數據插入的數據從 hbase:meta 表中找到 regionB

5914200010001 這個 rowkey 同時屬於 regionA 和 RegionB 

檢查集羣,果然驗證了自己的猜測


上圖可以看到使用紅線框起來的這個 region 是有問題的,

剛開始的時候,時間點 T1 插入數據到了正常的 region 中,

時間點 T2,插入數據,正好到5192-5294 這個異常的 region 中去了。

所以導致 scan 和 get 結果不一致。

這個異常的 Region 怎麼來的?應用懷疑是 HBase split 出現異常導致的,真的是 HBase 自己 split 出來的嗎?答案是否定的。

表是預先分區的,指定的每個 splitkey 都爲 7位長度(比如4750000,4800000),

rowkey 設計上面確保是 13 位長度,異常的 region 的 startkey/endkey 只有 4 位長度, 基本上可以排除 split 出來的可能性.

因爲region的startkey 要不是預先分區指定的值,要不是 split 時候取的 splitPonit 值(也就是 region下面列族中最大的 hfile midkey) ,所以幾乎不可能是 split 異常導致的

當時有個大膽的推測,會不會是這個 region 是誰拷貝了一個其它表或者之前的表的 region 目錄,放在表目錄下,然後一頓操作猛如虎,把這個給上線了。。。

後來 check 了 NameNode 的審計日誌,果然發現是被人拷貝過來的。。。

通過觀察這個 region 的 .regioninfo 信息,發現這個region 是數個月之前的,後來被人爲拷貝過來的, 具體爲啥拷貝就不細說了。。。

這個 case 非常有意思, 會涉及到 HBase 的 hbck工具,hfile工具,如何查看 master 頁面,hbase:meta 元數據信息,hbase 表的目錄結構等等信息

明白了問題的現象和原因以後,我們來處理這個問題呢?

處理思路:

儘快恢復業務!

下線錯誤 region -> 修復 hbase:meta -> move  region 目錄 -> 恢復數據

這個問題非常考驗對 HBase 的理解以及工具的使用。

1、unassign region :下線 region

2、move region 目錄,將出問題的 region 拷貝走

(這個目錄中的數據後續可能還需要導入)

3、scan 'hbase:meta' 找到出問題的 region 信息,從 hbase:meta 中刪除

(小心操作)

4、導入數據 使用 dobulkload 將出問題的 region hfile 重新導入進去

因爲錯誤的region 是被拷貝過來的,需要研究一下這個錯誤的 region 當時拷貝過來的時候,是否含有 hfile,也就是舊的數據;一般來說舊數據按理說我們是不需要,我們需要的是拷貝過來的錯誤的 region 上線後面又寫入的這部分數據,

這部分數據雖然寫到了錯誤的 region,但確實是需要的數據。

這塊的處理邏輯是需要推斷,稍微判斷失誤,就可能會丟數據,或者導入不該導入的數據進來。

首先使用 hbase hfile 工具,來檢查一下這個錯誤的 region 下面的 hfile 的信息,

可能會使用到如下命令:

查看某個hfile 基本信息,比如startkey/endkey/midkey,又多少key,最大,最小,平均長度,時間戳等等
$ hbase hfile -f hfile_path -s 打印kv$ hbase hfile -f hfile_path -p打印key$ hbase hfile -f hfile_path -e

本案例中從這些 hfile 中打印出來的信息,可以發現 hfile 中的數據都是後寫入的,根據 rowkey 信息(內含時間戳)以及 KV 的 timestamp 字段來判斷。到此 HBase 其實已經可以正常讀寫了。不過 此時 hbase 的 hmaster 中還有髒數據,比如頁面中還會顯示這個錯誤的 region

5、根據需要決定是否重啓 HMaster,清理 HMaster 內存中的髒數據

如上是大概的推測:是否可以解決問題?線上環境還是需要非常謹慎的。

製造 Region overlap/ 復現問題

首先我們來”製造”一個類似的問題,也就是生成一個錯誤的region,製造region overlap(當時環境使用的是2.x 的某個早期版本,hbck2 還不完善),復現問題:

1) 首先創建一個表

create 'test','f'SPLITS => ['05''15''25']

2) 然後將這個表目錄拷貝出來

假設拷貝到 /tmp/xxx/test

3) 刪除表

disbale 'test'drop 'test'

4)重新創建表(不同splitkeys)

create 'test''f'SPLITS => ['10''20''30']

5)然後選取上一次建表的region目錄拷貝到新表目錄中

比如:

hdfs dfs -cp /tmp/xxx/test/4f3cab0063decfac00755c88337da380 /apps/hbase/data/data/default/test/


6)上線有問題的 region

執行命令

 hbase hbck -j $hbase_home/hbase-operator-tools/hbase-hbck***.jar addFsRegionsMissingInMeta default:test


如上命令的意思是根據 hdfs 中的 region 目錄等信息加載到 hbase:meta 表中

7)重啓 hmaster

8)上線這個有問題的 reigon

hbase hbck -j  $hbase_home/hbase-operator-tools//hbase-hbck***.jar assigns 4f3cab0063decfac00755c88337da380


查看 hmaster 界面,就可以成功看到 ` region overlap` 重疊的情況了

然後 scan hbase:meta 就可以成功看到 這個錯誤的 region 信息也存在 hbase:meta 中了,此時就成功復現了 region overlap

**解決流程 **

  1. 下線錯誤region:進入 hbase shell  對出問題的 region執行 unassign 'regionanme'

2.移動錯誤 region 目錄,

例如移動到 hdfs://ns1/tmp/下新建一個目錄放進去

HBase 目錄結構如下

/apps/hbase/data/data/default/test/regionname/f/hfile

data 表目錄

default:命名空間

test:表名

regionname:region目錄

region 目錄下面有.regioninfo

f:列族目錄

hfile: 爲 hfile 文件

  1. scan 'hbase:meta',{STARTROW => 'tablename,591420001000',LIMIT => 100} ,這裏row填有問題的前面的row,

可能提示遮擋問題有問題,可以追加到文件裏,從文件裏複製

命令:echo “scan ‘hbase:meta’,{STARTROW => ‘tablename,591420001000’,LIMIT => 100}” hbase shell > hbase.txt

4.deleteall 'hbase:meta','tablename,rowkey.有問題的 region.’

示例命令:deleteall 'hbase:meta','test,5192,1578035374274. *****6bdd9b41aefefd0f89c.'

hbase:meta 表中髒數據清理以後客戶端讀寫就獲取不到錯誤 region 了

5.數據導入

hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles "/tmp/ hbase-loaddata /******89c/ " "t"


示例命令: 

hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles " /tmp/hbase-loaddata/*****6bdd9b41aefefd0f89c " "test"

6、重啓 `hmaster

最後問題得以解決。

這個問題,需要對 unassignhbckregion 如何上下線,hbase 表目錄結構,hfile 工具,dobulkload 工具,.regioninfohbase:meta 等工具鏈

HBase 元數據原理和上下線、讀寫流程等都需要有一定的瞭解。


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

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