HBase中-ROOT-和.META.表結(jié)構(gòu)(Region定位原理)

#在HBase中,大部分的操作都是在RegionServer完成的,Client端想要插入,刪除,查詢數(shù)據(jù)都需要先找到相應(yīng)的RegionServer。什么叫相應(yīng)的RegionServer?就是管理你要操作的那個(gè)Region的RegionServer。Client本身并不知道哪個(gè)RegionServer管理哪個(gè)Region,那么它是如何找到相應(yīng)的RegionServer的?本文就是在研究源碼的基礎(chǔ)上揭秘這個(gè)過程。

#在此基礎(chǔ)上我們引入兩個(gè)特殊的概念:-ROOT-和.META.。這是什么?它們是HBase的兩張內(nèi)置表,從存儲(chǔ)結(jié)構(gòu)和操作方法的角度來說,它們和其他HBase的表沒有任何區(qū)別,你可以認(rèn)為這就是兩張普通的表,對(duì)于普通表的操作對(duì)它們都適用。它們與眾不同的地方是HBase用它們來存貯一個(gè)重要的系統(tǒng)信息——Region的分布情況以及每個(gè)Region的詳細(xì)信息。

#好了,既然我們前面說到-ROOT-.META.可以被看作是兩張普通的表,那么它們和其他表一樣就應(yīng)該有自己的表結(jié)構(gòu)。沒錯(cuò),它們有自己的表結(jié)構(gòu),并且-ROOT-.META.這兩張表的表結(jié)構(gòu)是相同的,在分析源碼之后我將這個(gè)表結(jié)構(gòu)大致的畫了出來:

-ROOT-和.META.表結(jié)構(gòu)示例參考

我們來仔細(xì)分析一下這個(gè)結(jié)構(gòu),每條Row記錄了一個(gè)Region的信息。

首先是RowKey,RowKey由三部分組成:TableName, StartKey 和 TimeStamp。
RowKey存儲(chǔ)的內(nèi)容我們又稱之為Region的Name。哦,還記得嗎?我們?cè)谇懊娴奈恼轮刑岬降?,用來存放Region的文件夾的名字是RegionName的Hash值,因?yàn)镽egionName可能包含某些非法字符。現(xiàn)在你應(yīng)該知道為什么RegionName會(huì)包含非法字符了吧,因?yàn)镾tartKey是被允許包含任何值的。將組成RowKey的三個(gè)部分用逗號(hào)連接就構(gòu)成了整個(gè)RowKey,這里TimeStamp使用十進(jìn)制的數(shù)字字符串來表示的。

這里有一個(gè)RowKey的例子:?

Table1,RK10000,12345678

然后是表中最主要的Family:info,info里面包含三個(gè)Column:regioninfo, server, serverstartcode。其中regioninfo就是Region的詳細(xì)信息,包括StartKey, EndKey 以及每個(gè)Family的信息等等。server存儲(chǔ)的就是管理這個(gè)Region的RegionServer的地址。

所以當(dāng)Region被拆分、合并或者重新分配的時(shí)候,都需要來修改這張表的內(nèi)容。

到目前為止我們已經(jīng)學(xué)習(xí)了必須的背景知識(shí),下面我們要正式開始介紹Client端尋找RegionServer的整個(gè)過程。我打算用一個(gè)假想的例子來學(xué)習(xí)這個(gè)過程,因此我先構(gòu)建了假想的-ROOT-表和.META.表。

我們先來看.META.表,假設(shè)HBase中只有兩張用戶表:Table1和Table2,Table1非常大,被劃分成了很多Region,因此在.META.表中有很多條Row用來記錄這些Region。而Table2很小,只是被劃分成了兩個(gè)Region,因此在.META.中只有兩條Row用來記錄。這個(gè)表的內(nèi)容看上去是這個(gè)樣子的:?

.META.行記錄結(jié)構(gòu)示例參考

現(xiàn)在假設(shè)我們要從Table2里面插尋一條RowKey是RK10000的數(shù)據(jù)。那么我們應(yīng)該遵循以下步驟:

1. 從.META.表里面查詢哪個(gè)Region包含這條數(shù)據(jù)。
2. 獲取管理這個(gè)Region的RegionServer地址。
3. 連接這個(gè)RegionServer, 查到這條數(shù)據(jù)。

好,我們先來第一步。問題是.META.也是一張普通的表,我們需要先知道哪個(gè)RegionServer管理了.META.表,怎么辦?有一個(gè)方法,我們把管理.META.表的RegionServer的地址放到ZooKeeper上面不久行了,這樣大家都知道了誰在管理.META.。

貌似問題解決了,但對(duì)于這個(gè)例子我們遇到了一個(gè)新問題。因?yàn)門able1實(shí)在太大了,它的Region實(shí)在太多了,.META.為了存儲(chǔ)這些Region信息,花費(fèi)了大量的空間,自己也需要?jiǎng)澐殖啥鄠€(gè)Region。這就意味著可能有多個(gè)RegionServer在管理.META.。怎么辦?在ZooKeeper里面存儲(chǔ)所有管理.META.的RegionServer地址讓Client自己去遍歷?HBase并不是這么做的。

HBase的做法是用另外一個(gè)表來記錄.META.的Region信息,就和.META.記錄用戶表的Region信息一模一樣。這個(gè)表就是-ROOT-表。這也解釋了為什么-ROOT-和.META.擁有相同的表結(jié)構(gòu),因?yàn)樗麄兊脑硎且荒R粯拥摹?/p>

