下面看下hbase:meta 表的結構,hbase:meta表中,保存了每個表的region地址,還有一些其他信息,例如region的名字,HRegionInfo,服務器的信息。hbase:meta表中每一行對應一個單一的region。例如我們現在創建一個表名叫"t"。hbase:meta中對應的行會像下面這個樣子。
Row |
Column Family |
Column Qualifier |
Value |
t,,1351700811858 |
info |
regioninfo |
NAME => |
server |
10.7.73.121:64782 |
||
serverstartcode |
1351986939360 |
具體含義:
rowKey:([table],[region start key],[region id]),
- rowkey中第一個分隔符前存的是表名;
- 第二分隔符前存的是region的第一個rowKey,這里兩個需要注意,1.如果這個地方為空的話,表明這是table的第一個region。並且如果一個region中startkey和endkey都為空的為,表明這個table只有一個region。2.在mata表中,startkey 靠前的region會排在startkey 靠后的region前面。(Hbase中的keys是按照字段順序來排序的)
- region id就是region的id,通常來說就是region創建的時候的timestamp
- regioninfo 是HRegionInfo的序列化值。
- server是指服務器的地址和端口
- serverstartcode 是服務開始的時候的timestamp
根據meta表查找key對應的region
當有一個key需要做put操作的時候,會先掃描meta表,找到對應region,然后進行插入操作。
例如:有一個table具有三個region,每個region的startkey分別是 空,bar,foo,如下圖:
1 table,,1351700811858 2 table,bar,1351700819876 3 table,foo,1351700829874
如果我們需要插入key ‘baz’ ,我們能找meta表中對應的rowkey為(table,bar,1351700819876)。
這個查找完之后會緩存在客戶端,下次查詢的時候會根據緩存來直接去訪問region。
自動split
當不斷的往一個table增加數據的時候,最終region會分裂。這樣hbase就能保證可以橫向的增長了。一個parent region會split兩個child region。
在child regions 上線之前我們需要做兩件事:
- 下線parent region
- 把child regions的相關信息增加到parent info中
首先是更新meta表中parent region的info:regioninfo列的值,然后增加兩列info:splitA(top child 的HRegionInfo,這里約定top為startkey較小的HReginInfo,bottom則反),和info:splitB(bottom child 的HRegionInfo)。這個操作能保證我們能跟蹤到region到底做了寫什么,方便后續的操作,以及后續如果操作被迫終端了,也有個憑證,能夠根據這些來恢復。最后parent region會被CatalogJanitor清理掉。
更新meta表
在更新完meta表中parent region的記錄的時候,就需要把child region相關插入到meta表中,top child region 的startkey 和paretn的startkey 是一樣的,這個時候regionId就發揮他的作用了,如果沒有regionId,當meta表中有top region和parent region的時候,我們就知道需要選擇哪個了,因為他們的startkey都一樣。而我們使用timestamp作為region的id(如果top region和parent region的timestamp一樣的時候,top的region id 取timestamp+1)。這樣我們就能保證child region總是排在parent region之后。
還有一個比較重要的就是,bottom child必須要先插入到meta表,然后top child才能插入。否則就會出現,在meta表中,bottom region里面的key找到不到對應的region的情況。舉個例子還是以上面的例子為基礎 meta中rowkey為(table,bar,1351700819876)的region分裂成兩個region的meta rowkey分別是(table,bar,1351700819810)和(table,belong,1351700819810),如果這個時候先插入top child:
1 table,,1351700811858 2 table,bar,1351700819876 <---- offline! 3 table,bar,1351700819810 <---- top child 4 table,foo,1351700829874
例如這個時候我需要找key為bgood,我最終會找到這里的第三行top region里面,但是top region里面並不包含bgood。bgood這個這個key是在bottom region里面的。如果先加入bottom就沒有這個問題,如下
table,,1351700811858 table,bar,1351700819876 <---- offline! table,belong,1351700819810 <---- bottom child table,foo,1351700829874
出錯恢復
一般來說,Hbase可以很好的恢復服務器錯誤,但是有時候還是會出問題的,如果在slipt的時候,regionserver出錯了,或者因為其他原因導致slipt整個周期只執行了一部分。這個時候meta表可能會出錯,例如有出錯的region在磁盤上面,或者重復的regions等。這個時候我們可以使用hbck工具來進行修復。使用以下命令查看更多hbck的信息:
/hbase/bin/hbase hbck -h
參考:
https://blog.safaribooksonline.com/2012/11/16/tip-2-hbase-meta-layout/ hbase:meta表