1、什麼是HBase
HBase是一個高可靠、高性能、面向列、可伸縮的分佈式存儲系統,利用HBase技術可在廉價的PC Server上搭建大規模結構化存儲集羣。
HBase是Google BigTable的開源實現,與Google BigTable利用GFS做爲其文件存儲系統相似,HBase利用Hadoop HDFS做爲其文件存儲系統;
Google運行MapReduce來處理BigTable中的海量數據,HBase一樣利用Hadoop MapReduce來處理HBase中的海量數據;
Google BigTable利用Chubby做爲協同服務,HBase利用Zookeeper做爲協同服務。
2、HBase設計模型
HBase中的每一張表就是所謂的BigTable。BigTable會存儲一系列的行記錄,行記錄有三個基本類型的定義:
是行在BigTable中的惟一標識。
是每一次數據操做對應關聯的時間戳,能夠看做SVN的版本。
定義爲<family>:<label>,經過這兩部分能夠指定惟一的數據的存儲列,family的定義和修改須要對HBase進行相似於DB的DDL操做,
而label,不須要定義直接可使用,這也爲動態定製列提供了一種手段。family另外一個做用體如今物理存儲優化讀寫操做上,同family
的數據物理上保存的會比較接近,所以在業務設計的過程當中能夠利用這個特性。
1. 邏輯存儲模型
HBase以表的形式存儲數據,表由行和列組成。列劃分爲若干個列簇,以下圖所示:
下面是對錶中元素的詳細解析:
RowKey
與NoSQL數據庫同樣,rowkey是用來檢索記錄的主鍵。訪問HBase Table中的行,只有三種方式:
- 經過單個rowkey訪問
- 經過rowkey的range
- 全表掃描
rowkey行鍵能夠任意字符串(最大長度64KB,實際應用中長度通常爲10-100bytes),在HBase內部RowKey保存爲字節數組。
存儲時,數據按照RowKey的字典序(byte order)排序存儲,設計key時,要充分了解這個特性,將常常一塊兒讀取的行存放在一塊兒。
須要注意的是:行的一次讀寫是原子操做(不論一次讀寫多少列)
列簇
HBase表中的每一個列,都歸屬於某個列簇,列簇是表的schema的一部分(而列不是),必須在使用表以前定義。列名都以列簇做爲前綴。例如:
courses:history, courses:math 都屬於 courses 這個列簇。
訪問控制,磁盤和內存的使用統計都是在列簇層面進行的。
實際應用中,列簇上的控制權限能幫助咱們管理不一樣類型的應用:咱們容許一些應用能夠添加新的基本數據、
一些應用能夠讀取基本數據並建立繼承的列簇、一些應用則只容許瀏覽數據(設置可能由於隱私的緣由不能瀏覽全部數據)。
時間戳
HBase中經過row和columns肯定的爲一個存儲單元稱爲cell。每一個cell都保存着同一份數據的多個版本。版本經過時間戳來索引。
時間戳的類型是64位整型。時間戳能夠由HBase在寫入時自動賦值,此時時間戳是精確到毫秒的當前系統時間。時間戳也能夠由客戶顯示賦值。
若是應用程序要避免數據版本衝突,就必須本身生成具備惟一性的時間戳。每一個cell中在不一樣版本的數據按照時間倒序排序,即最新的數據排在最前面。
爲了不數據存在過多的版本形成的管理負擔,HBase提供了兩種數據版本回收方式。一是保存數據的最後n個版本,二是保存最近一段時間內的版本
(好比最近七天)。用戶能夠針對每一個列簇進行設置。
Cell
由{row key, column(=+), version} 惟一肯定的單元。cell中的數據是沒有類型的,所有是字節碼形式存儲。
2. 物理存儲模型
Table在行的方向上分割爲多個HRegion,每一個HRegion分散在不一樣的RegionServer中。
每一個HRegion由多個Store構成,每一個Store由一個MemStore和0或多個StoreFile組成,每一個Store保存一個Columns Family
StoreFile以HFile格式存儲在HDFS中。
3、HBase存儲架構
從HBase的架構圖上能夠看出,HBase中的存儲包括HMaster、HRegionSever、HRegion、HLog、Store、MemStore、StoreFile、HFile等,如下是HBase存儲架構圖:
HBase中的每張表都經過鍵按照必定的範圍被分割成多個子表(HRegion),默認一個HRegion超過256M就要被分割成兩個,這個過程由HRegionServer管理,
而HRegion的分配由HMaster管理。
HMaster的做用:
- 爲HRegionServer分配HRegion
- 負責HRegionServer的負載均衡
- 發現失效的HRegionServer並從新分配
- HDFS上的垃圾文件回收
- 處理Schema更新請求
HRegionServer的做用:
- 維護HMaster分配給它的HRegion,處理對這些HRegion的IO請求
- 負責切分正在運行過程當中變得過大的HRegion
能夠看到,Client訪問HBase上的數據並不須要HMaster參與,尋址訪問ZooKeeper和HRegionServer,數據讀寫訪問HRegionServer,
HMaster僅僅維護Table和Region的元數據信息,Table的元數據信息保存在ZooKeeper上,負載很低。HRegionServer存取一個子表時,
會建立一個HRegion對象,而後對錶的每一個列簇建立一個Store對象,每一個Store都會有一個MemStore和0或多個StoreFile與之對應,
每一個StoreFile都會對應一個HFile,HFile就是實際的存儲文件。所以,一個HRegion有多少列簇就有多少個Store。
一個HRegionServer會有多個HRegion和一個HLog。
HRegion
Table在行的方向上分割爲多個HRegion,HRegion是HBase中分佈式存儲和負載均衡的最小單元,即不一樣的HRegion能夠分別在不一樣的HRegionServer上,
但同一個HRegion是不會拆分到多個HRegionServer上的。HRegion按大小分割,每一個表通常只有一個HRegion,隨着數據不斷插入表,HRegion不斷增大,
當HRegion的某個列簇達到一個閥值(默認256M)時就會分紅兩個新的HRegion。
一、<表名,StartRowKey, 建立時間>
二、由目錄表(-ROOT-和.META.)記錄該Region的EndRowKey
HRegion定位:HRegion被分配給哪一個HRegionServer是徹底動態的,因此須要機制來定位HRegion具體在哪一個HRegionServer,HBase使用三層結構來定位HRegion:
一、經過zk裏的文件/hbase/rs獲得-ROOT-表的位置。-ROOT-表只有一個region。
二、經過-ROOT-表查找.META.表的第一個表中相應的HRegion位置。其實-ROOT-表是.META.表的第一個region;
.META.表中的每個Region在-ROOT-表中都是一行記錄。
三、經過.META.表找到所要的用戶表HRegion的位置。用戶表的每一個HRegion在.META.表中都是一行記錄。
-ROOT-表永遠不會被分隔爲多個HRegion,保證了最多須要三次跳轉,就能定位到任意的region。Client會將查詢的位置信息保存緩存起來,緩存不會主動失效,
所以若是Client上的緩存所有失效,則須要進行6次網絡來回,才能定位到正確的HRegion,其中三次用來發現緩存失效,另外三次用來獲取位置信息。
Store
每個HRegion由一個或多個Store組成,至少是一個Store,HBase會把一塊兒訪問的數據放在一個Store裏面,即爲每一個ColumnFamily建一個Store,
若是有幾個ColumnFamily,也就有幾個Store。一個Store由一個MemStore和0或者多個StoreFile組成。 HBase以Store的大小來判斷是否須要切分HRegion。
MemStore
MemStore 是放在內存裏的,保存修改的數據即keyValues。當MemStore的大小達到一個閥值(默認64MB)時,MemStore會被Flush到文件,
即生成一個快照。目前HBase會有一個線程來負責MemStore的Flush操做。
StoreFile
MemStore內存中的數據寫到文件後就是StoreFile,StoreFile底層是以HFile的格式保存。
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進行壓縮和解壓縮。(備註: DataBlock Index的缺陷。 a) 佔用過多內存 b) 啓動加載時間緩慢)
HLog
HLog(WAL log):WAL意爲write ahead log,用來作災難恢復使用,HLog記錄數據的全部變動,一旦region server 宕機,就能夠從log中進行恢復。
LogFlusher
按期的將緩存中信息寫入到日誌文件中
LogRoller
對日誌文件進行管理維護