最近某應用反饋 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=1595252559734, value=2-1
詳細瞭解以及現象:
剛開始懷疑會不會是使用問題,應用查詢的時候,指定了版本;後來詢問了是否設置了多版本之類的情況,答案是沒有。經過溝通詢問,發現有些 rowkey
的數據是有問題,有些是正常的,這是一個非常重要的信息,也就是說異常的Case只會發生在某些行數據中。
由此信息懷疑問題是否和 rowkey
分佈的 Region
有關係,
根據對 HBase
的瞭解,大概猜測出了 Region
很可能發生了重疊的情況。
Region 重疊
Region 重疊,英文叫做 region overlap,意思是region 範圍發生了交叉,
正常region
~10
10~20
20~30
30~40
40~
重疊region
~10
10~20
15~25
20~30
30~40
40~
如上 10~20,15~25,20~30 就發生了重疊
空洞 region
region
還有一個常見的問題,叫做 region
空洞 hole
~10
10~20
30~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
**解決流程 **
下線錯誤
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 文件
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
最後問題得以解決。
這個問題,需要對 unassign
、hbck
、region
如何上下線,hbase
表目錄結構,hfile
工具,dobulkload
工具,.regioninfo
、hbase:meta
等工具鏈
HBase 元數據原理和上下線、讀寫流程等都需要有一定的瞭解。
本文分享自微信公衆號 - HBase工作筆記(HBase-Notes)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。