HBase 是一個高可靠、高性能、面向列、可伸縮的分佈式存儲系統,利用Hbase技術可在廉價PC Server上搭建 大規模結構化存儲集羣。jquery
HBase 是Google Bigtable 的開源實現,與Google Bigtable 利用GFS做爲其文件存儲系統相似, HBase 利用Hadoop HDFS 做爲其文件存儲系統;Google 運行MapReduce 來處理Bigtable中的海量數據, HBase 一樣利用Hadoop MapReduce來處理HBase中的海量數據;Google Bigtable 利用Chubby做爲協同服務, HBase 利用Zookeeper做爲對應。數據庫
HBase 中的表通常有如下特色。編程
1)大:一個表能夠有上億行,上百萬列。數組
2)面向列:面向列表(簇)的存儲和權限控制,列(簇)獨立檢索。緩存
3)稀疏:對於爲空(NULL)的列,並不佔用存儲空間,所以,表能夠設計的很是稀疏。安全
HBase 支持不少種訪問,訪問HBase的常見接口以下。網絡
一、Native Java API,最常規和高效的訪問方式,適合Hadoop MapReduce Job並行批處理HBase表數據。架構
二、HBase Shell,HBase的命令行工具,最簡單的接口,適合HBase管理使用。併發
三、Thrift Gateway,利用Thrift序列化技術,支持C++,PHP,Python等多種語言,適合其餘異構系統在線訪問HBase表數據。負載均衡
四、REST Gateway,支持REST 風格的Http API訪問HBase, 解除了語言限制。
五、Pig,可使用Pig Latin流式編程語言來操做HBase中的數據,和Hive相似,本質最終也是編譯成MapReduce Job來處理HBase表數據,適合作數據統計。
六、Hive,當前Hive的Release版本尚沒有加入對HBase的支持,但在下一個版本Hive 0.7.0中將會支持HBase,可使用相似SQL語言來訪問HBase。
從HBase的架構圖上能夠看出,HBase中的存儲包括HMaster、HRegionServer、HRegion、Store、MemStore、StoreFile、HFile、HLog等,本課程統一介紹他們的做用即存儲結構。 如下是 HBase 存儲架構圖:
HBase中的每張表都經過行鍵按照必定的範圍被分割成多個子表(HRegion),默認一個HRegion超過256M就要被分割成兩個,這個過程由HRegionServer管理,而HRegion的分配由HMaster管理。
HMaster
一、 爲Region server分配region。
二、 負責Region server的負載均衡。
三、發現失效的Region server並從新分配其上的region。
四、 HDFS上的垃圾文件回收。
五、 處理schema更新請求。
HRegionServer
一、 維護master分配給他的region,處理對這些region的io請求。
二、 負責切分正在運行過程當中變的過大的region。
能夠看到,client訪問hbase上的數據並不須要master參與(尋址訪問zookeeper和region server,數據讀寫訪問region server),master僅僅維護table和region的元數據信息(table的元數據信息保存在zookeeper上),負載很低。 HRegionServer存取一個子表時,會建立一個HRegion對象,而後對錶的每一個列族建立一個Store實例,每一個Store都會有一個MemStore和0個或多個StoreFile與之對應,每一個StoreFile都會對應一個HFile, HFile就是實際的存儲文件。所以,一個HRegion有多少個列族就有多少個Store。 一個HRegionServer會有多個HRegion和一個HLog。
table在行的方向上分隔爲多個Region。Region是HBase中分佈式存儲和負載均衡的最小單元,即不一樣的region能夠分別在不一樣的Region Server上,但同一個Region是不會拆分到多個server上。
Region按大小分隔,每一個表通常是隻有一個region。隨着數據不斷插入表,region不斷增大,當region的某個列族達到一個閾值(默認256M)時就會分紅兩個新的region。
每一個region由如下信息標識:
一、< 表名,startRowkey,建立時間>
二、由目錄表(-ROOT-和.META.)記錄該region的endRowkey
HRegion定位:Region被分配給哪一個Region Server是徹底動態的,因此須要機制來定位Region具體在哪一個region server。
HBase使用三層結構來定位region:
一、 經過zk裏的文件/hbase/rs獲得-ROOT-表的位置。-ROOT-表只有一個region。
二、經過-ROOT-表查找.META.表的第一個表中相應的region的位置。其實-ROOT-表是.META.表的第一個region;.META.表中的每個region在-ROOT-表中都是一行記錄。
三、經過.META.表找到所要的用戶表region的位置。用戶表中的每一個region在.META.表中都是一行記錄。
-ROOT-表永遠不會被分隔爲多個region,保證了最多須要三次跳轉,就能定位到任意的region。client會將查詢的位置信息保存緩存起來,緩存不會主動失效,所以若是client上的緩存所有失效,則須要進行6次網絡來回,才能定位到正確的region,其中三次用來發現緩存失效,另外三次用來獲取位置信息。
每個region由一個或多個store組成,至少是一個store,hbase會把一塊兒訪問的數據放在一個store裏面,即爲每一個ColumnFamily建一個store,若是有幾個ColumnFamily,也就有幾個Store。一個Store由一個memStore和0或者多個StoreFile組成。 HBase以store的大小來判斷是否須要切分region。
memStore 是放在內存裏的。保存修改的數據即keyValues。當memStore的大小達到一個閥值(默認64MB)時,memStore會被flush到文件,即生成一個快照。目前hbase 會有一個線程來負責memStore的flush操做。
memStore內存中的數據寫到文件後就是StoreFile,StoreFile底層是以HFile的格式保存。
HBase中KeyValue數據的存儲格式,是hadoop的二進制格式文件。 首先HFile文件是不定長的,長度固定的只有其中的兩塊:Trailer和FileInfo。Trailer中有指針指向其餘數據塊的起始點,FileInfo記錄了文件的一些meta信息。 Data Block是hbase io的基本單元,爲了提升效率,HRegionServer中有基於LRU的block cache機制。每一個Data塊的大小能夠在建立一個Table的時候經過參數指定(默認塊大小64KB),大號的Block有利於順序Scan,小號的Block利於隨機查詢。每一個Data塊除了開頭的Magic之外就是一個個KeyValue對拼接而成,Magic內容就是一些隨機數字,目的是防止數據損壞,結構以下。
HFile結構圖以下:
Data Block段用來保存表中的數據,這部分能夠被壓縮。 Meta Block段(可選的)用來保存用戶自定義的kv段,能夠被壓縮。 FileInfo段用來保存HFile的元信息,不能被壓縮,用戶也能夠在這一部分添加本身的元信息。 Data Block Index段(可選的)用來保存Meta Blcok的索引。 Trailer這一段是定長的。保存了每一段的偏移量,讀取一個HFile時,會首先讀取Trailer,Trailer保存了每一個段的起始位置(段的Magic Number用來作安全check),而後,DataBlock Index會被讀取到內存中,這樣,當檢索某個key時,不須要掃描整個HFile,而只需從內存中找到key所在的block,經過一次磁盤io將整個 block讀取到內存中,再找到須要的key。DataBlock Index採用LRU機制淘汰。 HFile的Data Block,Meta Block一般採用壓縮方式存儲,壓縮以後能夠大大減小網絡IO和磁盤IO,隨之而來的開銷固然是須要花費cpu進行壓縮和解壓縮。目標HFile的壓縮支持兩種方式:gzip、lzo。
另外,針對目前針對現有HFile的兩個主要缺陷:
a) 佔用過多內存
b) 啓動加載時間緩慢
基於此缺陷,提出了HFile Version2設計。
其實HLog文件就是一個普通的Hadoop Sequence File, Sequence File的value是key時HLogKey對象,其中記錄了寫入數據的歸屬信息,除了table和region名字外,還同時包括sequence number和timestamp,timestamp是寫入時間,sequence number的起始值爲0,或者是最近一次存入文件系統中的sequence number。 Sequence File的value是HBase的KeyValue對象,即對應HFile中的KeyValue。
HLog(WAL log):WAL意爲write ahead log,用來作災難恢復使用,HLog記錄數據的全部變動,一旦region server 宕機,就能夠從log中進行恢復。
前面提到,數據以KeyValue形式到達HRegionServer,將寫入WAL以後,寫入一個SequenceFile。看過去沒問題,可是由於數據流在寫入文件系統時,常常會緩存以提升性能。這樣,有些本覺得在日誌文件中的數據實際在內存中。這裏,咱們提供了一個LogFlusher的類。它調用HLog.optionalSync(),後者根據 hbase.regionserver.optionallogflushinterval (默認是10秒),按期調用Hlog.sync()。另外,HLog.doWrite()也會根據 hbase.regionserver.flushlogentries (默認100秒)按期調用Hlog.sync()。Sync() 自己調用HLog.Writer.sync(),它由SequenceFileLogWriter實現。
Log的大小經過$HBASE_HOME/conf/hbase-site.xml 的 hbase.regionserver.logroll.period 限制,默認是一個小時。因此每60分鐘,會打開一個新的log文件。長此以往,會有一大堆的文件須要維護。首先,LogRoller調用HLog.rollWriter(),定時滾動日誌,以後,利用HLog.cleanOldLogs()能夠清除舊的日誌。它首先取得存儲文件中的最大的sequence number,以後檢查是否存在一個log全部的條目的「sequence number」均低於這個值,若是存在,將刪除這個log。 每一個region server維護一個HLog,而不是每個region一個,這樣不一樣region(來自不一樣的table)的日誌會混在一塊兒,這樣作的目的是不斷追加單個文件相對於同時寫多個文件而言,能夠減小磁盤尋址次數,所以能夠提升table的寫性能。帶來麻煩的時,若是一個region server下線,爲了恢復其上的region,須要將region server上的log進行拆分,而後分發到其餘region server上進行恢復。
HBase 中的每一張表就是所謂的 BigTable。BigTable 會存儲一系列的行記錄,行記錄有三個基本類型的定義:Row Key、Time Stamp、Column。
一、Row Key 是行在 BigTable 中的惟一標識。
二、Time Stamp 是每次數據操做對應關聯的時間戳,能夠看作 SVN 的版本。
三、Column 定義爲< family>:< label>,經過這兩部分能夠指定惟一的數據的存儲列,family 的定義和修改須要 對 HBase 進行相似於 DB 的 DDL 操做,而 label ,不須要定義直接可使用,這也爲動態定製列提供了一種手段 。family 另外一個做用體如今物理存儲優化讀寫操做上,同 family 的數據物理上保存的會比較臨近,所以在業務設計的過程當中能夠利用這個特性。
HBase 以表的形式存儲數據。表由行和列組成。列劃分爲若干個列族(row family),以下圖所示。
一、 Row Key
與 NoSQL 數據庫同樣,Row Key 是用來檢索記錄的主鍵。訪問 HBase table 中的行,只有三種方式:
1)經過單個 Row Key 訪問。
2)經過 Row Key 的 range 全表掃描。
3)Row Key 可使任意字符串(最大長度是64KB,實際應用中長度通常爲 10 ~ 100bytes),在HBase 內部,Row Key 保存爲字節數組。
在存儲時,數據按照 Row Key 的字典序(byte order)排序存儲。設計 Key 時,要充分排序存儲這個特性,將常常一塊兒讀取的行存儲到一塊兒(位置相關性)。
行的一次讀寫是原子操做(不論一次讀寫多少列)。這個設計決策可以使用戶很容易理解程序在對同一個行進行併發更新操做時的行爲。
二、 列族
HBase 表中的每一個列都歸屬於某個列族。列族是表的 Schema 的一部分(而列不是),必須在使用表以前定義。列名都以列族做爲前綴,例如 courses:history、courses:math 都屬於 courses 這個列族。
訪問控制、磁盤和內存的使用統計都是在列族層面進行的。在實際應用中,列族上的控制權限能幫助咱們管理不一樣類型的應用, 例如,容許一些應用能夠添加新的基本數據、一些應用能夠讀取基本數據並建立繼承的列族、一些應用則只容許瀏覽數據(甚至可能由於隱私的緣由不能瀏覽全部數據)。
三、 時間戳
HBase 中經過 Row 和 Columns 肯定的一個存儲單元稱爲 Cell。每一個 Cell 都保存着同一份數據的多個版本。 版本經過時間戳來索引,時間戳的類型是 64 位整型。時間戳能夠由HBase(在數據寫入時自動)賦值,此時時間戳是精確到毫秒的當前系統時間。時間戳也 能夠由客戶顯示賦值。若是應用程序要避免數據版本衝突,就必須本身生成具備惟一性的時間戳。每一個 Cell 中,不一樣版本的數據按照時間倒序排序,即最新的數據排在最前面。
爲了不數據存在過多版本形成的管理(包括存儲和索引)負擔,HBase 提供了兩種數據版本回收方式。 一是保存數據的最後 n 個版本,二是保存最近一段時間內的版本(好比最近七天)。用戶能夠針對每一個列族進行設置。
四、 Cell
Cell 是由 {row key,column(=< family> + < label>),version} 惟一肯定的單元。Cell 中的數據是沒有類型的,所有是字節碼形式存儲。
Table 在行的方向上分割爲多個HRegion,每一個HRegion分散在不一樣的RegionServer中。
每一個HRegion由多個Store構成,每一個Store由一個memStore和0或多個StoreFile組成,每一個Store保存一個Columns Family
StoreFile以HFile格式存儲在HDFS中。