一、HBase概況介紹
HBase是一個高可靠性、高性能、面向列、可伸縮的分布式存儲系統,利用HBase技術可在廉價PC Server上搭建大規模結構化的存儲集群。HBase的目標是存儲并處理大型數據,具體來說是僅需使用普通的硬件配置,就能夠處理由成千上萬的行和列所組成的大型數據。
與MapReduce的離線批處理計算框架不同,HBase是一個可以隨機訪問的存儲和檢索數據平臺,彌補了HDFS不能隨機訪問數據的缺陷,適合實時性要求不是非常高的業務場景。HBase存儲的都是Byte數組,它不介意數據類型,允許動態、靈活的數據模型。
HBase的特點
· 大:一個表可以有上億行,上百萬列。
· 面向列:面向列表(簇)的存儲和權限控制,列(簇)獨立檢索。
· 稀疏:對于為空(NULL)的列,并不占用存儲空間,因此,表可以設計的非常稀疏。
· 無模式:每一行都有一個可以排序的主鍵和任意多的列,列可以根據需要動態增加,同一張表中不同的行可以有截然不同的列。
· 數據多版本:每個單元中的數據可以有多個版本,默認情況下,版本號自動分配,版本號就是單元格插入時的時間戳。
· 數據類型單一:HBase中的數據都是字符串,沒有類型。
HBase 的應用場景
HBase 不適合所有場景。
首先,確信有足夠多數據,如果有上億或上千億行數據,HBase 是很好的備選。如果只有上千或上百萬行,則用傳統的R DBMS 可能是更好的選擇。因為所有數據可以在一兩個節點保存,集群其他節點可能閑置。
其次,確信可以不依賴所有 RDBMS 的額外特性(例如,列數據類型、 第二索引、事務、高級查詢語言等)。
第三,確信你有足夠的硬件。因為 HDFS 在小于5個數據節點時,基本上體現不出它的優勢。
雖然,HBase 能在單獨的筆記本上運行良好,但這應僅當成是開發階段的配置。
二、HBase體系結構
2.1 設計思路
HBase是一個分布式的數據庫,使用Zookeeper管理集群,使用HDFS作為底層存儲。在架構層面上由HMaster(Zookeeper選舉產生的Leader)和多個HRegionServer組成,基本架構如下圖所示:
在HBase的概念中,HRegionServer對應集群中的一個節點,一個HRegionServer負責管理多個HRegion,而一個HRegion代表一張表的一部分數據。在HBase中,一張表可能會需要很多個HRegion來存儲數據,每個HRegion中的數據并不是雜亂無章的。HBase在管理HRegion的時候會給每個HRegion定義一個Rowkey的范圍,落在特定范圍內的數據將交給特定的Region,從而將負載分攤到多個節點,這樣就充分利用了分布式的優點和特性。另外,HBase會自動調節Region所處的位置,如果一個HRegionServer過熱,即大量的請求落在這個HRegionServer管理的HRegion上,HBase就會把HRegion移動到相對空閑的其它節點,依次保證集群環境被充分利用。
2.2基本架構
HBase由HMaster和HRegionServer組成,同樣遵從主從服務器架構。HBase將邏輯上的表劃分成多個數據塊即HRegion,存儲在HRegionServer中。HMaster負責管理所有的HRegionServer,它本身并不存儲任何數據,而只是存儲數據到HRegionServer的映射關系(元數據)。集群中的所有節點通過Zookeeper進行協調,并處理HBase運行期間可能遇到的各種問題。?
三、 HBase數據模型
HBase是一個類似于BigTable的分布式數據庫,它是一個稀疏的長期存儲的(存在HDFS上)、多維度的、排序的映射表。這張表的索引是行關鍵字、列關鍵字和時間戳。HBase的數據都是字符串,沒有類型。?
? ? ?可以將一個表想象成一個大的映射關系,通過行鍵、行鍵+時間戳或行鍵+列(列族:列修飾符),就可以定位特定數據。由于HBase是稀疏存儲數據的,所以某些列可以是空白的。上表給出了com.cnn.www網站的數據存放邏輯視圖,表中僅有一行數據,行的唯一標識為“com.cnn.www”,對這行數據的每一次邏輯修改都有一個時間戳關聯對應。表中共有四列:contents:html、anchor:cnnsi.com、anchor:my.look.ca、mime:type,每一列以前綴的方式給出其所屬的列族。
行鍵(RowKey)是數據行在表中的唯一標識,并作為檢索記錄的主鍵。在HBase中訪問表中的行只有三種方式:通過某個行鍵訪問、給定行鍵的范圍訪問、全表掃描。行鍵可以是任意字符串(最大長度64KB)并按照字典序進行存儲。對于那些經常一起讀取的行,需要對鍵值精心設計,以便它們能放在一起存儲。
四、 HBase讀寫流程
下圖是HRegionServer數據存儲關系圖。上文提到,HBase使用MemStore和StoreFile存儲對表的更新。數據在更新時首先寫入HLog和MemStore。MemStore中的數據是排序的,當MemStore累計到一定閾值時,就會創建一個新的MemStore,并且將老的MemStore添加到Flush隊列,由單獨的線程Flush到磁盤上,成為一個StoreFile。與此同時,系統會在Zookeeper中記錄一個CheckPoint,表示這個時刻之前的數據變更已經持久化了。當系統出現意外時,可能導致MemStore中的數據丟失,此時使用HLog來恢復CheckPoint之后的數據。
StoreFile是只讀的,一旦創建后就不可以再修改。因此Hbase的更新其實是不斷追加的操作。當一個Store中的StoreFile達到一定閾值后,就會進行一次合并操作,將對同一個key的修改合并到一起,形成一個大的StoreFile。當StoreFile的大小達到一定閾值后,又會對 StoreFile進行切分操作,等分為兩個StoreFile。
寫操作流程
步驟1:Client通過Zookeeper的調度,向HRegionServer發出寫數據請求,在HRegion中寫數據。
步驟2:數據被寫入HRegion的MemStore,直到MemStore達到預設閾值。
步驟3:MemStore中的數據被Flush成一個StoreFile。
步驟4:隨著StoreFile文件的不斷增多,當其數量增長到一定閾值后,觸發Compact合并操作,將多個StoreFile合并成一個StoreFile,同時進行版本合并和數據刪除。
步驟5:StoreFiles通過不斷的Compact合并操作,逐步形成越來越大的StoreFile。
步驟6:單個StoreFile大小超過一定閾值后,觸發Split操作,把當前HRegion Split成2個新的HRegion。父HRegion會下線,新Split出的2個子HRegion會被HMaster分配到相應的HRegionServer 上,使得原先1個HRegion的壓力得以分流到2個HRegion上。
讀操作流程
步驟1:client訪問Zookeeper,查找-ROOT-表,獲取.META.表信息。
步驟2:從.META.表查找,獲取存放目標數據的HRegion信息,從而找到對應的HRegionServer。
步驟3:通過HRegionServer獲取需要查找的數據。
步驟4:HRegionserver的內存分為MemStore和BlockCache兩部分,MemStore主要用于寫數據,BlockCache主要用于讀數據。讀請求先到MemStore中查數據,查不到就到BlockCache中查,再查不到就會到StoreFile上讀,并把讀的結果放入BlockCache。
hbase工作原理
Client
首先當一個請求產生時,HBase Client使用RPC(遠程過程調用)機制與HMaster和HRegionServer進行通信,對于管理類操作,Client與HMaster進行RPC;對于數據讀寫操作,Client與HRegionServer進行RPC。
Zookeeper
HBase Client使用RPC(遠程過程調用)機制與HMaster和HRegionServer進行通信,但如何尋址呢?由于Zookeeper中存儲了-ROOT-表的地址和HMaster的地址,所以需要先到Zookeeper上進行尋址。
HRegionServer也會把自己以Ephemeral方式注冊到Zookeeper中,使HMaster可以隨時感知到各個HRegionServer的健康狀態。此外,Zookeeper也避免了HMaster的單點故障。
HMaster
當用戶需要進行Table和Region的管理工作時,就需要和HMaster進行通信。HBase中可以啟動多個HMaster,通過Zookeeper的Master Eletion機制保證總有一個Master運行。
· 管理用戶對Table的增刪改查操作
· 管理HRegionServer的負載均衡,調整Region的分布
· 在Region Split后,負責新Region的分配
· 在HRegionServer停機后,負責失效HRegionServer上的Regions遷移
HRegionServer
當用戶需要對數據進行讀寫操作時,需要訪問HRegionServer。HRegionServer存取一個子表時,會創建一個HRegion對象,然后對表的每個列族創建一個Store實例,每個Store都會有一個 MemStore和0個或多個StoreFile與之對應,每個StoreFile都會對應一個HFile, HFile就是實際的存儲文件。因此,一個HRegion有多少個列族就有多少個Store。 一個HRegionServer會有多個HRegion和一個HLog。
當HStore存儲是HBase的核心了,其中由兩部分組成:MemStore和StoreFiles。 MemStore是Sorted Memory Buffer,用戶
寫入數據首先 會放在MemStore,當MemStore滿了以后會Flush成一個 StoreFile(實際存儲在HDHS上的是HFile),當StoreFile文件數量增長到一定閥值,就會觸發Compact合并操作,并將多個StoreFile合并成一個StoreFile,合并過程中會進行版本合并和數據刪除,因此可以看出HBase其實只有增加數據,所有的更新和刪除操作都是在后續的compact過程中進行的,這使得用戶的 讀寫操作只要進入內存中就可以立即返回,保證了HBase I/O的高性能。
下面以一個具體數據Put的流程,讓我們加深對HBase工作流程的認識。
HBase Put流程
下面是put流程的時序圖:
客戶端:
· 客戶端發起Put寫請求,講put寫入writeBuffer,如果是批量提交,寫滿緩存后自動提交
· 根據rowkey將put吩咐給不同regionserver
服務端:
· RegionServer將put按rowkey分給不同的region
· Region首先把數據寫入wal
· wal寫入成功后,把數據寫入memstore
· Memstore寫完后,檢查memstore大小是否達到flush閥值
· 如果達到flush閥值,將memstore寫入HDFS,生成HFile文件
HBase Compact &&Split
當StoreFile文件數量增長到一定閥值,就會觸發Compact合并操作,并將多個StoreFile合并成一個StoreFile,當這個StoreFile大小超過一定閥值后,會觸發Split操作,同時把當前Region Split成2個Region,這是舊的Region會下線,新Split出的2個Region會被HMaster分配到相應的HregionServer上,使得原先1個Region的壓力得以分散到2個Region上。
如下圖四個Storefile文件(從memstore文件經過flush而得到,默認64M的storefile文件)經過Compact合并成一個大的256M storefile文件,當設定的Region閥值為128M時,就會Split為兩個128M的Storefile文件,然后HMaster再把這兩個storefile文件分配到不停地Regionserver上。
HFile
HBase中所有的數據文件都存儲在Hadoop HDFS上,主要包括兩種文件類型:
· Hfile:HBase中KeyValue數據的存儲格式,HFile是Hadoop的 二進制格式文件,實際上StoreFile就是對Hfile做了輕量級包裝,即StoreFile底層就是HFile
· HLog File:HBase中WAL(write ahead log)的存儲格式,物理上是Hadoop的Sequence File
HFile的存儲格式如下:
?
HFile文件是不定長的,長度固定的只有其中的兩塊:Trailer和FileInfo。
Trailer中有指針指向其他數據塊的起始點,FileInfo記錄了文件的一些meta信息。 Data Block是hbase io的基本單元,為了提高效率,HRegionServer中有基于LRU的block cache機制。
每個Data塊的大小可以在創建一個Table的時候通過參數指定(默認塊大小64KB),大號的Block有利于順序Scan,小號的 Block利于隨機查詢。
每個Data塊除了開頭的Magic以外就是一個個KeyValue對拼接而成,Magic內容就是一些隨機數字,目的是防止數 據損壞,結構如下。
?
上圖可知,開始是兩個固定長度的數值,分別表示key的長度和alue的長度。緊接著是Key,開始是固定長度的數值,表示RowKey的長度,緊接著是RowKey,然后是固定長度的數值,表示Family的長度,然后是Family,接著是Qualifier,然后是兩個固定長度的數值,表示Time Stamp和Key Type(Put/Delete)。Value部分沒有那么復雜的結構,就是純粹的二進制數據。
HBase的三維有序(即字典順序)存儲
Hfile是HBase中KeyValue數據的存儲格式。從上面的 HBase物理數據模型中可以看出,HBase是面向列表(簇)的存儲。每個Cell由 {row key,column(=《 family》 + 《 label》),version} 唯一確定的單元,他們組合在一起就是一個KeyValue。根據上述描述,這個KeyValue中的key就是{row key,column(=《 family》 + 《 label》),version} ,而value就是cell中的值。
HBase的三維有序存儲中的三維是指:rowkey(行主鍵),column key(columnFamily+《 label》),timestamp(時間戳或者版本號)三部分組成的三維有序存儲。
· rowkey
rowkey是行的主鍵,它是以字典順序排序的。所以 rowkey的設計是至關重要的,關系到你應用層的查詢效率。我們在根據rowkey范圍查詢的時候,我們一般是知道startRowkey,如果我們通過scan只傳startRowKey : d開頭的,那么查詢的是所有比d大的都查了,而我們只需要d開頭的數據,那就要通過endRowKey來限制。我們可以通過設定endRowKey為:d 開頭,后面的根據你的rowkey組合來設定,一般是加比startKey大一位。
· column key
column key是第二維,數據按rowkey字典排序后,如果rowkey相同,則是根據column key來排序的,也是按字典排序。
我們在設計table的時候要學會利用這一點。比如我們的收件箱。我們有時候需要按主題排序,那我們就可以把主題這設置為我們的column key,即設計為columnFamily+主題。,這樣的設計。
· timestamp
timestamp 時間戳,是第三維,這是個按降序排序的,即最新的數據排在最前面。這個就沒有什么說的了。網上其他的博客也提到比較多。
HLog Replay
根據以上的敘述,我們已經了解了關于HStore的基本原理,但我們還必須要了解一下HLog的功能,因為上述的HStore在系統正常工作的前提下是沒問題的,但是在分布式 系統環境中,無法避免系統出錯或者宕機,因為一旦HRegionServer意外退出,MemStore中的內存數據將會丟失,這就需要引入HLog。每個HRegionServer中都有一個HLog對象,HLog是一個實現Write Ahead Log的類,在每一次用戶操作寫入MemStore的同時,也會寫一份數據到HLog文件中,HLog文件定期(當文件已持久化到StoreFile中的數據)會滾出新的,并且刪除舊的文件。當HRegionServer意外終止 后,HMaster會通過Zookeeper感知到,HMaster首先會處理遺留的Hlog文件,將其中不同Region的Log數據進行拆分,分別放到相應Region的目錄下,然后再將失效的Region重新分配,領取到這些Region的Regionserver在Load Region的過程中,會發現歷史HLog需要處理,因此Replay HLog中的數據到MemStore中,然后flush到StoreFiles,完成數據恢復。
HLog存儲格式
WAL(Write Ahead Log):RegionServer在處理插入和刪除過程中,用來記錄操作內容的日志,只有日志寫入成功,才會通知客戶端操作成功。
上圖中是HLog文件的結構,其實HLog文件就是一個普通的Hadoop Sequence File,Sequence File的Key是HLogKey對象,HLogKey中記錄了寫入數據的歸屬信息,除了table和Region名字外,同時還包括sequence number和timestamp,timestamp是”寫入時間”,sequence number 的起始值為0,或者是最近一次存入文件系統中的sequence number。
HLog Sequence File 的Value是HBase的KeyValue對象昂,即對應HFile中的KeyValue。
HBase性能和優化影響HBase性能的因素
?
評論