一、HBase邏輯視圖
| 視圖術(shù)語 | 解釋 |
|---|---|
| table | 表,一個(gè)表包含多行數(shù)據(jù)。 |
| row | 行,一行數(shù)據(jù)包含:一個(gè)唯一標(biāo)識(shí)rowkey、多個(gè)column及對(duì)應(yīng)的value。 (一張表中所有row都按roweky的字典順序由小到大排序) |
| column | 列,hbase中的列由列族(column family,cf)和列名(qualifier)組成, 格式:cf:qualifier。 (cf下可以設(shè)置任意多個(gè)qualifier,理論上可以擴(kuò)展到上百萬列) |
| timestamp | 時(shí)間戳,每個(gè)cell在寫入時(shí)hbase都會(huì)默認(rèn)分配一個(gè)時(shí)間戳作為該cell的版本,用戶也可在寫入時(shí)自帶時(shí)間戳。 (同一rowkey、column下可以有多個(gè)value存在,這些value使用時(shí)間戳作為版本號(hào),版本越大,數(shù)據(jù)越新) |
| cell | 單元格,由五元組(row, column, timestamp, type, value)組成的結(jié)構(gòu), 其中,type表示Put/Pelete這樣的操作類型。該結(jié)構(gòu)在數(shù)據(jù)庫中以KV結(jié)構(gòu)存儲(chǔ), 其中(row, column, timestamp,type)是K, value是字段對(duì)應(yīng)的KV結(jié)構(gòu)的V。 |

上圖邏輯視圖表示:
- 表中存儲(chǔ)2行數(shù)據(jù),兩個(gè)rowkey分別是com.cnn.www和com.example.ww,按字典序由小到大排列;
- 每行有3個(gè)列族,分別是anchior,coments,people,其中anchior列族下有2列,分別是cnnsi.com和my.lock.ca;
- 根據(jù)行com.cnn.www和列cnnsi.com可以定位到數(shù)據(jù)CNN,對(duì)應(yīng)的時(shí)間戳信息是t9;同row下的conent:html列下,卻有3個(gè)版本的數(shù)據(jù),版本號(hào)分別是t5, t6, t7;
(1)HBase引用了列族的概念,列族下的列可以動(dòng)態(tài)擴(kuò)展;
(2)HBase使用時(shí)間戳實(shí)現(xiàn)數(shù)據(jù)的多版本支持;
二、多維稀疏排序Map
BigTable本質(zhì)上是一個(gè)Map結(jié)構(gòu)數(shù)據(jù)庫(Map由key和value組成),HBase也是由一系列KV構(gòu)成。且HBase的Map結(jié)構(gòu)有很多限定詞:稀疏的、分布式的、持久性的、多緯的、排序的。
HBase中Map的key是一個(gè)復(fù)合鍵,由(row, column, timestamp,type),value是cell(單元格)的值。
舉例說明:上述HBase邏輯視圖對(duì)應(yīng)的Map存儲(chǔ)結(jié)構(gòu)如下:
{"com.cnn.www","anchor","cnnsi.com","put","t9"} --> "CNN"
HBase Map存儲(chǔ)結(jié)構(gòu)的特性如下:
(1)多維:HBase Map的key是一個(gè)復(fù)合數(shù)據(jù)結(jié)構(gòu),由多維元素構(gòu)成,包括:row, column, timestamp,type),其中,column由column family:qualifier構(gòu)成。
(2)稀疏:HBase中空值不需要填充null;稀疏性是HBase的列可以無限擴(kuò)充的一個(gè)重要條件。
(3)排序:構(gòu)成HBase的KV在同一個(gè)文件中都是有序的,排序規(guī)則不僅僅按照rowkey排序,而是按KV中的key進(jìn)行排序——先比較rowkey,rowkey小的排在前面;若rowkey相同,再比較column,以此類推。這樣的多維元素排序規(guī)則,對(duì)于提升HBase的讀取性能至關(guān)重要。
(4)分布式:構(gòu)成HBase的所有Map并不是集中在某臺(tái)機(jī)器上,而是分布在整個(gè)集群中。
三、HBase物理視圖
HBase中的數(shù)據(jù)是按列族存儲(chǔ)的,即:將數(shù)據(jù)按列族分布存儲(chǔ)在不同的目錄中。
舉例說明:上述HBase邏輯視圖中列族anchor的所有數(shù)據(jù)存儲(chǔ)在一起形成:

