一、HBase簡介
Hbase是什么
HBase是一種構(gòu)建在HDFS之上的分布式、面向列、多版本、非關(guān)系型的數(shù)據(jù)庫。在需要實時讀寫、隨機(jī)訪問超大規(guī)模數(shù)據(jù)集時,可以使用HBase。HBase 是Google Bigtable 的開源實現(xiàn)。
HBase的特點(diǎn)
大:一個表可以有上億行,上百萬列。
面向列:面向列(組)的存儲和權(quán)限控制,列(組)獨(dú)立檢索。
稀疏:對于為空(NULL)的列,并不占用存儲空間,因此,表可以設(shè)計的非常稀疏。
無模式:每一行都有一個可以排序的主鍵和任意多的列,列可以根據(jù)需要動態(tài)增加,同一張表中不同的行可以有截然不同的列。
數(shù)據(jù)多版本:每個單元中的數(shù)據(jù)可以有多個版本,默認(rèn)情況下,版本號自動分配,版本號就是單元格插入時的時間戳。
數(shù)據(jù)類型單一:HBase中的數(shù)據(jù)都是字符串,沒有類型,存儲在hbase上的都是字節(jié)數(shù)組。
二、HBase數(shù)據(jù)模型
HBase 以表的形式存儲數(shù)據(jù)。表由行和列組成。列劃分為若干個列族(row family),如下圖所示。

1) HBase的邏輯數(shù)據(jù)模型

2) HBase的物理數(shù)據(jù)模型

邏輯數(shù)據(jù)模型中空白cell在物理上是不存儲的,因此若一個請求為要獲取t8時間的contents:html,他的結(jié)果就是空。相似的,若請求為獲取t9時間的anchor:my.look.ca,結(jié)果也是空。但是,如果不指明時間,將會返回最新時間的行,每個最新的都會返回
Row Key
與 NoSQL 數(shù)據(jù)庫一樣,Row Key 是用來檢索記錄的主鍵。幾種訪問 HBase table 中的行方式:
1)通過單個 Row Key 訪問。
2)通過 Row Key 的 range 全表掃描。
3)Row Key 可以使任意字符串(最大長度是64KB,實際應(yīng)用中長度一般為 10 ~ 100bytes),在HBase 內(nèi)部,Row Key 保存為字節(jié)數(shù)組。列族
HBase 表中的每個列都?xì)w屬于某個列族。列族是表的 Schema 的一部分(而列不是),必須在使用表之前定義。列名都以列族作為前綴,例如 courses:history、courses:math 都屬于 courses 這個列族。
訪問控制、磁盤和內(nèi)存的使用統(tǒng)計都是在列族層面進(jìn)行的。在實際應(yīng)用中,列族上的控制權(quán)限能幫助我們管理不同類型的應(yīng)用, 例如,允許一些應(yīng)用可以添加新的基本數(shù)據(jù)、一些應(yīng)用可以讀取基本數(shù)據(jù)并創(chuàng)建繼承的列族、 一些應(yīng)用則只允許瀏覽數(shù)據(jù)(甚至可能因為隱私的原因不能瀏覽所有數(shù)據(jù))。Cell
時間戳HBase 中通過 Row 和 Columns 確定的一個存儲單元稱為 Cell。每個 Cell 都保存著同一份數(shù)據(jù)的多個版本。 版本通過時間戳來索引,時間戳的類型是 64 位整型。時間戳可以由HBase(在數(shù)據(jù)寫入時自動)賦值, 此時時間戳是精確到毫秒的當(dāng)前系統(tǒng)時間。時間戳也 可以由客戶顯示賦值。如果應(yīng)用程序要避免數(shù)據(jù)版本沖突,就必須自己生成具有唯一性的時間戳。每個 Cell 中,不同版本的數(shù)據(jù)按照時間倒序排序,即最新的數(shù)據(jù)排在最前面。
為了避免數(shù)據(jù)存在過多版本造成的管理(包括存儲和索引)負(fù)擔(dān),HBase 提供了兩種數(shù)據(jù)版本回收方式。 一是保存數(shù)據(jù)的最后 n 個版本,二是保存最近一段時間內(nèi)的版本(比如最近七天)。用戶可以針對每個列族進(jìn)行設(shè)置。
3) HBase物理存儲
Table 在行的方向上分割為多個HRegion,每個HRegion分散在不同的RegionServer中。

