問題背景
同一份測試樣本,同一天的不同時間段查詢HBase表,
命中結果不一致。對比分析兩份樣本結果差異,發現樣本2的結果是樣本1的子集,樣本1多出42條結果,且都是key 「1b」 開頭
後續多次測試均無法得到樣本1的結果,也就是說「數據憑空少了」。
接口問題排查
程序中通過調用後端提供的服務接口進行數據查詢,接口日誌中 返回結果為空List,無異常。
登錄hbase shell手動進行scan查詢:
scan 'ns:table_express',{STARTROW=>'1b3e9f822f33977ceefedaa88db41bbd22c2f8845d59ac3d6203b9601dd7669b0000000000000000000000000000000000000000',ENDROW=>'1b3e9f822f33977ceefedaa88db41bbd22c2f8845d59ac3d6203b9601dd7669bfffffffffffffffffffffffffffffffffffffffff'}
報錯如下:
ERROR: org.apache.hadoop.hbase.NotServingRegionException ns:table_express,1b37fe2afa75581bf5f757449491783878.d4a172571b229e74109df6c03a959588 is not online on node85-47,16020,1547732390682
at org.apache.hadoop.hbase.regionserver.HRegionServer.getRegionByEncodedName(HRegionSer.java:3245
at org.apache.hadoop.hbase.regionserver.HRegionServer.getRegion(HRegionServ.java:3222)
at org.apache.hadoop.hbase.regionserver.RSRpcServices.getRegion(RSRpcService.java:1414)
at org.apache.hadoop.hbase.reg ionserver RSRpcServices.newReg ionScanner(RSRpcServices.java 2947)
at org.apache.hadoop.hbase.regionserver.RSRpcServices.scan(RSRpcServices.java:3272) I
at org.apache.hadoop.hbase.shaded.protobuf.generated ClientProtos$ClientServices callBlockingMethod(ClientProto
at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:413)
at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:130)
at org.apache.hadoop.hbase.ipc RpcExecutor$Handler.run(RpcExecutor.java:324)
at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:304)
重複測試其他異常數據均得到 NotServingRegionException 異常,但是其他不在異常範圍內的key 可以正常查詢。
結論:
- 1b開頭的這些數據所在的region 「不在服務區」。
- 接口沒有返回具體的異常信息,而是返回空,一定程度上會影響判斷。
Region問題排查
表狀態檢查:
hbase hbck -summary ns:table_express
結果如下:
19/09/19 09:53:10 WARN util.HBaseFsck: No HDFS region dir found: { meta => ns:table_express,1b1e73ed71329daa72ffb28f42947ee7d40c9cb7872063682cb511fd16dbbfd1201810277ccbfc2577361956656a23f805afb859,1549491783878.1513a155f24ac2df20b4797077ed6ae0., hdfs => null, deployed => , replicaId => 0 } meta={ENCODED => 1513a155f24ac2df20b4797077ed6ae0, NAME => 'ns:table_express,1b1e73ed71329daa72ffb28f42947ee7d40c9cb7872063682cb511fd16dbbfd1201810277ccbfc2577361956656a23f805afb859,1549491783878.1513a155f24ac2df20b4797077ed6ae0.', STARTKEY => '1b1e73ed71329daa72ffb28f42947ee7d40c9cb7872063682cb511fd16dbbfd1201810277ccbfc2577361956656a23f805afb859', ENDKEY => '1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae'}
19/09/19 09:53:10 WARN util.HBaseFsck: No HDFS region dir found: { meta => ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588., hdfs => null, deployed => , replicaId => 0 } meta={ENCODED => d4a172571b229e74109df6c03a959588, NAME => 'ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.', STARTKEY => '1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae', ENDKEY => '1b50b073e140ffd3bdb3d9eca2bd7a1db27eb757a06dee480f2ebd537ca0f44d201812187ab3f7d880e20053ee071eab7d0d5360'}
2 inconsistencies detected.
Status: INCONSISTENT
檢測到2個不一致信息。
此外,在hbase web ui中,該表的region塊存在 所有數值都為0的異常情況:
可以確認是該表的region數據發生異常,且日誌中異常的region信息如下:
- ns:table_express,1b1e73ed71329daa72ffb28f42947ee7d40c9cb7872063682cb511fd16dbbfd1201810277ccbfc2577361956656a23f805afb859,1549491783878.1513a155f24ac2df20b4797077ed6ae0.
- ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.
此信息為 hbase:meta 表中的rowkey,根據meta表rowkey的組成規則,取rowkey中最後一段的encode編碼信息,到hdfs上驗證該region數據目錄是否存在:
hadoop fs -ls /hbase/data/ns/table_express/1513a155f24ac2df20b4797077ed6ae0
ls: `/hbase/data/ns/table_express/1513a155f24ac2df20b4797077ed6ae0`: No such file or directory
可以看到,該region在hdfs上對應的數據目錄消失了。
進入 hbase shell 中查詢meta表異常rowkey對應的值:
get 'hbase:meta','ns:table_express,1b1e73ed71329daa72ffb28f42947ee7d40c9cb7872063682cb511fd16dbbfd1201810277ccbfc2577361956656a23f805afb859,1549491783878.1513a155f24ac2df20b4797077ed6ae0.'
# 結果如下:
info:regioninfo timestamp=1566891946444, value={ENCODED => 96dd94004c9dd9fce3f4eb80c885ad85, NAME => 'ns:table_express,0778ba8d2889fe7343ffc120c4ae83da0778ba8d2889fe7343ffc120c4ae83da,1559425462970.96dd94004c9dd9fce3f4eb80c885ad85.', STARTKEY => '0778ba8d2889fe7343ffc120c4ae83da0778ba8d2889fe7343ffc120c4ae83da', ENDKEY => '0857
87e9323caa99fc45325a351797fdd4849891167b36bfc6241197b5a58cb1201802142fd6fdc3bf0b5b9cb8faf80d04b71d1a'}
info:seqnumDuringOpen timestamp=1566891946444, value=\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x02'
info:server timestamp=1566891946444, value=node85-104:16020
info:serverstartcode timestamp=1566891946444, value=1563956428836
info:sn timestamp=1566891945886, value=node85-104,16020,1563956428836
info:state timestamp=1566891946444, value=OPEN
元數據信息正常,至此,可以確認問題原因:
元數據顯示該region在正常提供服務中,客戶端到具體節點上檢索數據時發現該region的數據目錄不存在,拋出異常。
附:meta表結構
hbase:meta表結構如下:
- rowkey:${表名},${起始鍵},${region時間戳}.${encode編碼}.
- info:state:Region狀態,正常情況下為 OPEN
- info:serverstartcode:RegionServer啟動的13位時間戳
- info:server:所在RegionServer 地址和端口,如node85-47:16020
- info:snserver:和serverstartcode組成,如node85-47:16020,1549491783878
- info:seqnumDuringOpen:Region在線時長的二進制串
- info:regioninfo:region的詳細信息,如:ENCODED、NAME、STARTKEY、ENDKEY等
其中,regioninfo是重要信息:
- ENCODED:基於${表名},${起始鍵},${region時間戳}生成的32位md5字符串,region數據存儲在hdfs上時使用的唯一編號,可以從meta表中根據該值定位到hdfs中的具體路徑。 rowkey中最後的${encode編碼}就是 ENCODED 的值,其是rowkey組成的一部分。
- NAME:與ROWKEY值相同
- STARTKEY:該region的起始鍵
- ENDKEY:該region的結束鍵
修復過程
使用元數據修復工具
嘗試直接使用命令修復:
hbase hbck -repair ns:table_express
hbase hbck -fixMeta
執行失敗:HBase 2.0 中已經不支持元數據修復工具,只支持「查看」類型的操作,不支持「讀入」類型的操作。
使用hdfs工具檢查是否有文件塊異常:
hdfs fsck /hbase
# 結果正常
手動修復元數據
備份原有的region信息:
get 'hbase:meta','ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.'
# 備份數據
# 刪除該region信息
delete 'hbase:meta','ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.','info:regioninfo'
delete 'hbase:meta','ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.','info:server'
delete 'hbase:meta','ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.','info:serverstartcode'
delete 'hbase:meta','ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.','info:sn'
delete 'hbase:meta','ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.','info:state'
delete 'hbase:meta','ns:table_express,1b37fe2afa75581bf5f7574336f1cdfbf0f902966db54bf38aa505665828929020181207edad0e69052f705b07331e32c00b5aae,1549491783878.d4a172571b229e74109df6c03a959588.','info:seqnumDuringOpen'
刷新hbase web ui頁面,發現 d4a172571b229e74109df6c03a959588 region 已經消失。
執行hbck -summary 發現 不一致的部分由2變成了1。
嘗試:
- hbase shell中手動scan
- 通過接口重新查詢該值
可以成功獲得結果。
繼續刪除 1513a155f24ac2df20b4797077ed6ae0 region塊對應的meta數據後,重新測試數據樣本,可得到正確的結果。
問題分析
- d4a172571b229e74109df6c03a959588
- 1513a155f24ac2df20b4797077ed6ae0
以上兩個reigon在split時,子region的數據塊已經並在meta表中更新上線提供正常服務,父region的數據塊已刪除,但是 meta表中沒有更新對應的元數據信息(原因仍待排查)。
導致對應的數據查詢時,仍然通過父region檢索數據,但是父region的數據已被刪除,故無法成功檢索。
可以通過以下命令列出該表在meta表中所有的region信息,分析排查是否有相關的region範圍 覆蓋了有問題的region數據:
echo "scan 'hbase:meta',{FILTER => org.apache.hadoop.hbase.filter.PrefixFilter.new(org.apache.hadoop.hbase.util.Bytes.toBytes('ns:table_express'))}" | hbase shell | awk -F ' ' '{print $1}' | grep table_express | grep -v bak | sort | uniq
來判斷消失的region塊是否已經由其他region託管服務。
NotServingRegionException 大概率是Region轉換過程中出現了問題,通過 hbase:meta 表 和其中記錄的region信息可以幫助我們定位問題所在,所以掌握meta表結構和相關存儲規則是一個很有效的工具。
閱讀更多 跳刀跳刀 的文章