四、列族式存儲(chǔ)的優(yōu)勢(shì)
HBase是列族式存儲(chǔ)的,為什么HBase要將數(shù)據(jù)按列族式分布存儲(chǔ)?回答這個(gè)問題之前,需要先了解行式存儲(chǔ)和列式存儲(chǔ):
(1)行式存儲(chǔ)
將一行數(shù)據(jù)存儲(chǔ)在一起。行式存儲(chǔ)在獲取一行數(shù)據(jù)時(shí)很高效,但是如果只需要讀取表中某列數(shù)據(jù),行式存儲(chǔ)會(huì)先取出一行行數(shù)據(jù),再對(duì)每行數(shù)據(jù)中截取目標(biāo)列,這種處理方式在查找過程中引入了大量無用列信息,從而導(dǎo)致大量?jī)?nèi)存占用。行式存儲(chǔ)的系統(tǒng)適合處理OLTP類型的負(fù)載,不適合PLAP這類分析型負(fù)載。
(2)列式存儲(chǔ)
將一列數(shù)據(jù)存儲(chǔ)在一起。列式存儲(chǔ)對(duì)于只查找某列數(shù)據(jù)的請(qǐng)求高效,只需要連續(xù)讀出所有待查目標(biāo)列,然后遍歷處理即可;對(duì)于獲取某行的請(qǐng)求就不夠高效了。另外,同一列的數(shù)據(jù)通常具有相同的數(shù)據(jù)類型,因此列式存儲(chǔ)具有天然的高壓縮特性。
列族式存儲(chǔ)介于行式存儲(chǔ)和列式存儲(chǔ),可以通過不同的設(shè)計(jì)思路在行式存儲(chǔ)和列式存儲(chǔ)之間相互切換。比如:設(shè)計(jì)一個(gè)列族里有多個(gè)列,這種設(shè)計(jì)模式就等同于行式存儲(chǔ);設(shè)計(jì)多個(gè)列族,每個(gè)列族下僅一個(gè)列,這種設(shè)計(jì)模式就等同于列式存儲(chǔ)。
在當(dāng)前體系下不建議設(shè)置太多列族,但是這種架構(gòu)為HBase將來演變?yōu)镠TAP系統(tǒng)(Hybrid Transactional and Analytical Processing)提供列最核心的基礎(chǔ)。
四、HBase體系結(jié)構(gòu)