每個HRegion由多個Store構(gòu)成,每個Store由一個memStore和0或多個StoreFile組成,每個Store保存一個Columns Family

三、HBase系統(tǒng)架構(gòu)
1) HBase架構(gòu)圖

從HBase的架構(gòu)圖上可以看出,HBase中的組件包括Client、Zookeeper、HMaster、HRegionServer、HRegion、Store、MemStore、StoreFile、HFile、HLog等,接下來介紹他們的作用。
HBase中的每張表都通過行鍵按照一定的范圍被分割成多個子表(HRegion),默認(rèn)一個HRegion超過256M就要被分割成兩個,這個過程由HRegionServer管理,而HRegion的分配由HMaster管理。
Client
包含訪問HBase的接口,并維護(hù)cache來加快對HBase的訪問。Zookeeper
HBase依賴Zookeeper,默認(rèn)情況下HBase管理Zookeeper實例(啟動或關(guān)閉Zookeeper),Master與RegionServers啟動時會向Zookeeper注冊。
保證任何時候,集群中只有一個master
實時監(jiān)控Region server的上線和下線信息。并實時通知給master
存儲HBase的schema和table元數(shù)據(jù)HMaster
為Region server分配region
負(fù)責(zé)Region server的負(fù)載均衡
發(fā)現(xiàn)失效的Region server并重新分配其上的region。
處理schema更新請求。HRegionServer
維護(hù)master分配給他的region,處理對這些region的io請求。
負(fù)責(zé)切分正在運(yùn)行過程中變的過大的region。
注意:client訪問hbase上的數(shù)據(jù)時不需要master的參與,因為數(shù)據(jù)尋址訪問zookeeper和region server,而數(shù)據(jù)讀寫訪問region server。master僅僅維護(hù)table和region的元數(shù)據(jù)信息,而table的元數(shù)據(jù)信息保存在zookeeper上,因此master負(fù)載很低。HRegion
table在行的方向上分隔為多個Region。Region是HBase中分布式存儲和負(fù)載均衡的最小單元,即不同的region可以分別在不同的Region Server上,但同一個Region是不會拆分到多個server上。
Region按大小分隔,每個表一般是只有一個region。隨著數(shù)據(jù)不斷插入表,region不斷增大,當(dāng)region的某個列族達(dá)到一個閾值時就會分成兩個新的region。
每個region由以下信息標(biāo)識:< 表名,startRowkey,創(chuàng)建時間>
由目錄表(-ROOT-和.META.)記錄該region的endRowkeyStore
每一個region由一個或多個store組成,至少是一個store,hbase會把一起訪問的數(shù)據(jù)放在一個store里面,即為每個 ColumnFamily建一個store,如果有幾個ColumnFamily,也就有幾個Store。一個Store由一個memStore和0或者 多個StoreFile組成。 HBase以store的大小來判斷是否需要切分regionMemStore
memStore 是放在內(nèi)存里的。保存修改的數(shù)據(jù)即keyValues。當(dāng)memStore的大小達(dá)到一個閥值(默認(rèn)128MB)時,memStore會被flush到文 件,即生成一個快照。目前hbase 會有一個線程來負(fù)責(zé)memStore的flush操作。StoreFile
memStore內(nèi)存中的數(shù)據(jù)寫到文件后就是StoreFile,StoreFile底層是以HFile的格式保存。-
HFile
HBase中KeyValue數(shù)據(jù)的存儲格式,HFile是Hadoop的 二進(jìn)制格式文件,實際上StoreFile就是對Hfile做了輕量級包裝,即StoreFile底層就是HFile
HFile的存儲格式如下:
HFile由多個Data Block、Meta Block、FileInfo、Data Index、Meta Index、Trailer組成,其中Data Block是HBase的最小存儲單元,在前文中提到的BlockCache就是基于Data Block的緩存的。一個Data Block由一個魔數(shù)和一系列的KeyValue(Cell)組成,魔數(shù)是一個隨機(jī)的數(shù)字,用于表示這是一個Data Block類型,以快速監(jiān)測這個Data Block的格式,防止數(shù)據(jù)的破壞。Data Block的大小可以在創(chuàng)建Column Family時設(shè)置(HColumnDescriptor.setBlockSize()),默認(rèn)值是64KB,大號的Block有利于順序Scan,小號Block利于隨機(jī)查詢,因而需要權(quán)衡。Meta塊是可選的,F(xiàn)ileInfo是固定長度的塊,它紀(jì)錄了文件的一些Meta信息,例如:AVG_KEY_LEN, AVG_VALUE_LEN, LAST_KEY, COMPARATOR, MAX_SEQ_ID_KEY等。Data Index和Meta Index紀(jì)錄了每個Data塊和Meta塊的其實點(diǎn)、未壓縮時大小、Key(起始RowKey?)等。Trailer紀(jì)錄了FileInfo、Data Index、Meta Index塊的起始位置,Data Index和Meta Index索引的數(shù)量等。其中FileInfo和Trailer是固定長度的。
HFile里面的每個KeyValue對就是一個簡單的byte數(shù)組。但是這個byte數(shù)組里面包含了很多項,并且有固定的結(jié)構(gòu)。我們來看看里面的具體結(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),就是純粹的二進(jìn)制數(shù)據(jù)。 -
HLog
HLog(WAL log):WAL意為write ahead log,用來做災(zāi)難恢復(fù)使用,HLog記錄數(shù)據(jù)的所有變更,一旦region server 宕機(jī),就可以從log中進(jìn)行恢復(fù)。
HLog文件就是一個普通的Hadoop Sequence File, Sequence File的value是key時HLogKey對象,其中記錄了寫入數(shù)據(jù)的歸屬信息,除了table和region名字外,還同時包括sequence number和timestamp,timestamp是寫入時間,sequence number的起始值為0,或者是最近一次存入文件系統(tǒng)中的sequence number。 Sequence File的value是HBase的KeyValue對象,即對應(yīng)HFile中的KeyValue。
上圖中是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。
2) HRegion定位

