一、HBase概況介紹
HBase是一個高可靠性、高性能、面向列、可伸縮的分布式存儲系統(tǒng),利用HBase技術(shù)可在廉價PC Server上搭建大規(guī)模結(jié)構(gòu)化的存儲集群。HBase的目標是存儲并處理大型數(shù)據(jù),具體來說是僅需使用普通的硬件配置,就能夠處理由成千上萬的行和列所組成的大型數(shù)據(jù)。
與MapReduce的離線批處理計算框架不同,HBase是一個可以隨機訪問的存儲和檢索數(shù)據(jù)平臺,彌補了HDFS不能隨機訪問數(shù)據(jù)的缺陷,適合實時性要求不是非常高的業(yè)務(wù)場景。HBase存儲的都是Byte數(shù)組,它不介意數(shù)據(jù)類型,允許動態(tài)、靈活的數(shù)據(jù)模型。
HBase的特點
· 大:一個表可以有上億行,上百萬列。
· 面向列:面向列表(簇)的存儲和權(quán)限控制,列(簇)獨立檢索。
· 稀疏:對于為空(NULL)的列,并不占用存儲空間,因此,表可以設(shè)計的非常稀疏。
· 無模式:每一行都有一個可以排序的主鍵和任意多的列,列可以根據(jù)需要動態(tài)增加,同一張表中不同的行可以有截然不同的列。
· 數(shù)據(jù)多版本:每個單元中的數(shù)據(jù)可以有多個版本,默認情況下,版本號自動分配,版本號就是單元格插入時的時間戳。
· 數(shù)據(jù)類型單一:HBase中的數(shù)據(jù)都是字符串,沒有類型。
HBase 的應(yīng)用場景
HBase 不適合所有場景。
首先,確信有足夠多數(shù)據(jù),如果有上億或上千億行數(shù)據(jù),HBase 是很好的備選。如果只有上千或上百萬行,則用傳統(tǒng)的R DBMS 可能是更好的選擇。因為所有數(shù)據(jù)可以在一兩個節(jié)點保存,集群其他節(jié)點可能閑置。
其次,確信可以不依賴所有 RDBMS 的額外特性(例如,列數(shù)據(jù)類型、 第二索引、事務(wù)、高級查詢語言等)。
第三,確信你有足夠的硬件。因為 HDFS 在小于5個數(shù)據(jù)節(jié)點時,基本上體現(xiàn)不出它的優(yōu)勢。
雖然,HBase 能在單獨的筆記本上運行良好,但這應(yīng)僅當(dāng)成是開發(fā)階段的配置。
二、HBase體系結(jié)構(gòu)
2.1 設(shè)計思路
HBase是一個分布式的數(shù)據(jù)庫,使用Zookeeper管理集群,使用HDFS作為底層存儲。在架構(gòu)層面上由HMaster(Zookeeper選舉產(chǎn)生的Leader)和多個HRegionServer組成,基本架構(gòu)如下圖所示:
在HBase的概念中,HRegionServer對應(yīng)集群中的一個節(jié)點,一個HRegionServer負責(zé)管理多個HRegion,而一個HRegion代表一張表的一部分數(shù)據(jù)。在HBase中,一張表可能會需要很多個HRegion來存儲數(shù)據(jù),每個HRegion中的數(shù)據(jù)并不是雜亂無章的。HBase在管理HRegion的時候會給每個HRegion定義一個Rowkey的范圍,落在特定范圍內(nèi)的數(shù)據(jù)將交給特定的Region,從而將負載分攤到多個節(jié)點,這樣就充分利用了分布式的優(yōu)點和特性。另外,HBase會自動調(diào)節(jié)Region所處的位置,如果一個HRegionServer過熱,即大量的請求落在這個HRegionServer管理的HRegion上,HBase就會把HRegion移動到相對空閑的其它節(jié)點,依次保證集群環(huán)境被充分利用。
2.2基本架構(gòu)
HBase由HMaster和HRegionServer組成,同樣遵從主從服務(wù)器架構(gòu)。HBase將邏輯上的表劃分成多個數(shù)據(jù)塊即HRegion,存儲在HRegionServer中。HMaster負責(zé)管理所有的HRegionServer,它本身并不存儲任何數(shù)據(jù),而只是存儲數(shù)據(jù)到HRegionServer的映射關(guān)系(元數(shù)據(jù))。集群中的所有節(jié)點通過Zookeeper進行協(xié)調(diào),并處理HBase運行期間可能遇到的各種問題。?
三、 HBase數(shù)據(jù)模型
HBase是一個類似于BigTable的分布式數(shù)據(jù)庫,它是一個稀疏的長期存儲的(存在HDFS上)、多維度的、排序的映射表。這張表的索引是行關(guān)鍵字、列關(guān)鍵字和時間戳。HBase的數(shù)據(jù)都是字符串,沒有類型。?
? ? ?可以將一個表想象成一個大的映射關(guān)系,通過行鍵、行鍵+時間戳或行鍵+列(列族:列修飾符),就可以定位特定數(shù)據(jù)。由于HBase是稀疏存儲數(shù)據(jù)的,所以某些列可以是空白的。上表給出了com.cnn.www網(wǎng)站的數(shù)據(jù)存放邏輯視圖,表中僅有一行數(shù)據(jù),行的唯一標識為“com.cnn.www”,對這行數(shù)據(jù)的每一次邏輯修改都有一個時間戳關(guān)聯(lián)對應(yīng)。表中共有四列:contents:html、anchor:cnnsi.com、anchor:my.look.ca、mime:type,每一列以前綴的方式給出其所屬的列族。
行鍵(RowKey)是數(shù)據(jù)行在表中的唯一標識,并作為檢索記錄的主鍵。在HBase中訪問表中的行只有三種方式:通過某個行鍵訪問、給定行鍵的范圍訪問、全表掃描。行鍵可以是任意字符串(最大長度64KB)并按照字典序進行存儲。對于那些經(jīng)常一起讀取的行,需要對鍵值精心設(shè)計,以便它們能放在一起存儲。
四、 HBase讀寫流程
下圖是HRegionServer數(shù)據(jù)存儲關(guān)系圖。上文提到,HBase使用MemStore和StoreFile存儲對表的更新。數(shù)據(jù)在更新時首先寫入HLog和MemStore。MemStore中的數(shù)據(jù)是排序的,當(dāng)MemStore累計到一定閾值時,就會創(chuàng)建一個新的MemStore,并且將老的MemStore添加到Flush隊列,由單獨的線程Flush到磁盤上,成為一個StoreFile。與此同時,系統(tǒng)會在Zookeeper中記錄一個CheckPoint,表示這個時刻之前的數(shù)據(jù)變更已經(jīng)持久化了。當(dāng)系統(tǒng)出現(xiàn)意外時,可能導(dǎo)致MemStore中的數(shù)據(jù)丟失,此時使用HLog來恢復(fù)CheckPoint之后的數(shù)據(jù)。
StoreFile是只讀的,一旦創(chuàng)建后就不可以再修改。因此Hbase的更新其實是不斷追加的操作。當(dāng)一個Store中的StoreFile達到一定閾值后,就會進行一次合并操作,將對同一個key的修改合并到一起,形成一個大的StoreFile。當(dāng)StoreFile的大小達到一定閾值后,又會對 StoreFile進行切分操作,等分為兩個StoreFile。
寫操作流程
步驟1:Client通過Zookeeper的調(diào)度,向HRegionServer發(fā)出寫數(shù)據(jù)請求,在HRegion中寫數(shù)據(jù)。
步驟2:數(shù)據(jù)被寫入HRegion的MemStore,直到MemStore達到預(yù)設(shè)閾值。
步驟3:MemStore中的數(shù)據(jù)被Flush成一個StoreFile。
步驟4:隨著StoreFile文件的不斷增多,當(dāng)其數(shù)量增長到一定閾值后,觸發(fā)Compact合并操作,將多個StoreFile合并成一個StoreFile,同時進行版本合并和數(shù)據(jù)刪除。
步驟5:StoreFiles通過不斷的Compact合并操作,逐步形成越來越大的StoreFile。
步驟6:單個StoreFile大小超過一定閾值后,觸發(fā)Split操作,把當(dāng)前HRegion Split成2個新的HRegion。父HRegion會下線,新Split出的2個子HRegion會被HMaster分配到相應(yīng)的HRegionServer 上,使得原先1個HRegion的壓力得以分流到2個HRegion上。
讀操作流程
步驟1:client訪問Zookeeper,查找-ROOT-表,獲取.META.表信息。
步驟2:從.META.表查找,獲取存放目標數(shù)據(jù)的HRegion信息,從而找到對應(yīng)的HRegionServer。
步驟3:通過HRegionServer獲取需要查找的數(shù)據(jù)。
步驟4:HRegionserver的內(nèi)存分為MemStore和BlockCache兩部分,MemStore主要用于寫數(shù)據(jù),BlockCache主要用于讀數(shù)據(jù)。讀請求先到MemStore中查數(shù)據(jù),查不到就到BlockCache中查,再查不到就會到StoreFile上讀,并把讀的結(jié)果放入BlockCache。
hbase工作原理
Client
首先當(dāng)一個請求產(chǎn)生時,HBase Client使用RPC(遠程過程調(diào)用)機制與HMaster和HRegionServer進行通信,對于管理類操作,Client與HMaster進行RPC;對于數(shù)據(jù)讀寫操作,Client與HRegionServer進行RPC。
Zookeeper
HBase Client使用RPC(遠程過程調(diào)用)機制與HMaster和HRegionServer進行通信,但如何尋址呢?由于Zookeeper中存儲了-ROOT-表的地址和HMaster的地址,所以需要先到Zookeeper上進行尋址。
HRegionServer也會把自己以Ephemeral方式注冊到Zookeeper中,使HMaster可以隨時感知到各個HRegionServer的健康狀態(tài)。此外,Zookeeper也避免了HMaster的單點故障。
HMaster
當(dāng)用戶需要進行Table和Region的管理工作時,就需要和HMaster進行通信。HBase中可以啟動多個HMaster,通過Zookeeper的Master Eletion機制保證總有一個Master運行。
· 管理用戶對Table的增刪改查操作
· 管理HRegionServer的負載均衡,調(diào)整Region的分布
· 在Region Split后,負責(zé)新Region的分配
· 在HRegionServer停機后,負責(zé)失效HRegionServer上的Regions遷移
HRegionServer
當(dāng)用戶需要對數(shù)據(jù)進行讀寫操作時,需要訪問HRegionServer。HRegionServer存取一個子表時,會創(chuàng)建一個HRegion對象,然后對表的每個列族創(chuàng)建一個Store實例,每個Store都會有一個 MemStore和0個或多個StoreFile與之對應(yīng),每個StoreFile都會對應(yīng)一個HFile, HFile就是實際的存儲文件。因此,一個HRegion有多少個列族就有多少個Store。 一個HRegionServer會有多個HRegion和一個HLog。
當(dāng)HStore存儲是HBase的核心了,其中由兩部分組成:MemStore和StoreFiles。 MemStore是Sorted Memory Buffer,用戶
寫入數(shù)據(jù)首先 會放在MemStore,當(dāng)MemStore滿了以后會Flush成一個 StoreFile(實際存儲在HDHS上的是HFile),當(dāng)StoreFile文件數(shù)量增長到一定閥值,就會觸發(fā)Compact合并操作,并將多個StoreFile合并成一個StoreFile,合并過程中會進行版本合并和數(shù)據(jù)刪除,因此可以看出HBase其實只有增加數(shù)據(jù),所有的更新和刪除操作都是在后續(xù)的compact過程中進行的,這使得用戶的 讀寫操作只要進入內(nèi)存中就可以立即返回,保證了HBase I/O的高性能。
下面以一個具體數(shù)據(jù)Put的流程,讓我們加深對HBase工作流程的認識。
HBase Put流程
下面是put流程的時序圖:
客戶端:
· 客戶端發(fā)起Put寫請求,講put寫入writeBuffer,如果是批量提交,寫滿緩存后自動提交
· 根據(jù)rowkey將put吩咐給不同regionserver
服務(wù)端:
· RegionServer將put按rowkey分給不同的region
· Region首先把數(shù)據(jù)寫入wal
· wal寫入成功后,把數(shù)據(jù)寫入memstore
· Memstore寫完后,檢查memstore大小是否達到flush閥值
· 如果達到flush閥值,將memstore寫入HDFS,生成HFile文件
HBase Compact &&Split
當(dāng)StoreFile文件數(shù)量增長到一定閥值,就會觸發(fā)Compact合并操作,并將多個StoreFile合并成一個StoreFile,當(dāng)這個StoreFile大小超過一定閥值后,會觸發(fā)Split操作,同時把當(dāng)前Region Split成2個Region,這是舊的Region會下線,新Split出的2個Region會被HMaster分配到相應(yīng)的HregionServer上,使得原先1個Region的壓力得以分散到2個Region上。
如下圖四個Storefile文件(從memstore文件經(jīng)過flush而得到,默認64M的storefile文件)經(jīng)過Compact合并成一個大的256M storefile文件,當(dāng)設(shè)定的Region閥值為128M時,就會Split為兩個128M的Storefile文件,然后HMaster再把這兩個storefile文件分配到不停地Regionserver上。
HFile
HBase中所有的數(shù)據(jù)文件都存儲在Hadoop HDFS上,主要包括兩種文件類型:
· Hfile:HBase中KeyValue數(shù)據(jù)的存儲格式,HFile是Hadoop的 二進制格式文件,實際上StoreFile就是對Hfile做了輕量級包裝,即StoreFile底層就是HFile
· HLog File:HBase中WAL(write ahead log)的存儲格式,物理上是Hadoop的Sequence File
HFile的存儲格式如下:
?
HFile文件是不定長的,長度固定的只有其中的兩塊:Trailer和FileInfo。
Trailer中有指針指向其他數(shù)據(jù)塊的起始點,F(xiàn)ileInfo記錄了文件的一些meta信息。 Data Block是hbase io的基本單元,為了提高效率,HRegionServer中有基于LRU的block cache機制。
每個Data塊的大小可以在創(chuàng)建一個Table的時候通過參數(shù)指定(默認塊大小64KB),大號的Block有利于順序Scan,小號的 Block利于隨機查詢。
每個Data塊除了開頭的Magic以外就是一個個KeyValue對拼接而成,Magic內(nèi)容就是一些隨機數(shù)字,目的是防止數(shù) 據(jù)損壞,結(jié)構(gòu)如下。
?
上圖可知,開始是兩個固定長度的數(shù)值,分別表示key的長度和alue的長度。緊接著是Key,開始是固定長度的數(shù)值,表示RowKey的長度,緊接著是RowKey,然后是固定長度的數(shù)值,表示Family的長度,然后是Family,接著是Qualifier,然后是兩個固定長度的數(shù)值,表示Time Stamp和Key Type(Put/Delete)。Value部分沒有那么復(fù)雜的結(jié)構(gòu),就是純粹的二進制數(shù)據(jù)。
HBase的三維有序(即字典順序)存儲
Hfile是HBase中KeyValue數(shù)據(jù)的存儲格式。從上面的 HBase物理數(shù)據(jù)模型中可以看出,HBase是面向列表(簇)的存儲。每個Cell由 {row key,column(=《 family》 + 《 label》),version} 唯一確定的單元,他們組合在一起就是一個KeyValue。根據(jù)上述描述,這個KeyValue中的key就是{row key,column(=《 family》 + 《 label》),version} ,而value就是cell中的值。
HBase的三維有序存儲中的三維是指:rowkey(行主鍵),column key(columnFamily+《 label》),timestamp(時間戳或者版本號)三部分組成的三維有序存儲。
· rowkey
rowkey是行的主鍵,它是以字典順序排序的。所以 rowkey的設(shè)計是至關(guān)重要的,關(guān)系到你應(yīng)用層的查詢效率。我們在根據(jù)rowkey范圍查詢的時候,我們一般是知道startRowkey,如果我們通過scan只傳startRowKey : d開頭的,那么查詢的是所有比d大的都查了,而我們只需要d開頭的數(shù)據(jù),那就要通過endRowKey來限制。我們可以通過設(shè)定endRowKey為:d 開頭,后面的根據(jù)你的rowkey組合來設(shè)定,一般是加比startKey大一位。
· column key
column key是第二維,數(shù)據(jù)按rowkey字典排序后,如果rowkey相同,則是根據(jù)column key來排序的,也是按字典排序。
我們在設(shè)計table的時候要學(xué)會利用這一點。比如我們的收件箱。我們有時候需要按主題排序,那我們就可以把主題這設(shè)置為我們的column key,即設(shè)計為columnFamily+主題。,這樣的設(shè)計。
· timestamp
timestamp 時間戳,是第三維,這是個按降序排序的,即最新的數(shù)據(jù)排在最前面。這個就沒有什么說的了。網(wǎng)上其他的博客也提到比較多。
HLog Replay
根據(jù)以上的敘述,我們已經(jīng)了解了關(guān)于HStore的基本原理,但我們還必須要了解一下HLog的功能,因為上述的HStore在系統(tǒng)正常工作的前提下是沒問題的,但是在分布式 系統(tǒng)環(huán)境中,無法避免系統(tǒng)出錯或者宕機,因為一旦HRegionServer意外退出,MemStore中的內(nèi)存數(shù)據(jù)將會丟失,這就需要引入HLog。每個HRegionServer中都有一個HLog對象,HLog是一個實現(xiàn)Write Ahead Log的類,在每一次用戶操作寫入MemStore的同時,也會寫一份數(shù)據(jù)到HLog文件中,HLog文件定期(當(dāng)文件已持久化到StoreFile中的數(shù)據(jù))會滾出新的,并且刪除舊的文件。當(dāng)HRegionServer意外終止 后,HMaster會通過Zookeeper感知到,HMaster首先會處理遺留的Hlog文件,將其中不同Region的Log數(shù)據(jù)進行拆分,分別放到相應(yīng)Region的目錄下,然后再將失效的Region重新分配,領(lǐng)取到這些Region的Regionserver在Load Region的過程中,會發(fā)現(xiàn)歷史HLog需要處理,因此Replay HLog中的數(shù)據(jù)到MemStore中,然后flush到StoreFiles,完成數(shù)據(jù)恢復(fù)。
HLog存儲格式
WAL(Write Ahead Log):RegionServer在處理插入和刪除過程中,用來記錄操作內(nèi)容的日志,只有日志寫入成功,才會通知客戶端操作成功。
上圖中是HLog文件的結(jié)構(gòu),其實HLog文件就是一個普通的Hadoop Sequence File,Sequence File的Key是HLogKey對象,HLogKey中記錄了寫入數(shù)據(jù)的歸屬信息,除了table和Region名字外,同時還包括sequence number和timestamp,timestamp是”寫入時間”,sequence number 的起始值為0,或者是最近一次存入文件系統(tǒng)中的sequence number。
HLog Sequence File 的Value是HBase的KeyValue對象昂,即對應(yīng)HFile中的KeyValue。
HBase性能和優(yōu)化影響HBase性能的因素
?
評論
查看更多