免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
HBase存儲(chǔ)架構(gòu)

HBase存儲(chǔ)架構(gòu)

1070人閱讀評論(1)收藏舉報(bào)

 

英文原文:http://www.larsgeorge.com/2009/10/hbase-architecture-101-storage.html

 

HBase最隱秘的問題之一就是它的數(shù)據(jù)是如何存儲(chǔ)的。雖然大多數(shù)用戶都不會(huì)因?yàn)檫@個(gè)問題向你抱怨,但是如果你想學(xué)習(xí)哪些高級的配置選項(xiàng)并了解它們的意思,你可能就需要來了解一下這個(gè)存儲(chǔ)問題了。“怎樣才能把HBase調(diào)整到最適合我需求的狀態(tài)?”你可能對于這樣一系列類似的問題非常感興趣。那么你就需要繞過這些問題來學(xué)習(xí)HBase的基礎(chǔ)知識(shí)。另一個(gè)支持你學(xué)習(xí)這些基礎(chǔ)知識(shí)的理由是有時(shí)候各種各樣你想不到的災(zāi)難需要你恢復(fù)整個(gè)HBase。

我首先學(xué)習(xí)了HBase中控制各種不同文件的獨(dú)立的類,然后根據(jù)我對整個(gè)HBase存儲(chǔ)系統(tǒng)的理解在腦海中構(gòu)建HBase架構(gòu)的圖像。但是我發(fā)現(xiàn)想要在頭腦中構(gòu)建出一幅連貫的HBase架構(gòu)圖片很困難,于是我就把它畫了出來。

你可能注意到了這不是一個(gè)UML圖或者調(diào)用圖。這個(gè)圖混合了類和他們管理控制的文件,將注意力集中到了本文要討論的主題上。后面我將會(huì)討論這張圖所涉及到的細(xì)節(jié),包括一些配置文件項(xiàng)是如何影響底層的文件存儲(chǔ)系統(tǒng)的。

好,我們現(xiàn)在來分析這張圖里面到底包含了什么。首先HBase操控兩種基本類型的文件,一種用于存儲(chǔ)WALlog,另一種用于存儲(chǔ)具體的數(shù)據(jù)。這兩種文件主要由HRegionServer來管理,但是在有的情況下HMaster會(huì)跳過HRegionServer,直接操作這兩種文件。你可能注意到了,這些文件都被存儲(chǔ)在HDFS上面,并且每個(gè)文件包含了多個(gè)數(shù)據(jù)塊。配置文件中就有一個(gè)選項(xiàng)用來調(diào)整系統(tǒng)控制數(shù)據(jù)的大小。我們后面會(huì)詳細(xì)討論這個(gè)問題。

接下來看一下數(shù)據(jù)的大致流程。假設(shè)你需要通過某個(gè)特定的RowKey查詢一行記錄,首先Client端會(huì)連接Zookeeper Qurom,通過ZookeeperClient能獲知哪個(gè)Server管理-ROOT- Region。接著Client訪問管理-ROOT-Server,進(jìn)而獲知哪個(gè)Server管理.META.表。這兩個(gè)信息Client只會(huì)獲取一次并緩存起來。在后續(xù)的操作中Client會(huì)直接訪問管理.META.表的Server,并獲取Region分布的信息。一旦Client獲取了這一行的位置信息,比如這一行屬于哪個(gè)Region,Client將會(huì)緩存這個(gè)信息并直接訪問HRegionServer。久而久之Client緩存的信息漸漸增多,即使不訪問.META.表也能知道去訪問哪個(gè)HRegionServer。

注意:當(dāng)HBase啟動(dòng)的時(shí)候HMaster負(fù)責(zé)分配RegionHRegionServer,這其中當(dāng)然也包括-ROOT-表和.META.表的Region

 

接下來HRegionServer打開這個(gè)Region并創(chuàng)建一個(gè)HRegion對象。當(dāng)HRegion打開以后,它給每個(gè)table的每個(gè)HColumnFamily創(chuàng)建一個(gè)Store實(shí)例。每個(gè)Store實(shí)例擁有一個(gè)或者多個(gè)StoreFile實(shí)例。StoreFileHFile做了輕量級的包裝。除了Store實(shí)例以外,每個(gè)HRegion還擁有一個(gè)MemStore實(shí)例和一個(gè)HLog實(shí)例。現(xiàn)在我們就可以看看這些實(shí)例是如何在一起工作的,遵循什么樣的規(guī)則以及這些規(guī)則的例外。


保留住Put