通過zk里的文件/hbase/rs得到-ROOT-表的位置。-ROOT-表只有一個region。
通過-ROOT-表查找.META.表的第一個表中相應(yīng)的region的位置。其實-ROOT-表是.META.表的第一個region;.META.表中的每一個region 在-ROOT-表中都是一行記錄。
通過.META.表找到所要的用戶表region的位置。用戶表中的每個region在.META.表中都是一行記錄。
-ROOT-表永遠(yuǎn)不會被分隔為多個region,保證了最多需要三次跳轉(zhuǎn),就能定位到任意的region。client會將查詢的位置 信息保存緩存起來,緩存不會主動失效,因此如果client上的緩存全部失效,則需要進(jìn)行6次網(wǎng)絡(luò)來回,才能定位到正確的region,其中三次用來發(fā)現(xiàn) 緩存失效,另外三次用來獲取位置信息。
提示:
-ROOT-表:表包含.META.表所在的region列表,該表只有一個Region;Zookeeper中記錄了-ROOT-表的location
.META.表:表包含所有的用戶空間region列表,以及Region Server的服務(wù)器地址
hbase:meta表:高版本中已經(jīng)舍棄了ROOT和META表了,采用了這個表
四、HBase工作流程
HBase的流程圖

Client
首先當(dāng)一個請求產(chǎn)生時,HBase Client使用RPC(遠(yuǎn)程過程調(diào)用)機(jī)制與HMaster和HRegionServer進(jìn)行通信,對于管理類操作,Client與HMaster進(jìn)行RPC;對于數(shù)據(jù)讀寫操作,Client與HRegionServer進(jìn)行RPC。Zookeeper
HBase Client使用RPC(遠(yuǎn)程過程調(diào)用)機(jī)制與HMaster和HRegionServer進(jìn)行通信,但如何尋址呢?由于Zookeeper中存儲了-ROOT-表的地址和HMaster的地址,所以需要先到Zookeeper上進(jìn)行尋址。
HRegionServer也會把自己以Ephemeral方式注冊到Zookeeper中,使HMaster可以隨時感知到各個HRegionServer的健康狀態(tài)。此外,Zookeeper也避免了HMaster的單點(diǎn)故障。HMaster
當(dāng)用戶需要進(jìn)行Table和Region的管理工作時,就需要和HMaster進(jìn)行通信。HBase中可以啟動多個HMaster,通過Zookeeper的Master Eletion機(jī)制保證總有一個Master運(yùn)行。
管理用戶對Table的增刪改查操作
管理HRegionServer的負(fù)載均衡,調(diào)整Region的分布
在Region Split后,負(fù)責(zé)新Region的分配
在HRegionServer停機(jī)后,負(fù)責(zé)失效HRegionServer上的Regions遷移HRegionServer
當(dāng)用戶需要對數(shù)據(jù)進(jìn)行讀寫操作時,需要訪問HRegionServer。HRegionServer存取一個子表時,會創(chuàng)建一個HRegion對象,然后對表的每個列族創(chuàng)建一個Store實例,每個Store都會有一個 MemStore和0個或多個StoreFile與之對應(yīng),每個StoreFile都會對應(yīng)一個HFile, HFile就是實際的存儲文件。因此,一個HRegion有多少個列族就有多少個Store。 一個HRegionServer會有多個HRegion和一個HLog。注意:HStore存儲由兩部分組成:MemStore和StoreFiles。 MemStore是Sorted Memory Buffer,用戶 寫入數(shù)據(jù)首先 會放在MemStore,當(dāng)MemStore滿了以后會Flush成一個 StoreFile(實際存儲在HDHS上的是HFile),當(dāng)StoreFile文件數(shù)量增長到一定閥值,就會觸發(fā)Compact合并操作,并將多個StoreFile合并成一個StoreFile,合并過程中會進(jìn)行版本合并和數(shù)據(jù)刪除,因此可以看出HBase其實只有增加數(shù)據(jù),所有的更新和刪除操作都是在后續(xù)的compact過程中進(jìn)行的,這使得用戶的 讀寫操作*只要進(jìn)入內(nèi)存中就可以立即返回,保證了HBase I/O的高性能。
五、HBase的高可用
- HDFS機(jī)架識別策略:當(dāng)數(shù)據(jù)文件損壞時,會找相同機(jī)架上備份的數(shù)據(jù)文件,如果相同機(jī)架上的數(shù)據(jù)文件也損壞會找不同機(jī)架備份數(shù)據(jù)文件。
- HBase的Region快速恢復(fù):當(dāng)regionserver損壞時,master會對該regionserver上的region進(jìn)行重新分配,遷移到其他可用的regionserver上并恢復(fù)region。
- Master節(jié)點(diǎn)的HA機(jī)制:Master為一主多備。當(dāng)Master主節(jié)點(diǎn)宕機(jī)后,剩下的備節(jié)點(diǎn)通過選舉,產(chǎn)生主節(jié)點(diǎn)。
六、HBase運(yùn)維
- 時鐘同步
- 手動majorcompact
- region hole修復(fù)
- region overlap修復(fù)
- 讀寫集群配置要區(qū)分
- memstore flush時機(jī)