假設(shè).META.表被分成了兩個(gè)Region,那么-ROOT-的內(nèi)容看上去大概是這個(gè)樣子的:

-ROOT-行記錄結(jié)構(gòu)示例參考

這么一來Client端就需要先去訪問-ROOT-表。所以需要知道管理-ROOT-表的RegionServer的地址。這個(gè)地址被存在ZooKeeper中。默認(rèn)的路徑是:?

/hbase/root-region-server??

等等,如果-ROOT-表太大了,要被分成多個(gè)Region怎么辦?嘿嘿,HBase認(rèn)為-ROOT-表不會(huì)大到那個(gè)程度,因此-ROOT-只會(huì)有一個(gè)Region,這個(gè)Region的信息也是被存在HBase內(nèi)部的。?

現(xiàn)在讓我們從頭來過,我們要查詢Table2中RowKey是RK10000的數(shù)據(jù)。整個(gè)路由過程的主要代碼在org.apache.hadoop.hbase.client.HConnectionManager.TableServers中:

privateHRegionLocation?locateRegion(finalbyte[]?tableName, finalbyte[]?row,booleanuseCache)throwsIOException?{

if(tableName?==null ||?tableName.length?==0)?{

? thrownewIllegalArgumentException("table?name?cannot?be?null?or?zero?length");

}??

if(Bytes.equals(tableName,?ROOT_TABLE_NAME))?{

synchronized(rootRegionLock)?{

//?This?block?guards?against?two?threads?trying?to?find?the?root

//?region?at?the?same?time.?One?will?go?do?the?find?while?the

//?second?waits.?The?second?thread?will?not?do?find.

if(!useCache?||?rootRegionLocation?==null)?{

this.rootRegionLocation?=?locateRootRegion();

}??

returnthis.rootRegionLocation;

}??

}elseif(Bytes.equals(tableName,?META_TABLE_NAME))?{

returnlocateRegionInMeta(ROOT_TABLE_NAME,?tableName,?row,?useCache,?metaRegionLock);

}else{

//?Region?not?in?the?cache?–?have?to?go?to?the?meta?RS

returnlocateRegionInMeta(META_TABLE_NAME,?tableName,?row,?useCache,?userRegionLock);

????}??

}??

?這是一個(gè)遞歸調(diào)用的過程:?

#

獲取Table2,RowKey為RK10000的RegionServer?=>?獲取.META.,RowKey為Table2,RK10000,99999999999999的RegionServer?=>?獲取-ROOT-,RowKey為.META.,Table2,RK10000,99999999999999,99999999999999的RegionServer?=>?獲取-ROOT-的RegionServer?=>?從ZooKeeper得到-ROOT-的RegionServer?=>?從-ROOT-表中查到RowKey最接近(小于)?.META.,Table2,RK10000,99999999999999,99999999999999的一條Row,并得到.META.的RegionServer?=>?從.META.表中查到RowKey最接近(小于)Table2,RK10000,99999999999999的一條Row,并得到Table2的RegionServer?=>?從Table2中查到RK10000的Row

到此為止Client完成了路由RegionServer的整個(gè)過程,在整個(gè)過程中使用了添加“99999999999999”后綴并查找最接近(小于)RowKey的方法。對(duì)于這個(gè)方法大家可以仔細(xì)揣摩一下,并不是很難理解。

#最后要提醒大家注意兩件事情:

1. 在整個(gè)路由過程中并沒有涉及到MasterServer,也就是說HBase日常的數(shù)據(jù)操作并不需要MasterServer,不會(huì)造成MasterServer的負(fù)擔(dān)。

2. Client端并不會(huì)每次數(shù)據(jù)操作都做這整個(gè)路由過程,很多數(shù)據(jù)都會(huì)被Cache起來。至于如何Cache,則不在本文的討論范圍之內(nèi)。

#

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最近在逐步跟進(jìn)Hbase的相關(guān)工作,由于之前對(duì)Hbase并不怎么了解,因此系統(tǒng)地學(xué)習(xí)了下Hbase,為了加深對(duì)Hb...
    飛鴻無痕閱讀 50,581評(píng)論 19 272
  • 簡(jiǎn)介 HBase是高可靠性,高性能,面向列,可伸縮的分布式存儲(chǔ)系統(tǒng),利用HBase技術(shù)可在廉價(jià)PC Serve...
    九世的貓閱讀 2,376評(píng)論 1 6
  • 參考:http://www.itdecent.cn/p/569106a3008f 最近在逐步跟進(jìn)Hbase的相關(guān)...
    博弈史密斯閱讀 929評(píng)論 1 1
  • 本文首先簡(jiǎn)單介紹了HBase,然后重點(diǎn)講述了HBase的高并發(fā)和實(shí)時(shí)處理數(shù)據(jù) 、HBase數(shù)據(jù)模型、HBase物理...
    達(dá)微閱讀 2,839評(píng)論 1 13
  • 比特科技: 存儲(chǔ)、數(shù)據(jù)庫、大數(shù)據(jù)技術(shù) ? HBase原理和設(shè)計(jì) http://www.bitstech.net/...
    葡萄喃喃囈語閱讀 764評(píng)論 0 11

友情鏈接更多精彩內(nèi)容