Hbase是什麼數據庫
HBase是一種構建在HDFS之上的分佈式、面向列的存儲系統。在須要實時讀寫、隨機訪問超大規模數據集時,可使用HBase。數組
儘管已經有許多數據存儲和訪問的策略和實現方法,但事實上大多數解決方案,特別是一些關係類型的,在構建時並無考慮超大規模和分佈式的特色。許多商家經過複製和分區的方法來擴充數據庫使其突破單個節點的界限,但這些功能一般都是過後增長的,安裝和維護都和複雜。同時,也會影響RDBMS的特定功能,例如聯接、複雜的查詢、觸發器、視圖和外鍵約束這些操做在大型的RDBMS上的代價至關高,甚至根本沒法實現。緩存
HBase從另外一個角度處理伸縮性問題。它經過線性方式從下到上增長節點來進行擴展。HBase不是關係型數據庫,也不支持SQL,可是它有本身的特長,這是RDBMS不能處理的,HBase巧妙地將大而稀疏的表放在商用的服務器集羣上。服務器
HBase 是Google Bigtable 的開源實現,與Google Bigtable 利用GFS做爲其文件存儲系統相似, HBase 利用Hadoop HDFS 做爲其文件存儲系統;Google 運行MapReduce 來處理Bigtable中的海量數據, HBase 一樣利用Hadoop MapReduce來處理HBase中的海量數據;Google Bigtable 利用Chubby做爲協同服務, HBase 利用Zookeeper做爲對應。
網絡
HBase數據模型併發
Row Key負載均衡
與 NoSQL 數據庫同樣,Row Key 是用來檢索記錄的主鍵。訪問 HBase table 中的行,只有三種方式:分佈式
1)經過單個 Row Key 訪問。oop
2)經過 Row Key 的 range 全表掃描。性能
3)Row Key 可使任意字符串(最大長度是64KB,實際應用中長度通常爲 10 ~ 100bytes),在HBase 內部,Row Key 保存爲字節數組。
在存儲時,數據按照* Row Key 的字典序(byte order)排序存儲*。設計 Key 時,要充分排序存儲這個特性,將常常一塊兒讀取的行存儲到一塊兒(位置相關性)。
注意 字典序對 int 排序的結果是 1,10,100,11,12,13,14,15,16,17,18,19,20,21,…, 9,91,92,93,94,95,96,97,98,99。要保存整形的天然序,Row Key 必須用 0 進行左填充。
行的一次讀寫是原子操做(不論一次讀寫多少列)。這個設計決策可以使用戶很容易理解程序在對同一個行進行併發更新操做時的行爲。
列族
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 中的數據是沒有類型的,所有是字節碼形式存儲。
Hbase基本組件說明:
Client
包含訪問HBase的接口,並維護cache來加快對HBase的訪問,好比region的位置信息
Master
爲Region server分配region
負責Region server的負載均衡
發現失效的Region server並從新分配其上的region
管理用戶對table的增刪改查操做
Region Server
Regionserver維護region,處理對這些region的IO請求
Regionserver負責切分在運行過程當中變得過大的region
Zookeeper做用
經過選舉,保證任什麼時候候,集羣中只有一個master,Master與RegionServers 啓動時會向ZooKeeper註冊
存貯全部Region的尋址入口
實時監控Region server的上線和下線信息。並實時通知給Master
存儲HBase的schema和table元數據
默認狀況下,HBase 管理ZooKeeper 實例,好比, 啓動或者中止ZooKeeper
Zookeeper的引入使得Master再也不是單點故障
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上,所以master負載很低。
HRegion
table在行的方向上分隔爲多個Region。Region是HBase中分佈式存儲和負載均衡的最小單元,即不一樣的region能夠分別在不一樣的Region Server上,但同一個Region是不會拆分到多個server上。
Region按大小分隔,每一個表通常是隻有一個region。隨着數據不斷插入表,region不斷增大,當region的某個列族達到一個閾值(默認256M)時就會分紅兩個新的region。
每一個region由如下信息標識:
< 表名,startRowkey,建立時間>
由目錄表(-ROOT-和.META.)記錄該region的endRowkey
Region被分配給哪一個Region Server是徹底動態的,因此須要機制來定位Region具體在哪一個region server。
下面咱們來看看Region是如何被定位的。
HRegion定位
經過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,其中三次用來發現 緩存失效,另外三次用來獲取位置信息。
提示:
-ROOT-表:表包含.META.表所在的region列表,該表只有一個Region;Zookeeper中記錄了-ROOT-表的location
.META.表:表包含全部的用戶空間region列表,以及Region Server的服務器地址
Store
每個region由一個或多個store組成,至少是一個store,hbase會把一塊兒訪問的數據放在一個store裏面,即爲每一個 ColumnFamily建一個store,若是有幾個ColumnFamily,也就有幾個Store。一個Store由一個memStore和0或者 多個StoreFile組成。 HBase以store的大小來判斷是否須要切分region
MemStore
memStore 是放在內存裏的。保存修改的數據即keyValues。當memStore的大小達到一個閥值(默認64MB)時,memStore會被flush到文 件,即生成一個快照。目前hbase 會有一個線程來負責memStore的flush操做。
StoreFile
memStore內存中的數據寫到文件後就是StoreFile,StoreFile底層是以HFile的格式保存。
HLog
HLog(WAL log):WAL意爲write ahead log,用來作災難恢復使用,HLog記錄數據的全部變動,一旦region server 宕機,就能夠從log中進行恢復。
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。
LogFlusher
前面提到,數據以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實現。
LogRoller
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上進行恢復。