現(xiàn)在看一下數(shù)據(jù)是怎樣被寫到實(shí)際的存儲(chǔ)中去的。Client發(fā)起了一個(gè)HTable.put(Put)請求給HRegionServer,HRegionServer會(huì)將請求匹配到某個(gè)具體的HRegion上面。緊接著的操作時(shí)決定是否寫WAL log。是否寫WAL logClient傳遞的一個(gè)標(biāo)志決定,你可以設(shè)置這個(gè)標(biāo)志:Put.writeToWAL(boolean)。WAL log文件是一個(gè)標(biāo)準(zhǔn)的Hadoop SequenceFile(現(xiàn)在還在討論是否應(yīng)該把文件格式改成一個(gè)更適合HBase的格式)。在文件中存儲(chǔ)了HLogKey,這些Keys包含了和實(shí)際數(shù)據(jù)對應(yīng)的序列號,用途是當(dāng)RegionServer崩潰以后能將WAL log中的數(shù)據(jù)同步到永久存儲(chǔ)中去。做完這一步以后,Put數(shù)據(jù)會(huì)被保存到MemStore中,同時(shí)會(huì)檢查MemStore是否已經(jīng)滿了,如果已經(jīng)滿了,則會(huì)觸發(fā)一個(gè)Flush to Disk的請求。HRegionServer有一個(gè)獨(dú)立的線程來處理Flush to Disk的請求,它負(fù)責(zé)將數(shù)據(jù)寫成HFile文件并存到HDFS上。它也會(huì)存儲(chǔ)最后寫入的數(shù)據(jù)序列號,這樣就可以知道哪些數(shù)據(jù)已經(jīng)存入了永久存儲(chǔ)的HDFS中。現(xiàn)在讓我們來看看這些存儲(chǔ)文件。

 

存儲(chǔ)文件

HBaseHDFS上面的所有文件有一個(gè)可配置的根目錄,默認(rèn)根目錄是/hbase。通過使用hadoopDFS工具就可以看到這些文件夾的結(jié)構(gòu)。

在根目錄下面你可以看到一個(gè).logs文件夾,這里面存了所有由HLog管理的WAL log文件。在.logs目錄下的每個(gè)文件夾對應(yīng)一個(gè)HRegionServer,每個(gè)HRegionServer下面的每個(gè)log文件對應(yīng)一個(gè)Region。

有時(shí)候你會(huì)發(fā)現(xiàn)一些oldlogfile.log文件(在大多數(shù)情況下你可能看不到這個(gè)文件),這個(gè)文件在一種異常情況下會(huì)被產(chǎn)生。這個(gè)異常情況就是HMasterlog文件的訪問情況產(chǎn)生了懷疑,它會(huì)產(chǎn)生一種稱作“log splits”的結(jié)果。有時(shí)候HMaster會(huì)發(fā)現(xiàn)某個(gè)log文件沒人管了,就是說任何一個(gè)HRegionServer都不會(huì)管理這個(gè)log文件(有可能是原來管理這個(gè)文件的HRegionServer掛了),HMaster會(huì)負(fù)責(zé)分割這個(gè)log文件(按照它們歸屬的Region),并把那些HLogKey寫到一個(gè)叫做oldlogfile.log的文件中,并按照它們歸屬的Region直接將文件放到各自的Region文件夾下面。各個(gè)HRegion會(huì)從這個(gè)文件中讀取數(shù)據(jù)并將它們寫入到MemStore中去,并開始將數(shù)據(jù)Flush to Disk。然后就可以把這個(gè)oldlogfile.log文件刪除了。

注意:有時(shí)候你可能會(huì)發(fā)現(xiàn)另一個(gè)叫做oldlogfile.log.old的文件,這是由于HMaster做了重復(fù)分割log文件的操作并發(fā)現(xiàn)oldlogfile.log已經(jīng)存在了。這時(shí)候就需要和HRegionServer以及HMaster協(xié)商到底發(fā)生了什么,以及是否可以把old的文件刪掉了。從我目前遇到的情況來看,old文件都是空的并且可以被安全刪除的。

HBase的每個(gè)Table在根目錄下面用一個(gè)文件夾來存儲(chǔ),文件夾的名字就是Table的名字。在Table文件夾下面每個(gè)Region也用一個(gè)文件夾來存儲(chǔ),但是文件夾的名字并不是Region的名字,而是Region的名字通過Jenkins Hash計(jì)算所得到的字符串。這樣做的原因是Region的名字里面可能包含了不能在HDFS里面作為路徑名的字符。在每個(gè)Region文件夾下面每個(gè)ColumnFamily也有自己的文件夾,在每個(gè)ColumnFamily文件夾下面就是一個(gè)個(gè)HFile文件了。所以整個(gè)文件夾結(jié)構(gòu)看起來應(yīng)該是這個(gè)樣子的:

