![初識 HBase](http://static.javashuo.com/static/loading.gif)
HBase簡介
對大數據領域有必定了解的小夥伴對HBase應該不會陌生,HBase是Apache基金會開源的一個分佈式非關係型數據庫,屬於Hadoop的組件。它使用Java編寫,需運行於HDFS文件系統之上。HBase與Hadoop中的其餘組件同樣,能夠運行在廉價硬件上,並可提供數10億行 X 數百萬列的大數據存儲、管理能力,以及隨機訪問和實時讀/寫能力。HBase的設計模型參考了Google的Bigtable,能夠說是Bigtable的開源實現版本。html
HBase特性
- 數據容量大,單表能夠有百億行、百萬列,數據矩陣橫向和縱向兩個維度所支持的數據量級都很是具備彈性
- 多版本,每一列存儲的數據能夠有多個version
- 稀疏性,爲空的列並不佔用存儲空間,表能夠設計的很是稀疏
- 讀寫強一致,非 「最終一致性」 的數據存儲,使得它很是適合高速的計算聚合
- 自動分片,經過Region分散在集羣中,當行數增加的時候,Region也會自動的切分和再分配
- Hadoop/HDFS集成,和HDFS開箱即用,不用太麻煩的銜接。擴展性強,只須要增長DataNode就能夠增長存儲空間
- 豐富的「簡潔,高效」API,提供了Thrift/REST API,Java API等方式對HBase進行訪問
- 塊緩存,布隆過濾器,能夠高效的列查詢優化
- 操做管理,Hbase提供了內置的web界面來操做,還能夠監控JMX指標
- 高可靠,保證了系統的容錯能力,WAL機制使得數據寫入時不會由於集羣異常而致使寫入數據丟失。故HBase選擇了CAP中的CP
- 面向列的存儲和權限控制,並支持獨立檢索,能夠動態的增長列
- 列式存儲:其數據在表中是按照某列存儲的,這樣在查詢只須要少數幾個字段的時候,能大大減小讀取的數據量
- 高性能,具有海量數據的隨機訪問和實時讀寫能力
- 寫方面:底層的 LSM 數據結構和 Rowkey 有序排列等架構上的獨特設計,使得HBase具備很是高的寫入性能。
- 讀方面:region 切分、主鍵索引和緩存機制使得HBase在海量數據下具有必定的隨機讀取性能,針對 Rowkey 的查詢可以達到毫秒級別
綜上,HBase是一個高可靠、高性能、面向列、可伸縮的分佈式數據庫,是谷歌Bigtable的開源實現。主要用來存儲非結構化和半結構化的鬆散數據。HBase的目標是處理很是龐大的表,能夠經過水平擴展的方式,利用廉價計算機集羣處理由超過10億行數據和數百萬列元素組成的數據表。更多內容詳見官方文檔。web
HBase提供的訪問接口
類型 |
特色 |
場合 |
Native Java API |
最常規和高效的訪問方式 |
適合Hadoop MapReduce做業並行批處理HBase表數據 |
HBase Shell |
HBase的命令行工具,最簡單的接口 |
適合管理HBase時使用 |
Thrift Gateway |
利用Thrift序列化技術進行訪問,支持C++、PHP、Python等多種語言 |
適合其餘異構系統在線訪問HBase表數據 |
REST Gateway |
解除了語言限制,任何語言均可以經過該方式訪問HBase |
支持REST風格的HTTP API訪問HBase |
Pig |
使用 Pig Latin 流式編程語言來處理HBase中的數據 |
適合作數據統計 |
Hive |
簡單 |
當須要以相似SQL語言方式來訪問HBase的時候 |
HBase 與 HDFS 的區別
- HDFS是面向批量的訪問模式,其類型爲文件系統,存儲的是文件類型的數據
- HBase是面向隨機訪問和實時讀寫模式,其類型爲數據庫服務,存儲的是非結構化和半結構化的鬆散數據
- HBase 使用 HDFS 做爲底層的文件系統,HBase 的數據最終會寫到 HDFS 中。就像其餘的數據庫同樣,真正的數據是存儲在操做系統裏的文件系統中的
- 打個不恰當的比方:它們的區別就像是Linux文件系統與MongoDB的區別
HBase 與關係數據庫的區別
數據類型:數據庫
- 關係數據庫採用關係模型,具備豐富的數據類型和存儲方式,HBase則採用了更加簡單的數據模型,它把數據存儲爲未經解釋的字符串。
數據操做:apache
- 關係數據庫中包含了豐富的操做,其中會涉及複雜的多表鏈接。HBase操做則不存在複雜的表與表之間的關係,只有簡單的插入、查詢、刪除、清空等,由於HBase在設計上就避免了複雜的表和表之間的關係。因此HBase也就不支持複雜的條件查詢,只能是經過行鍵查詢。
存儲模式:編程
- 關係數據庫是基於行模式存儲的。HBase是基於列存儲的,每一個列簇都由幾個文件保存,不一樣列簇的文件是分離的。而且列簇中的列是能夠動態增長的,而關係數據庫須要一開始就設計好。除此以外,HBase能夠自動切分數據,關係型數據庫則須要咱們人工切分數據。
數據索引:json
- 關係數據庫一般能夠針對不一樣列構建複雜的多個索引,以提升數據訪問性能。HBase只有一個索引——行鍵,經過巧妙的設計,HBase中的全部訪問方法,或者經過行鍵訪問,或者經過行鍵掃描,從而使得整個系統不會慢下來。
數據維護:數組
- 在關係數據庫中,更新操做會用最新的當前值去替換記錄中原來的舊值,舊值被覆蓋後就不會存在。而在HBase中執行更新操做時,並不會刪除數據舊的版本,而是生成一個新的版本,舊有的版本仍然保留。
可伸縮性:瀏覽器
- 關係數據庫很難實現橫向擴展,縱向擴展的空間也比較有限。相反,HBase和BigTable這些分佈式數據庫就是爲了實現靈活的水平擴展而開發的,可以輕易地經過在集羣中增長或者減小硬件數量來實現性能的伸縮。
HBase 常見應用場景
- 存儲業務數據:交通工具GPS信息,司機點位信息,訂單信息,物流信息,設備訪問信息,用戶行爲信息等
- 存儲日誌數據:架構監控數據(登陸日誌,中間件訪問日誌,推送日誌,短信郵件發送記錄等),業務操做日誌信息等
- 存儲業務附件:UDFS系統存儲圖像,視頻,文檔等附件信息,智慧城市系統的監控圖像、流量數據等
HBase 的版本選擇與定位
如何選擇合適的 HBase 版本
HBase屬於Hadoop生態體系,因此HBase的版本選擇實際就是Hadoop的版本選擇。而Hadoop就像Linux同樣,也有多個發行版,經常使用發行版有如下幾種:緩存
- 原生的Apache Hadoop
- CDH:Cloudera Distributed Hadoop
- HDP:Hortonworks Data Platform
原生的Apache Hadoop在生產環境中不建議使用,由於Apache社區裏的Hadoop生態系統的框架只是解決了單個框架的問題,若是想要將不一樣的框架,例如Hive、Hbase等框架綜合起來使用的話,老是會產生jar包的衝突問題,並且這些衝突問題一般都是沒法解決的。因此在學習的時候可使用Apache Hadoop,可是生產環境中就不太建議使用了。服務器
CDH以及HDP都是基於Apache Hadoop社區版衍生出來的,這兩個發行版雖然都是商業版的,但不屬於收費版本,除非須要提供技術服務,才須要收取必定的服務費用,而且它們也都是開源的。在國內絕大多數公司都會選擇使用CDH版本,因此在這裏也主要介紹CDH,選擇CDH的主要理由以下:
- CDH對Hadoop版本的劃分很是清晰,目前只有三個系列的版本(如今已經更新到CDH6.32了,基於hadoop3.x),分別是cdh四、cdh5和cdh6,分別對應第一代Hadoop(Hadoop 1.0)、第二代Hadoop(Hadoop 2.0)和第三代Hadoop(Hadoop 3.0),相比而言,Apache版本則混亂得多;
- CDH文檔清晰且豐富,不少採用Apache版本的用戶都會閱讀cdh提供的文檔,包括安裝文檔、升級文檔等。
並且CDH提供了一個CM組件,讓咱們在安裝它的時候只須要在瀏覽器上的頁面中,點擊各類下一步就能夠完成安裝,比起Apache Hadoop的安裝要方便不少,並且不少操做均可以在圖形界面上完成,例如集羣的搭建以及節點切換等。CDH與Spark的合做是很是好的,因此在CDH中對Spark的支持比較好。最主要的是通常狀況下使用同一版本的CDH,就不會發生jar衝突的狀況。
CDH6的下載地址以下:
注:選擇版本的時候儘可能保持一致,例如hive選擇了cdh5.7.0的話,那麼其餘框架也要選擇cdh5.7.0,否則有可能會發生jar包的衝突。
HBase 在 Hadoop 生態系統中的定位
![初識 HBase](http://static.javashuo.com/static/loading.gif)
HBase 系統架構與數據模型
系統架構
大體的架構體系
在HBase中,表被分割成多個更小的塊而後分散的存儲在不一樣的服務器上,這些小塊叫作Region,存放Region的地方叫作RegionServer。Master進程負責處理不一樣的RegionServer之間的Region的分發。HBase裏的HRegionServer和HRegion類表明RegionServer和Region。HRegionServer除了包含一些HRegion以外,還處理兩種類型的文件用於數據存儲。
![初識 HBase](http://static.javashuo.com/static/loading.gif)
- HBase 依賴 Zookeeper 做爲分佈式的協調、治理工具,RegionServer、Master也會把本身的信息寫到ZooKeeper中
- HBase 還依賴 HDFS 做爲底層的文件系統,HBase 的數據最終是存儲到 HDFS 服務中的
- HBase 存在兩個主要進程,分別是RegionServer和Master
- HBase 中的 RegionServer,能夠類比爲 HDFS 的 DataNode 即數據節點。客戶端經過RegionServer對數據進行讀寫操做,而RegionServer會負責與 HDFS 進行數據交互
- RegionServer會實時向Master報告自身狀態及region等信息。Master知道全局的RegionServer運行狀況,能夠控制RegionServer的故障轉移和region的切分。Master至關因而RegionServer集羣的管理者,而且任什麼時候刻只有一個Master在運行
細化的架構體系
![初識 HBase](http://static.javashuo.com/static/loading.gif)
Client
- 客戶端包含訪問HBase的接口,同時在緩存中維護着已經訪問過的Region位置信息,用來加快後續數據訪問過程
Zookeeper
- Zookeeper做爲協調工具能夠幫助選舉出一個Master做爲集羣的總管,並保證在任什麼時候刻總有惟一一個Master在運行,這就避免了Master的「單點故障」的問題
![初識 HBase](http://static.javashuo.com/static/loading.gif)
Master
- 主要負責表和Region的管理工做
- 管理客戶端對錶的增長、刪除、修改、查詢等操做
- 實現不一樣RegionServer之間的負載均衡
- 在Region分裂或合併後,負責從新調整Region的分佈
- 對發生故障失效的RegionServer上的Region進行遷移
RegionServer
- RegionServer是HBase中最核心的模塊,負責維護分配給本身的Region,並響應用戶的讀寫請求。
- 用戶讀寫數據過程:
- 用戶寫入數據時,被分配到相應Region服務器去執行
- 用戶數據首先被寫入到MEMStore和Hlog中
- 只有當操做寫入Hlog以後,commit()調用纔會將其返回給客戶端
- 當用戶讀取數據時,Region服務器首先訪問MEMStore緩存,若是找不到,再去磁盤上面的StoreFile中尋找
- 緩存的刷新:
- 系統會週期性地把MemStore緩存裏的內容刷寫到磁盤的StoreFile文件中,清空緩存,並在Hlog裏面寫入一個標記
- 每次刷寫都生成一個新的StoreFile文件,所以,每一個Store包含多個StoreFile文件
- 每一個Region服務器都有一個本身的HLog 文件,每次啓動都檢查該文件,確認最近一次執行緩存刷新操做以後是否發生新的寫入操做;若是發現更新,則先寫入MemStore,再刷寫到StoreFile,最後刪除舊的Hlog文件,開始爲用戶提供服務。
- StoreFile的合併:
- 每次刷寫都生成一個新的StoreFile,數量太多,影響查找速度、
- 調用Store.compact()把多個合併成一個
- 合併操做比較耗費資源,只有數量達到一個閾值才啓動合併
讀寫流程示意圖:
![初識 HBase](http://static.javashuo.com/static/loading.gif)
HLog
- 預寫日誌文件,也叫作WAL(write-ahead log),WAL位於
/hbase/WALs/
目錄下
- 一般狀況,每一個RegionServer只有一個WAL實例。在2.0以前,WAL的實現叫作HLog
MasterProcWAL
:HMaster
記錄管理操做,好比解決衝突的服務器,表建立和其它DDL等操做到它的WAL文件中,這個WALs存儲在MasterProcWALs
目錄下,它不像RegionServer的WALs,HMaster
的WAL也支持彈性操做,就是若是Master服務器掛了,其它的Master接管的時候繼續操做這個文件。
WAL記錄全部的HBase數據改變,若是一個RegionServer在MemStore進行FLush的時候掛掉了,WAL能夠保證數據的改變被應用到。若是寫WAL失敗了,那麼修改數據的完整操做就是失敗的。
MultiWAL
:若是每一個RegionServer只有一個WAL,因爲HDFS必須是連續的,致使必須寫WAL連續的,而後出現性能問題。MultiWAL
可讓RegionServer同時寫多個WAL並行的,經過HDFS底層的多管道,最終提高總的吞吐量,可是不會提高單個Region的吞吐量。
HFile
- 真實存儲數據的文件,HFile是Hbase在HDFS中存儲數據的格式,它包含多層的索引,這樣在Hbase檢索數據的時候就不用徹底的加載整個文件。索引的大小(keys的大小,數據量的大小)影響block的大小,在大數據集的狀況下,block的大小設置爲每一個RegionServer 1GB也是常見的。
HFile的生成方式:
- 一、起初,HFile中並無任何Block,數據還存在於MemStore中
- 二、Flush發生時,建立HFile Writer,第一個空的Data Block出現,初始化後的Data Block中爲Header部分預留了空間,Header部分用來存放一個Data Block的元數據信息
- 三、然後,位於MemStore中的KeyValues被一個個append到位於內存中的第一個Data Block中
- 四、若是配置了Data Block Encoding,則會在Append KeyValue的時候進行同步編碼,編碼後的數據再也不是單純的KeyValue模式。Data Block Encoding是HBase爲了下降KeyValue結構性膨脹而提供的內部編碼機制
![初識 HBase](http://static.javashuo.com/static/loading.gif)
表結構及數據模型
HBase 是一個稀疏、多維度、排序的映射表,這張表的索引是行鍵、列簇、列限定符和時間戳。在 HBase 中每一個值都是一個未經解釋的字符串,沒有數據類型。用戶在表中存儲數據,每一行都有一個可排序的行鍵和任意多的列。
表在水平方向由一個或多個列簇組成,一個列簇中能夠包含任意多個列,同一個列簇裏面的數據存儲在一塊兒。列簇支持動態擴展,能夠很輕鬆地添加一個列簇或列,無需預先定義列的數量以及類型,全部列均以字符串形式存儲,用戶須要自行進行數據類型轉換。
在 HBase 中執行更新操做時,並不會刪除數據舊的版本,而是生成一個新的版本,舊的版本仍然保留(這是和HDFS只容許追加不容許修改的特性相關的),因此 HBase 的數據是版本化的。
![初識 HBase](http://static.javashuo.com/static/loading.gif)
- 表:HBase採用表來組織數據,表由行和列組成,列劃分爲若干列簇。
- 行:每一個HBase表都由若干行組成,每一行由行鍵(row key)來標識。
- 行鍵:每一行都會存在一個行鍵,能夠類比爲關係型數據庫中的主鍵
- 列簇:一個HBase表被分組成許多「列簇」(Column Family)的集合,列簇中的列是有序的,它是基本的訪問控制單元。在設計表時,列簇儘可能不超過5個,不然會影響性能。
- 列限定符:列簇裏的數據經過限定符(列名)來定位。每一個列簇中的列數是沒有限制的,列只有在插入數據後才存在
- 單元格:在HBase表中,經過行、列簇和列限定符肯定一個「單元格」(cell),單元格中存儲的數據沒有數據類型,總被視爲字節數組
byte[]
- 時間戳:每一個單元格都保存着同一份數據的多個版本,這些版本採用時間戳進行索引。
這是官方文檔中給出的一個示例表:
![初識 HBase](http://static.javashuo.com/static/loading.gif)
說明:
- 該表中包含兩行:
com.cnn.www
和com.example.www
- 有三個列簇:
contents
、anchor
和people
- 第一行(
com.cnn.www
)擁有5個版本,第二行(com.example.www
)擁有1個版本
- 對於第一行(
com.cnn.www
):
contents
列簇中包含一列:contents:html
anchor
列簇中包含兩列:anchor:cnnsi.com
和anchor:my.look.ca
cnnsi.com
列的值爲CNN
my.look.ca
列的值爲CNN.com
people
列簇中沒有任何列
- 對於第二行(
com.example.www
):
contents
列簇中包含一列:contents:html
anchor
列簇中沒有任何列
people
列簇中包含一列:people:author
使用json格式表示該表內容以下:
{
"com.cnn.www": {
contents: {
t6: contents:html: "<html>..."
t5: contents:html: "<html>..."
t3: contents:html: "<html>..."
}
anchor: {
t9: anchor:cnnsi.com = "CNN"
t8: anchor:my.look.ca = "CNN.com"
}
people: {}
}
"com.example.www": {
contents: {
t5: contents:html: "<html>..."
}
anchor: {}
people: {
t5: people:author: "John Doe"
}
}
}