1、HBase客戶端
client提供shell命令行接口、原生java api編程接口、thrift/REST api編程接口以及MapReduce編程接口??蛻舳酥С?jǐn)?shù)據(jù)的增刪改查和表的日常維護(hù)等,其中thrift/REST api主要用于非java的上層業(yè)務(wù)需求,MapReduce接口主要用于批量導(dǎo)入數(shù)據(jù)以及批量數(shù)據(jù)讀取。
HBase客戶端訪問數(shù)據(jù)行之前,先需要通過元數(shù)據(jù)表定位目標(biāo)數(shù)據(jù)所在RS,之后才會(huì)發(fā)送請(qǐng)求到該RS。同時(shí)這些元數(shù)據(jù)會(huì)被緩存在客戶端本地,以方便之后的請(qǐng)求訪問。如果集群RS發(fā)生宕機(jī)或執(zhí)行了負(fù)載均衡等,從而導(dǎo)致數(shù)據(jù)分片發(fā)生遷移,客戶端需要重新請(qǐng)求最新的元數(shù)據(jù)并緩存在本地。
2、Zookeeper
ZK主要用于協(xié)調(diào)管理分布式應(yīng)用程序,在HBase系統(tǒng)中,ZK的作用如下:
- 實(shí)現(xiàn)Master高可用:通常情況下系統(tǒng)只有一個(gè)active Master,一旦由于異常宕機(jī),ZK會(huì)檢測(cè)到該宕機(jī)事件,并通過一定機(jī)制選舉出新的active Master,保證Hbase正常運(yùn)行。
- 管理系統(tǒng)核心元數(shù)據(jù):比如,管理正常工作的RS集合、保存元數(shù)據(jù)表hbase:meta所在的RS地址等。
- 參與RS宕機(jī)恢復(fù):ZK通過心跳感知到RS是否宕機(jī),并在宕機(jī)后通知Master進(jìn)行宕機(jī)處理;
- 實(shí)現(xiàn)分布式表鎖:HBase中對(duì)一個(gè)表進(jìn)行各種管理操作(比如alter操作)需要先加表鎖,防止其他用戶對(duì)同一個(gè)表進(jìn)行管理操作,造成表狀態(tài)不一致。因?yàn)镠Base是分布式存儲(chǔ),ZK可以通過特定機(jī)制實(shí)現(xiàn)分布式表鎖。
3、Master
Master主要負(fù)責(zé)HBase的各種管理工作:
- 處理用戶的各種管理請(qǐng)求,包括:建表、修改表、權(quán)限操作、切分表、合并數(shù)據(jù)分片、compaction等。
- 管理集群中所有RS,包括:RS中Region的負(fù)載均衡、RS的宕機(jī)恢復(fù)、Region的遷移等。
- 清理過期日志以及文件,Master會(huì)每隔一段是檢查HDFS中HLog是否過期、HFile是否已經(jīng)被刪除,并在過期后將其刪除。
4、RegionServer
RS主要用來響應(yīng)用戶的IO請(qǐng)求,是HBase中最核心的模塊,由WAL(HLog)、BlockCache以及多個(gè)Region構(gòu)成。
- WAL(HLog):WAL在HBase中有兩個(gè)核心作用:(1)實(shí)現(xiàn)數(shù)據(jù)的高可用性;(2)實(shí)現(xiàn)HBase集群之間主從復(fù)制;
(1)實(shí)現(xiàn)數(shù)據(jù)的高可用性
HBase數(shù)據(jù)隨機(jī)寫入時(shí),并非直接寫入HFile數(shù)據(jù)文件,而是先寫入緩存,再異步刷新落盤,為了防止緩存數(shù)據(jù)丟失,數(shù)據(jù)寫入緩存之前需要先順序?qū)懭際Log,這樣即使緩存數(shù)據(jù)丟失仍然可以通過HLog日志恢復(fù)。
(2)實(shí)現(xiàn)HBase集群之間主從復(fù)制
通過回放主集群推送過來的HLog日志實(shí)現(xiàn)主從復(fù)制。
- BlockCache:HBase的讀緩存,客戶端從磁盤讀取數(shù)據(jù)之后通常會(huì)將數(shù)據(jù)緩存到系統(tǒng)內(nèi)存中,后續(xù)訪問同一行數(shù)據(jù)可以直接從內(nèi)存中獲取而不需要訪問磁盤。對(duì)于帶有大量熱點(diǎn)讀的業(yè)務(wù)請(qǐng)求來說,緩存機(jī)制會(huì)帶來極大的性能提升。
當(dāng)前BlockCache主要有兩種實(shí)現(xiàn):LRUBlockCache和BucketCache。
BlockCache緩存對(duì)象是一系列Block塊,一個(gè)Block默認(rèn)是64K,由物理上相鄰的多個(gè)KV數(shù)據(jù)組成。
BlockCache同時(shí)利用了空間局部性和時(shí)間局部性原理:
(1)空間局部性:最近將讀取的KV數(shù)據(jù)很可能與當(dāng)前讀取到的KV數(shù)據(jù)在地址上是鄰近的。緩存單位是Block而不是單個(gè)KV就可以實(shí)現(xiàn)空間局部性。
(2)時(shí)間局部性:一個(gè)KV數(shù)據(jù)正在被訪問,那么近期它還可能再次被訪問。
- Region:數(shù)據(jù)表的一個(gè)分片,當(dāng)數(shù)據(jù)表超過一定閥值就會(huì)“水平切分”,分裂為兩個(gè)Region。Region是集群負(fù)載均衡的基本單位,通常一個(gè)表的Region會(huì)分布在整個(gè)集群的多臺(tái)RS上,一個(gè)RS上會(huì)管理多個(gè)Region(當(dāng)然,這些Region一般來自不同的數(shù)據(jù)表)。
(1)一個(gè)Region由一個(gè)或多個(gè)Store構(gòu)成,Store的個(gè)數(shù)取決于表中列族的個(gè)數(shù):多少個(gè)列族就有多少個(gè)Store。
(2)一個(gè)Store由一個(gè)MemStore(寫緩存)和一個(gè)或多個(gè)HFile組成。用戶寫入數(shù)據(jù)時(shí)首先寫到MemStore,當(dāng)MemStore寫滿之后(緩存數(shù)據(jù)超過閥值,默認(rèn)128MB),系統(tǒng)會(huì)異步將數(shù)據(jù)flush成一個(gè)HFile文件,隨著數(shù)據(jù)不斷寫入,HFile文件越來越多,當(dāng)HFile文件數(shù)量超過一定閥值后系統(tǒng)將執(zhí)行Compact操作,將這些小文件通過一定策略合并成一個(gè)或多個(gè)大文件。
(3)每個(gè)列族的數(shù)據(jù)都集中存儲(chǔ)在一起形成一個(gè)存儲(chǔ)單元Store,因此建議將具有相同IO特性的數(shù)據(jù)設(shè)置在一個(gè)列族里。
5、HDFS
HBase底層依賴HDFS組建存儲(chǔ)實(shí)際數(shù)據(jù),包括用戶數(shù)據(jù)文件、HLog日志文件等最終都會(huì)寫入HDFS落盤。
HDFS數(shù)據(jù)默認(rèn)三副本存儲(chǔ)策略,可以有效保證數(shù)據(jù)的高可用性。HBase內(nèi)部封裝了一個(gè)名為DFSClient的HDFS客戶端組件,負(fù)責(zé)對(duì)HDFS的實(shí)際數(shù)據(jù)進(jìn)行讀寫訪問。
五、HBase系統(tǒng)特性
1、優(yōu)點(diǎn)
容量巨大、可擴(kuò)展、稀疏性、高性能、多版本、支持過期、Hadoop原生支持
- 容量巨大:?jiǎn)伪砜芍С智|行、百萬列的數(shù)據(jù)規(guī)模;數(shù)據(jù)容量可以達(dá)到TB甚至PB級(jí)別;
- 良好的可擴(kuò)展性:集群容量擴(kuò)展方便,包括:數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)擴(kuò)展(增加DataNode節(jié)點(diǎn))、讀寫服務(wù)節(jié)點(diǎn)擴(kuò)展(增加RegionServer節(jié)點(diǎn))。
- 稀疏性:支持大量稀疏存儲(chǔ),即允許大量列值為空,并不占用任何存儲(chǔ)空間。
- 高性能:主要擅長OLTP場(chǎng)景,數(shù)據(jù)寫操作性能強(qiáng)。對(duì)于隨機(jī)單點(diǎn)讀以及小范圍掃描讀,性能也能得到保證;對(duì)于大范圍掃描讀,可以使用MapReduce提供的API,以便實(shí)現(xiàn)更高效的并行掃描。
- 多版本:一個(gè)kv可以同時(shí)保留多個(gè)版本,用戶可以根據(jù)需要選擇最新版本或某個(gè)歷史版本。
- 支持過期:支持TTL過期特性,用戶只需設(shè)置過期時(shí)間,超過TTL的數(shù)據(jù)會(huì)被自動(dòng)清理,不需要用戶手動(dòng)刪除。
- Hadoop原生支持:HBase是HAdoop生態(tài)中的核心成員之一,很多生態(tài)組件可以與其直接對(duì)接。
2、缺點(diǎn)
不支持復(fù)雜聚合運(yùn)算、不支持二級(jí)索引查找、不支持全局跨行事務(wù)
- 不支持復(fù)雜聚合運(yùn)算。例如:join、groupby等。復(fù)雜聚合運(yùn)算需要借助Phoenix組件(適合小規(guī)模聚合的OLTP場(chǎng)景)或Spark組件(適合大規(guī)模的OLAP場(chǎng)景)。
- 不支持二級(jí)索引查找。HBase本身沒有實(shí)現(xiàn)二級(jí)索引功能,目前比較普遍的使用Phoenix提供的二級(jí)索引功能。
- 原生不支持全局跨行事務(wù),只支持單行事務(wù)模型。可以使用Phoenix提供的全局事務(wù)模型組件。