/hbase/<tablename>/<encoded-regionname>/<column-family>/<filename>

在每個(gè)Region文件夾下面你會(huì)發(fā)現(xiàn)一個(gè).regioninfo文件,這個(gè)文件用來存儲(chǔ)這個(gè)RegionMeta Data。通過這些Meta Data我們可以重建被破壞的.META.表,關(guān)于.regioninfo的應(yīng)用你可以參考HBASE-7HBASE-1867。

有一件事情前面一直沒有提到,那就是Region的分割。當(dāng)一個(gè)Region的數(shù)據(jù)文件不斷增長并超過一個(gè)最大值的時(shí)候(你可以配置這個(gè)最大值 hbase.hregion.max.filesize),這個(gè)Region會(huì)被切分成兩個(gè)。這個(gè)過程完成的非???,因?yàn)樵嫉臄?shù)據(jù)文件并不會(huì)被改變,系統(tǒng)只是簡單的創(chuàng)建兩個(gè)Reference文件指向原始的數(shù)據(jù)文件。每個(gè)Reference文件管理原始文件一半的數(shù)據(jù)。Reference文件名字是一個(gè)ID,它使用被參考的Region的名字的Hash作為前綴。例如:1278437856009925445.3323223323。Reference文件只含有非常少量的信息,這些信息包括被分割的原始RegionKey以及這個(gè)文件管理前半段還是后半段。HBase使用HalfHFileReader類來訪問Reference文件并從原始數(shù)據(jù)文件中讀取數(shù)據(jù)。前面的架構(gòu)圖只并沒有畫出這個(gè)類,因?yàn)樗皇桥R時(shí)使用的。只有當(dāng)系統(tǒng)做Compaction的時(shí)候原始數(shù)據(jù)文件才會(huì)被分割成兩個(gè)獨(dú)立的文件并放到相應(yīng)的Region目錄下面,同時(shí)原始數(shù)據(jù)文件和那些Reference文件也會(huì)被清除。

前面dump出來的文件結(jié)構(gòu)也證實(shí)了這個(gè)過程,在每個(gè)Table的目錄下面你可以看到一個(gè)叫做compaction.dir的目錄。這個(gè)文件夾是一個(gè)數(shù)據(jù)交換區(qū),用于存放splitcompact Region過程中生成的臨時(shí)數(shù)據(jù)。

 

HFile

現(xiàn)在我們將深入HBase存儲(chǔ)架構(gòu)的核心,探討HBase具體的數(shù)據(jù)存儲(chǔ)文件的結(jié)構(gòu)。HFile就是這個(gè)數(shù)據(jù)存儲(chǔ)文件的結(jié)構(gòu)(Ryan Rawson就是靠它揚(yáng)名立萬的)。創(chuàng)建HFile這樣一個(gè)文件結(jié)構(gòu)的目的只有一個(gè):快速高效的存儲(chǔ)HBase的數(shù)據(jù)。HFile是基于Hadoop TFile的(參見 HADOOP-3315)。HFile模仿了Google BigtableSSTable的格式。原先HBase使用HadoopMapFile,但是這種文件已經(jīng)被證明了效率差。

現(xiàn)在讓我們來看看這個(gè)文件結(jié)構(gòu)到底是什么樣的。

 

 

 

首先這個(gè)文件是不定長的,長度固定的只有其中的兩塊:TrailerFileInfo。正如圖中所示的,Trailer中有指針指向其他數(shù)據(jù)塊的起始點(diǎn)。Index數(shù)據(jù)塊記錄了每個(gè)Data塊和Meta塊的起始點(diǎn)。Data塊和Meta塊都是可有可無的,但是對于大部分的HFile,你都可以看到Data塊。

那么每個(gè)塊的大小是如何確定的呢?這個(gè)值可以在創(chuàng)建一個(gè)Table的時(shí)候通過HColumnDescriptor(實(shí)際上應(yīng)該稱作FamilyDescriptor)來設(shè)定。這里我們可以看一個(gè)例子:


{NAME => 'docs', FAMILIES => [{NAME => 'cache',COMPRESSION => 'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE=> '65536', IN_MEMORY => 'false', BLOCKCACHE => 'false'}, {NAME =>'contents', COMPRESSION => 'NONE', VERSIONS => '3', TTL =>'2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE=> 'false'}, ...

 

從這里可以看出這是一個(gè)叫做docsTable,它有兩個(gè)Familycachecontents,這兩個(gè)Family對應(yīng)的HFile的數(shù)據(jù)塊的大小都是64K。

關(guān)于如何設(shè)定數(shù)據(jù)塊的大小,我們應(yīng)用一段HFile源碼中的注釋:

我們推薦將數(shù)據(jù)塊的大小設(shè)置為8KB1MB。大的數(shù)據(jù)塊比較適合順序的查詢(比如Scan),但不適合隨機(jī)查詢,想想看,每一次隨機(jī)查詢可能都需要你去解壓縮一個(gè)大的數(shù)據(jù)塊。小的數(shù)據(jù)塊適合隨機(jī)的查詢,但是需要更多的內(nèi)存來保存數(shù)據(jù)塊的索引(Data Index),而且創(chuàng)建文件的時(shí)候也可能比較慢,因?yàn)樵诿總€(gè)數(shù)據(jù)塊的結(jié)尾我們都要把壓縮的數(shù)據(jù)流Flush到文件中去(引起更多的Flush操作)。并且由于壓縮器內(nèi)部還需要一定的緩存,最小的數(shù)據(jù)塊大小應(yīng)該在20KB - 30KB左右??赡軓那懊娴拿枋瞿銜?huì)發(fā)現(xiàn)數(shù)據(jù)塊(Data Block)是數(shù)據(jù)壓縮的一個(gè)單位。后面我們會(huì)深入Data Block內(nèi)部去了解它的詳細(xì)構(gòu)造。

HBase的配置文件中你會(huì)看到一個(gè)參數(shù):hfile.min.blocksize.size,這個(gè)參數(shù)看上去只會(huì)用在數(shù)據(jù)遷移或者通過工具直接創(chuàng)建HFile的過程中。(貌似HBase創(chuàng)建HFile不會(huì)使用這個(gè)參數(shù),HBase使用的是.META.表中記錄的那個(gè)值)。

呼——,到現(xiàn)在為止解釋的還不錯(cuò)吧。好了,讓我們繼續(xù)。有時(shí)候我們可能會(huì)想知道一個(gè)HFile是否正常以及它里面包含了什么內(nèi)容。沒問題,已經(jīng)有一個(gè)應(yīng)用程序來做這件事了。

HFile.main()本身就提供了一個(gè)用來dump HFile的工具。

 

 

這里有一個(gè)dump文件的例子:

 

 

 

第一部分是存儲(chǔ)具體數(shù)據(jù)的KeyValue對,每個(gè)數(shù)據(jù)塊除了開頭的Magic以外就是一個(gè)個(gè)KeyValue對拼接而成。后面會(huì)詳細(xì)介紹每個(gè)KeyValue對的內(nèi)部構(gòu)造。第二部分是Tailer塊的具體內(nèi)容,最后一部分是FileInfo塊的具體內(nèi)容。Dump HFile還有一個(gè)作用就是檢查HFile是否正常。

 

KeyValue

HFile里面的每個(gè)KeyValue對就是一個(gè)簡單的byte數(shù)組。但是這個(gè)byte數(shù)組里面包含了很多項(xiàng),并且有固定的結(jié)構(gòu)。我們來看看里面的具體結(jié)構(gòu):

 

開始是兩個(gè)固定長度的數(shù)值,分別表示Key的長度和Value的長度。緊接著是Key,開始是固定長度的數(shù)值,表示RowKey的長度,緊接著是RowKey,然后是固定長度的數(shù)值,表示Family的長度,然后是Family,接著是Qualifier,然后是兩個(gè)固定長度的數(shù)值,表示Time StampKey Type。Value部分沒有這么復(fù)雜的結(jié)構(gòu),就是純粹的數(shù)據(jù)。

java.org.apache.hadoop.hbase.KeyValue是用來處理這個(gè)KeyValue,你可能會(huì)發(fā)現(xiàn)在這個(gè)類里面有兩個(gè)方法:getKeygetRow。getKey當(dāng)然是用來獲取Key的內(nèi)容,那么getRow是什么?其實(shí)是用來獲取RowKey的。RowKey不是HBase的基本元素嗎?是的,這個(gè)類已經(jīng)不是純粹的Key&Value處理,它已經(jīng)打上了HBase的烙印。

好了,這篇文章就到此為止了,它對HBase的存儲(chǔ)架構(gòu)做了一個(gè)大致的介紹。希望這篇文章對于那些想更深入的挖掘HBase細(xì)節(jié)的人來說,能作為一個(gè)起點(diǎn)。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
HBase技術(shù)介紹
淺談HBase系統(tǒng)架構(gòu)
HBase 系統(tǒng)架構(gòu)
HBase架構(gòu)核心模塊
大數(shù)據(jù)學(xué)習(xí)路線Hbase總結(jié)
HBase 底層原理詳解
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服