本文首先簡單介紹了HBase,然后重點(diǎn)講述了HBase的高并發(fā)和實(shí)時處理數(shù)據(jù) 奔垦、HBase數(shù)據(jù)模型痹屹、HBase物理存儲、HBase系統(tǒng)架構(gòu)蟀拷,HBase調(diào)優(yōu)、HBase Shell訪問等萍聊。
不過在此之前问芬,你可以先了解?Hadoop生態(tài)系統(tǒng)?,若想運(yùn)行HBase寿桨,則需要先搭建好Hadoop集群環(huán)境此衅,可以參考此文搭建5個節(jié)點(diǎn)的hadoop集群環(huán)境(CDH5)?。
好了亭螟,讓我們來學(xué)習(xí)HBase吧挡鞍!
2006年底由PowerSet 的Chad Walters和Jim Kellerman 發(fā)起,2008年成為Apache Hadoop的一個子項(xiàng)目≡だ樱現(xiàn)已作為產(chǎn)品在多家企業(yè)被使用墨微,如:
WorldLingo
Streamy.com
OpenPlaces
Yahoo!
Adobe
淘寶
Trend Micro
HBase是一種構(gòu)建在HDFS之上的分布式、面向列的存儲系統(tǒng)扁掸。在需要實(shí)時讀寫翘县、隨機(jī)訪問超大規(guī)模數(shù)據(jù)集時最域,可以使用HBase。
盡管已經(jīng)有許多數(shù)據(jù)存儲和訪問的策略和實(shí)現(xiàn)方法炼蹦,但事實(shí)上大多數(shù)解決方案羡宙,特別是一些關(guān)系類型的,在構(gòu)建時并沒有考慮超大規(guī)模和分布式的特點(diǎn)掐隐。許多商家通過復(fù)制和分區(qū)的方法來擴(kuò)充數(shù)據(jù)庫使其突破單個節(jié)點(diǎn)的界限狗热,但這些功能通常都是事后增加的,安裝和維護(hù)都和復(fù)雜虑省。同時匿刮,也會影響RDBMS的特定功能,例如聯(lián)接探颈、復(fù)雜的查詢熟丸、觸發(fā)器、視圖和外鍵約束這些操作在大型的RDBMS上的代價相當(dāng)高伪节,甚至根本無法實(shí)現(xiàn)光羞。
HBase從另一個角度處理伸縮性問題。它通過線性方式從下到上增加節(jié)點(diǎn)來進(jìn)行擴(kuò)展怀大。HBase不是關(guān)系型數(shù)據(jù)庫纱兑,也不支持SQL,但是它有自己的特長化借,這是RDBMS不能處理的潜慎,HBase巧妙地將大而稀疏的表放在商用的服務(wù)器集群上。
HBase 是Google Bigtable 的開源實(shí)現(xiàn)蓖康,與Google Bigtable 利用GFS作為其文件存儲系統(tǒng)類似铐炫, HBase 利用Hadoop HDFS 作為其文件存儲系統(tǒng);Google 運(yùn)行MapReduce 來處理Bigtable中的海量數(shù)據(jù)蒜焊, HBase 同樣利用Hadoop MapReduce來處理HBase中的海量數(shù)據(jù)倒信;Google Bigtable 利用Chubby作為協(xié)同服務(wù), HBase 利用Zookeeper作為對應(yīng)泳梆。
大:一個表可以有上億行堤结,上百萬列。
面向列:面向列表(簇)的存儲和權(quán)限控制鸭丛,列(簇)獨(dú)立檢索竞穷。
稀疏:對于為空(NULL)的列,并不占用存儲空間鳞溉,因此瘾带,表可以設(shè)計(jì)的非常稀疏。
無模式:每一行都有一個可以排序的主鍵和任意多的列熟菲,列可以根據(jù)需要動態(tài)增加看政,同一張表中不同的行可以有截然不同的列朴恳。
數(shù)據(jù)多版本:每個單元中的數(shù)據(jù)可以有多個版本,默認(rèn)情況下允蚣,版本號自動分配于颖,版本號就是單元格插入時的時間戳。
數(shù)據(jù)類型單一:HBase中的數(shù)據(jù)都是字符串嚷兔,沒有類型森渐。
HBase的高并發(fā)和實(shí)時處理數(shù)據(jù)
Hadoop是一個高容錯、高延時的分布式文件系統(tǒng)和高并發(fā)的批處理系統(tǒng)冒晰,不適用于提供實(shí)時計(jì)算同衣;HBase是可以提供實(shí)時計(jì)算的分布式數(shù)據(jù)庫,數(shù)據(jù)被保存在HDFS分布式文件系統(tǒng)上壶运,由HDFS保證期高容錯性耐齐,但是再生產(chǎn)環(huán)境中,HBase是如何基于hadoop提供實(shí)時性呢蒋情? HBase上的數(shù)據(jù)是以StoreFile(HFile)二進(jìn)制流的形式存儲在HDFS上block塊兒中埠况;但是HDFS并不知道的hbase存的是什么,它只把存儲文件是為二進(jìn)制文件棵癣,也就是說询枚,hbase的存儲數(shù)據(jù)對于HDFS文件系統(tǒng)是透明的。下面是HBase文件在HDFS上的存儲示意圖浙巫。
HBase HRegion servers集群中的所有的region的數(shù)據(jù)在服務(wù)器啟動時都是被打開的,并且在內(nèi)沖初始化一些memstore刷后,相應(yīng)的這就在一定程度上加快系統(tǒng)響 應(yīng)的畴;而Hadoop中的block中的數(shù)據(jù)文件默認(rèn)是關(guān)閉的,只有在需要的時候才打開尝胆,處理完數(shù)據(jù)后就關(guān)閉丧裁,這在一定程度上就增加了響應(yīng)時間。
從根本上說含衔,HBase能提供實(shí)時計(jì)算服務(wù)主要原因是由其架構(gòu)和底層的數(shù)據(jù)結(jié)構(gòu)決定的煎娇,即由LSM-Tree + HTable(region分區(qū)) + Cache決定——客戶端可以直接定位到要查數(shù)據(jù)所在的HRegion server服務(wù)器,然后直接在服務(wù)器的一個region上查找要匹配的數(shù)據(jù)贪染,并且這些數(shù)據(jù)部分是經(jīng)過cache緩存的缓呛。具體查詢流程如下圖所示:
具體數(shù)據(jù)訪問流程如下:
Client會通過內(nèi)部緩存的相關(guān)的-ROOT-中的信息和.META.中的信息直接連接與請求數(shù)據(jù)匹配的HRegion server;
然后直接定位到該服務(wù)器上與客戶請求對應(yīng)的Region杭隙,客戶請求首先會查詢該Region在內(nèi)存中的緩存——Memstore(Memstore是一個按key排序的樹形結(jié)構(gòu)的緩沖區(qū))哟绊;
如果在Memstore中查到結(jié)果則直接將結(jié)果返回給Client;
在Memstore中沒有查到匹配的數(shù)據(jù)痰憎,接下來會讀已持久化的StoreFile文件中的數(shù)據(jù)票髓。前面的章節(jié)已經(jīng)講過攀涵,StoreFile也是按 key排序的樹形結(jié)構(gòu)的文件——并且是特別為范圍查詢或block查詢優(yōu)化過的,洽沟;另外HBase讀取磁盤文件是按其基本I/O單元(即 HBase Block)讀數(shù)據(jù)的以故。
具體就是過程就是:
如果在BlockCache中能查到要造的數(shù)據(jù)則這屆返回結(jié)果,否則就讀去相應(yīng)的StoreFile文件中讀取一block的數(shù)據(jù)裆操,如果還沒有讀到要查的 數(shù)據(jù)怒详,就將該數(shù)據(jù)block放到HRegion Server的blockcache中,然后接著讀下一block塊兒的數(shù)據(jù)跷车,一直到這樣循環(huán)的block數(shù)據(jù)直到找到要請求的數(shù)據(jù)并返回結(jié)果棘利;如果將該 Region中的數(shù)據(jù)都沒有查到要找的數(shù)據(jù),最后接直接返回null朽缴,表示沒有找的匹配的數(shù)據(jù)善玫。當(dāng)然blockcache會在其大小大于一的閥值(heapsize * hfile.block.cache.size * 0.85)后啟動基于LRU算法的淘汰機(jī)制,將最老最不常用的block刪除密强。
HBase 以表的形式存儲數(shù)據(jù)茅郎。表由行和列組成。列劃分為若干個列族(row family)或渤,如下圖所示系冗。
HBase的邏輯數(shù)據(jù)模型:
HBase的物理數(shù)據(jù)模型(實(shí)際存儲的數(shù)據(jù)模型):
邏輯數(shù)據(jù)模型中空白cell在物理上是不存儲的,因?yàn)楦緵]有必要存儲薪鹦,因此若一個請求為要獲取t8時間的contents:html掌敬,他的結(jié)果就是空。相似的池磁,若請求為獲取t9時間的anchor:my.look.ca奔害,結(jié)果也是空。但是地熄,如果不指明時間华临,將會返回最新時間的行,每個最新的都會返回
與 NoSQL 數(shù)據(jù)庫一樣端考,Row Key 是用來檢索記錄的主鍵雅潭。訪問 HBase table 中的行,只有三種方式:
1)通過單個 Row Key 訪問却特。
2)通過 Row Key 的 range 全表掃描扶供。
3)Row Key 可以使任意字符串(最大長度是64KB,實(shí)際應(yīng)用中長度一般為 10 ~ 100bytes)裂明,在HBase 內(nèi)部诚欠,Row Key 保存為字節(jié)數(shù)組。
在存儲時,數(shù)據(jù)按照* Row Key 的字典序(byte order)排序存儲*轰绵。設(shè)計(jì) Key 時粉寞,要充分排序存儲這個特性,將經(jīng)常一起讀取的行存儲到一起(位置相關(guān)性)左腔。
注意 字典序?qū)?int 排序的結(jié)果是 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 進(jìn)行左填充坊秸。
行的一次讀寫是原子操作(不論一次讀寫多少列)。這個設(shè)計(jì)決策能夠使用戶很容易理解程序在對同一個行進(jìn)行并發(fā)更新操作時的行為澎怒。
HBase 表中的每個列都?xì)w屬于某個列族褒搔。列族是表的 Schema 的一部分(而列不是),必須在使用表之前定義喷面。列名都以列族作為前綴星瘾,例如 courses:history、courses:math 都屬于 courses 這個列族惧辈。
訪問控制琳状、磁盤和內(nèi)存的使用統(tǒng)計(jì)都是在列族層面進(jìn)行的。在實(shí)際應(yīng)用中盒齿,列族上的控制權(quán)限能幫助我們管理不同類型的應(yīng)用念逞, 例如,允許一些應(yīng)用可以添加新的基本數(shù)據(jù)边翁、一些應(yīng)用可以讀取基本數(shù)據(jù)并創(chuàng)建繼承的列族翎承、?
一些應(yīng)用則只允許瀏覽數(shù)據(jù)(甚至可能因?yàn)殡[私的原因不能瀏覽所有數(shù)據(jù))。
HBase 中通過 Row 和 Columns 確定的一個存儲單元稱為 Cell倒彰。每個 Cell 都保存著同一份數(shù)據(jù)的多個版本。 版本通過時間戳來索引莱睁,時間戳的類型是 64 位整型待讳。時間戳可以由HBase(在數(shù)據(jù)寫入時自動)賦值,?
此時時間戳是精確到毫秒的當(dāng)前系統(tǒng)時間仰剿。時間戳也 可以由客戶顯示賦值创淡。如果應(yīng)用程序要避免數(shù)據(jù)版本沖突,就必須自己生成具有唯一性的時間戳南吮。每個 Cell 中琳彩,不同版本的數(shù)據(jù)按照時間倒序排序,即最新的數(shù)據(jù)排在最前面。
為了避免數(shù)據(jù)存在過多版本造成的管理(包括存儲和索引)負(fù)擔(dān)露乏,HBase 提供了兩種數(shù)據(jù)版本回收方式碧浊。 一是保存數(shù)據(jù)的最后 n 個版本,二是保存最近一段時間內(nèi)的版本(比如最近七天)瘟仿。用戶可以針對每個列族進(jìn)行設(shè)置箱锐。
Cell 是由 {row key,column(=< family> + < label>)劳较,version} 唯一確定的單元驹止。Cell 中的數(shù)據(jù)是沒有類型的,全部是字節(jié)碼形式存儲观蜗。
HBase物理存儲
Table 在行的方向上分割為多個HRegion臊恋,每個HRegion分散在不同的RegionServer中。
每個HRegion由多個Store構(gòu)成墓捻,每個Store由一個memStore和0或多個StoreFile組成抖仅,每個Store保存一個Columns Family
HBase架構(gòu)圖如下:
從HBase的架構(gòu)圖上可以看出,HBase中的組件包括Client毙替、Zookeeper岸售、HMaster、HRegionServer厂画、HRegion凸丸、Store、MemStore袱院、StoreFile屎慢、HFile、HLog等忽洛,接下來介紹他們的作用腻惠。
HBase中的每張表都通過行鍵按照一定的范圍被分割成多個子表(HRegion),默認(rèn)一個HRegion超過256M就要被分割成兩個欲虚,這個過程由HRegionServer管理集灌,而HRegion的分配由HMaster管理。
包含訪問HBase的接口复哆,并維護(hù)cache來加快對HBase的訪問欣喧。
HBase依賴Zookeeper,默認(rèn)情況下HBase管理Zookeeper實(shí)例(啟動或關(guān)閉Zookeeper),Master與RegionServers啟動時會向Zookeeper注冊梯找。
Zookeeper的作用:
保證任何時候唆阿,集群中只有一個master
存儲所有Region的尋址入口
實(shí)時監(jiān)控Region server的上線和下線信息。并實(shí)時通知給master
存儲HBase的schema和table元數(shù)據(jù)
為Region server分配region
負(fù)責(zé)Region server的負(fù)載均衡
發(fā)現(xiàn)失效的Region server并重新分配其上的region锈锤。
HDFS上的垃圾文件回收驯鳖。
處理schema更新請求闲询。
維護(hù)master分配給他的region,處理對這些region的io請求浅辙。
負(fù)責(zé)切分正在運(yùn)行過程中變的過大的region扭弧。
注意:client訪問hbase上的數(shù)據(jù)時不需要master的參與,因?yàn)閿?shù)據(jù)尋址訪問zookeeper和region server摔握,而數(shù)據(jù)讀寫訪問region server寄狼。master僅僅維護(hù)table和region的元數(shù)據(jù)信息,而table的元數(shù)據(jù)信息保存在zookeeper上氨淌,因此master負(fù)載很低泊愧。
table在行的方向上分隔為多個Region。Region是HBase中分布式存儲和負(fù)載均衡的最小單元盛正,即不同的region可以分別在不同的Region Server上删咱,但同一個Region是不會拆分到多個server上。
Region按大小分隔豪筝,每個表一般是只有一個region痰滋。隨著數(shù)據(jù)不斷插入表,region不斷增大续崖,當(dāng)region的某個列族達(dá)到一個閾值(默認(rèn)256M)時就會分成兩個新的region敲街。
每個region由以下信息標(biāo)識:
< 表名,startRowkey,創(chuàng)建時間>
由目錄表(-ROOT-和.META.)記錄該region的endRowkey
Region被分配給哪個Region Server是完全動態(tài)的,所以需要機(jī)制來定位Region具體在哪個region server严望。?
下面我們來看看Region是如何被定位的多艇。
通過zk里的文件/hbase/rs得到-ROOT-表的位置。-ROOT-表只有一個region像吻。
通過-ROOT-表查找.META.表的第一個表中相應(yīng)的region的位置峻黍。其實(shí)-ROOT-表是.META.表的第一個region;.META.表中的每一個region?
在-ROOT-表中都是一行記錄拨匆。
通過.META.表找到所要的用戶表region的位置姆涩。用戶表中的每個region在.META.表中都是一行記錄。
-ROOT-表永遠(yuǎn)不會被分隔為多個region惭每,保證了最多需要三次跳轉(zhuǎn)骨饿,就能定位到任意的region。client會將查詢的位置 信息保存緩存起來台腥,緩存不會主動失效宏赘,因此如果client上的緩存全部失效,則需要進(jìn)行6次網(wǎng)絡(luò)來回览爵,才能定位到正確的region置鼻,其中三次用來發(fā)現(xiàn) 緩存失效镇饮,另外三次用來獲取位置信息蜓竹。
提示:
-ROOT-表:表包含.META.表所在的region列表,該表只有一個Region;Zookeeper中記錄了-ROOT-表的location
.META.表:表包含所有的用戶空間region列表,以及Region Server的服務(wù)器地址
每一個region由一個或多個store組成俱济,至少是一個store嘶是,hbase會把一起訪問的數(shù)據(jù)放在一個store里面,即為每個 ColumnFamily建一個store蛛碌,如果有幾個ColumnFamily聂喇,也就有幾個Store。一個Store由一個memStore和0或者 多個StoreFile組成蔚携。 HBase以store的大小來判斷是否需要切分region
memStore 是放在內(nèi)存里的希太。保存修改的數(shù)據(jù)即keyValues。當(dāng)memStore的大小達(dá)到一個閥值(默認(rèn)64MB)時酝蜒,memStore會被flush到文 件誊辉,即生成一個快照。目前hbase 會有一個線程來負(fù)責(zé)memStore的flush操作亡脑。
memStore內(nèi)存中的數(shù)據(jù)寫到文件后就是StoreFile堕澄,StoreFile底層是以HFile的格式保存。
HLog(WAL log):WAL意為write ahead log霉咨,用來做災(zāi)難恢復(fù)使用蛙紫,HLog記錄數(shù)據(jù)的所有變更,一旦region server 宕機(jī)途戒,就可以從log中進(jìn)行恢復(fù)坑傅。
HLog文件就是一個普通的Hadoop Sequence File, Sequence File的value是key時HLogKey對象,其中記錄了寫入數(shù)據(jù)的歸屬信息崔挖,除了table和region名字外贡避,還同時包括sequence number和timestamp,timestamp是寫入時間枉证,sequence number的起始值為0,或者是最近一次存入文件系統(tǒng)中的sequence number移必。 Sequence File的value是HBase的KeyValue對象室谚,即對應(yīng)HFile中的KeyValue。
前面提到崔泵,數(shù)據(jù)以KeyValue形式到達(dá)HRegionServer秒赤,將寫入WAL之后,寫入一個SequenceFile憎瘸∪肜海看過去沒問題,但是因?yàn)閿?shù) 據(jù)流在寫入文件系統(tǒng)時幌甘,經(jīng)常會緩存以提高性能潮售。這樣痊项,有些本以為在日志文件中的數(shù)據(jù)實(shí)際在內(nèi)存中。?
這里酥诽,我們提供了一個LogFlusher的類鞍泉。它調(diào)用 HLog.optionalSync(),后者根據(jù) hbase.regionserver.optionallogflushinterval (默認(rèn)是10秒),定期調(diào)用Hlog.sync()肮帐。另外咖驮,HLog.doWrite()也會根據(jù)?
hbase.regionserver.flushlogentries (默認(rèn)100秒)定期調(diào)用Hlog.sync()。Sync() 本身調(diào)用HLog.Writer.sync()训枢,它由SequenceFileLogWriter實(shí)現(xiàn)托修。
Log的大小通過$HBASE_HOME/conf/hbase-site.xml 的 hbase.regionserver.logroll.period 限制,默認(rèn)是一個小時恒界。所以每60分鐘诀黍,會打開一個新的log文件。久而久之仗处,會有一大堆的文件需要維護(hù)眯勾。首先,LogRoller調(diào)用 HLog.rollWriter()婆誓,定時滾動日志,之后洋幻,利用HLog.cleanOldLogs()可以清除舊的日志文留。它首先取得存儲文件中的最大的 sequence number好唯,之后檢查是否存在一個log所有的條目的“sequence number”均低于這個值燥翅,如果存在,將刪除這個log森书。 每個region server維護(hù)一個HLog靶端,而不是每一個region一個凛膏,這樣不同region(來自不同的table)的日志會混在一起猖毫,這樣做的目的是不斷追加 單個文件相對于同時寫多個文件而言吁断,可以減少磁盤尋址次數(shù)镊折,因此可以提高table的寫性能。帶來麻煩的時炎咖,如果一個region server下線乘盼,為了恢復(fù)其上的region绸栅,需要將region server上的log進(jìn)行拆分页屠,然后分發(fā)到其他region server上進(jìn)行恢復(fù)辰企。
目前為止牢贸,相信你已經(jīng)了解了HBase組件的使用和作用,但你可能還不太清楚上面提及的這些HBase組件間是如何運(yùn)作的臭增,下面我們來看看HBase的工作流程誊抛。
首先當(dāng)一個請求產(chǎn)生時芍锚,HBase Client使用RPC(遠(yuǎn)程過程調(diào)用)機(jī)制與HMaster和HRegionServer進(jìn)行通信并炮,對于管理類操作逃魄,Client與HMaster進(jìn)行RPC;對于數(shù)據(jù)讀寫操作伍俘,Client與HRegionServer進(jìn)行RPC。
HBase Client使用RPC(遠(yuǎn)程過程調(diào)用)機(jī)制與HMaster和HRegionServer進(jìn)行通信癌瘾,但如何尋址呢妨退?由于Zookeeper中存儲了-ROOT-表的地址和HMaster的地址咬荷,所以需要先到Zookeeper上進(jìn)行尋址幸乒。
HRegionServer也會把自己以Ephemeral方式注冊到Zookeeper中罕扎,使HMaster可以隨時感知到各個HRegionServer的健康狀態(tài)腔召。此外宴咧,Zookeeper也避免了HMaster的單點(diǎn)故障掺栅。
當(dāng)用戶需要進(jìn)行Table和Region的管理工作時氧卧,就需要和HMaster進(jìn)行通信。HBase中可以啟動多個HMaster,通過Zookeeper的Master Eletion機(jī)制保證總有一個Master運(yùn)行。
管理用戶對Table的增刪改查操作
管理HRegionServer的負(fù)載均衡星著,調(diào)整Region的分布
在Region Split后虚循,負(fù)責(zé)新Region的分配
在HRegionServer停機(jī)后,負(fù)責(zé)失效HRegionServer上的Regions遷移
當(dāng)用戶需要對數(shù)據(jù)進(jìn)行讀寫操作時铺遂,需要訪問HRegionServer襟锐。HRegionServer存取一個子表時粮坞,會創(chuàng)建一個HRegion對象,然后對表的每個列族創(chuàng)建一個Store實(shí)例跷究,每個Store都會有一個 MemStore和0個或多個StoreFile與之對應(yīng)俊马,每個StoreFile都會對應(yīng)一個HFile柴我, HFile就是實(shí)際的存儲文件艘儒。因此界睁,一個HRegion有多少個列族就有多少個Store翻斟。 一個HRegionServer會有多個HRegion和一個HLog访惜。
當(dāng)HStore存儲是HBase的核心了债热,其中由兩部分組成:MemStore和StoreFiles阳柔。 MemStore是Sorted Memory Buffer,用戶?
寫入數(shù)據(jù)首先 會放在MemStore,當(dāng)MemStore滿了以后會Flush成一個 StoreFile(實(shí)際存儲在HDHS上的是HFile)舌剂,當(dāng)StoreFile文件數(shù)量增長到一定閥值霍转,就會觸發(fā)Compact合并操作避消,并將多個StoreFile合并成一個StoreFile岩喷,合并過程中會進(jìn)行版本合并和數(shù)據(jù)刪除纱意,因此可以看出HBase其實(shí)只有增加數(shù)據(jù)偷霉,所有的更新和刪除操作都是在后續(xù)的compact過程中進(jìn)行的类少,這使得用戶的 讀寫操作只要進(jìn)入內(nèi)存中就可以立即返回硫狞,保證了HBase I/O的高性能残吩。
下面以一個具體數(shù)據(jù)Put的流程世剖,讓我們加深對HBase工作流程的認(rèn)識旁瘫。
下面是put流程的時序圖:
客戶端:
客戶端發(fā)起Put寫請求酬凳,講put寫入writeBuffer宁仔,如果是批量提交权埠,寫滿緩存后自動提交
根據(jù)rowkey將put吩咐給不同regionserver
服務(wù)端:
RegionServer將put按rowkey分給不同的region
Region首先把數(shù)據(jù)寫入wal
wal寫入成功后,把數(shù)據(jù)寫入memstore
Memstore寫完后,檢查memstore大小是否達(dá)到flush閥值
如果達(dá)到flush閥值转捕,將memstore寫入HDFS五芝,生成HFile文件
當(dāng)StoreFile文件數(shù)量增長到一定閥值枢步,就會觸發(fā)Compact合并操作价捧,并將多個StoreFile合并成一個StoreFile,當(dāng)這個StoreFile大小超過一定閥值后渔彰,會觸發(fā)Split操作恍涂,同時把當(dāng)前Region Split成2個Region,這是舊的Region會下線再沧,新Split出的2個Region會被HMaster分配到相應(yīng)的HregionServer上炒瘸,使得原先1個Region的壓力得以分散到2個Region上顷扩。
如下圖四個Storefile文件(從memstore文件經(jīng)過flush而得到隘截,默認(rèn)64M的storefile文件)經(jīng)過Compact合并成一個大的256M storefile文件婶芭,當(dāng)設(shè)定的Region閥值為128M時雕擂,就會Split為兩個128M的Storefile文件谤逼,然后HMaster再把這兩個storefile文件分配到不停地Regionserver上流部。
HBase中所有的數(shù)據(jù)文件都存儲在Hadoop HDFS上枝冀,主要包括兩種文件類型:
Hfile:HBase中KeyValue數(shù)據(jù)的存儲格式果漾,HFile是Hadoop的 二進(jìn)制格式文件绒障,實(shí)際上StoreFile就是對Hfile做了輕量級包裝,即StoreFile底層就是HFile
HLog File:HBase中WAL(write ahead log)的存儲格式庐镐,物理上是Hadoop的Sequence File
HFile的存儲格式如下:
HFile文件是不定長的必逆,長度固定的只有其中的兩塊:Trailer和FileInfo名眉。
Trailer中有指針指向其他數(shù)據(jù)塊的起始點(diǎn)璧针,F(xiàn)ileInfo記錄了文件的一些meta信息申屹。 Data Block是hbase io的基本單元哗讥,為了提高效率杆煞,HRegionServer中有基于LRU的block cache機(jī)制决乎。?
每個Data塊的大小可以在創(chuàng)建一個Table的時候通過參數(shù)指定(默認(rèn)塊大小64KB)构诚,大號的Block有利于順序Scan,小號的 Block利于隨機(jī)查詢丑蛤。?
每個Data塊除了開頭的Magic以外就是一個個KeyValue對拼接而成受裹,Magic內(nèi)容就是一些隨機(jī)數(shù)字名斟,目的是防止數(shù) 據(jù)損壞,結(jié)構(gòu)如下坑律。
上圖可知,開始是兩個固定長度的數(shù)值宫屠,分別表示key的長度和alue的長度浪蹂。緊接著是Key,開始是固定長度的數(shù)值坤次,表示RowKey的長度缰猴,緊接著是RowKey滑绒,然后是固定長度的數(shù)值缚窿,表示Family的長度倦零,然后是Family,接著是Qualifier扫茅,然后是兩個固定長度的數(shù)值葫隙,表示Time Stamp和Key Type(Put/Delete)。Value部分沒有那么復(fù)雜的結(jié)構(gòu)糟描,就是純粹的二進(jìn)制數(shù)據(jù)船响。
Hfile是HBase中KeyValue數(shù)據(jù)的存儲格式见间。從上面的 HBase物理數(shù)據(jù)模型中可以看出,HBase是面向列表(簇)的存儲史侣。每個Cell由 {row key抵窒,column(=< family> + < label>)削茁,version} 唯一確定的單元茧跋,他們組合在一起就是一個KeyValue瘾杭。根據(jù)上述描述,這個KeyValue中的key就是{row key讨阻,column(=< family> + < label>)钝吮,version} ,而value就是cell中的值耳标。
HBase的三維有序存儲中的三維是指:rowkey(行主鍵)麻捻,column key(columnFamily+< label>),timestamp(時間戳或者版本號)三部分組成的三維有序存儲。
rowkey
rowkey是行的主鍵寇僧,它是以字典順序排序的兴蒸。所以 rowkey的設(shè)計(jì)是至關(guān)重要的橙凳,關(guān)系到你應(yīng)用層的查詢效率岛啸。我們在根據(jù)rowkey范圍查詢的時候坚踩,我們一般是知道startRowkey,如果我們通過scan只傳startRowKey : d開頭的赴捞,那么查詢的是所有比d大的都查了,而我們只需要d開頭的數(shù)據(jù)恢着,那就要通過endRowKey來限制。我們可以通過設(shè)定endRowKey為:d 開頭财破,后面的根據(jù)你的rowkey組合來設(shè)定掰派,一般是加比startKey大一位。
column key
column key是第二維左痢,數(shù)據(jù)按rowkey字典排序后靡羡,如果rowkey相同,則是根據(jù)column key來排序的略步,也是按字典排序。?
我們在設(shè)計(jì)table的時候要學(xué)會利用這一點(diǎn)定页。比如我們的收件箱趟薄。我們有時候需要按主題排序,那我們就可以把主題這設(shè)置為我們的column key典徊,即設(shè)計(jì)為columnFamily+主題.,這樣的設(shè)計(jì)杭煎。
timestamp
timestamp 時間戳恩够,是第三維,這是個按降序排序的羡铲,即最新的數(shù)據(jù)排在最前面蜂桶。這個就沒有什么說的了。網(wǎng)上其他的博客也提到比較多也切。
根據(jù)以上的敘述屎飘,我們已經(jīng)了解了關(guān)于HStore的基本原理,但我們還必須要了解一下HLog的功能贾费,因?yàn)樯鲜龅腍Store在系統(tǒng)正常工作的前提下是沒問題的钦购,但是在分布式 系統(tǒng)環(huán)境中,無法避免系統(tǒng)出錯或者宕機(jī)褂萧,因?yàn)橐坏〩RegionServer意外退出押桃,MemStore中的內(nèi)存數(shù)據(jù)將會丟失,這就需要引入HLog导犹。每個HRegionServer中都有一個HLog對象唱凯,HLog是一個實(shí)現(xiàn)Write Ahead Log的類,在每一次用戶操作寫入MemStore的同時谎痢,也會寫一份數(shù)據(jù)到HLog文件中磕昼,HLog文件定期(當(dāng)文件已持久化到StoreFile中的數(shù)據(jù))會滾出新的,并且刪除舊的文件节猿。當(dāng)HRegionServer意外終止 后票从,HMaster會通過Zookeeper感知到,HMaster首先會處理遺留的Hlog文件滨嘱,將其中不同Region的Log數(shù)據(jù)進(jìn)行拆分峰鄙,分別放到相應(yīng)Region的目錄下,然后再將失效的Region重新分配太雨,領(lǐng)取到這些Region的Regionserver在Load Region的過程中吟榴,會發(fā)現(xiàn)歷史HLog需要處理,因此Replay HLog中的數(shù)據(jù)到MemStore中囊扳,然后flush到StoreFiles,完成數(shù)據(jù)恢復(fù)吩翻。
WAL(Write Ahead Log):RegionServer在處理插入和刪除過程中,用來記錄操作內(nèi)容的日志锥咸,只有日志寫入成功狭瞎,才會通知客戶端操作成功。
上圖中是HLog文件的結(jié)構(gòu)她君,其實(shí)HLog文件就是一個普通的Hadoop Sequence File脚作,Sequence File的Key是HLogKey對象,HLogKey中記錄了寫入數(shù)據(jù)的歸屬信息缔刹,除了table和Region名字外球涛,同時還包括sequence number和timestamp,timestamp是”寫入時間”,sequence number 的起始值為0校镐,或者是最近一次存入文件系統(tǒng)中的sequence number亿扁。
HLog Sequence File 的Value是HBase的KeyValue對象昂,即對應(yīng)HFile中的KeyValue鸟廓。
當(dāng)出現(xiàn)上圖三種情況的高可用策略:
HDFS機(jī)架識別策略:當(dāng)數(shù)據(jù)文件損壞時从祝,會找相同機(jī)架上備份的數(shù)據(jù)文件,如果相同機(jī)架上的數(shù)據(jù)文件也損壞會找不同機(jī)架備份數(shù)據(jù)文件引谜。
HBase的Region快速恢復(fù):當(dāng)節(jié)點(diǎn)損壞時牍陌,節(jié)點(diǎn)上的丟失region,會在其他節(jié)點(diǎn)上均勻快速恢復(fù)。
Master節(jié)點(diǎn)的HA機(jī)制:Master為一主多備员咽。當(dāng)Master主節(jié)點(diǎn)宕機(jī)后毒涧,剩下的備節(jié)點(diǎn)通過選舉,產(chǎn)生主節(jié)點(diǎn)贝室。
上圖中契讲,從HDFS以下都屬于HBase的支撐系統(tǒng)。
從構(gòu)成集群機(jī)器的底層硬件到把硬件和操作系統(tǒng)(尤其是文件系統(tǒng))滑频,JVM,HDFS連接起來的網(wǎng)絡(luò)之間的所有部件都會影響到HBase的性能捡偏。HBase系統(tǒng)的狀態(tài)也會影響到HBase的系統(tǒng)。例如峡迷,在集群中執(zhí)行合并的時候或者M(jìn)emstore刷寫的時候與什么都沒有做的時候相比银伟,其性能表現(xiàn)是不同的。應(yīng)用系統(tǒng)的性能還取決于它和HBase的交互方式绘搞,所以模式設(shè)計(jì)和其他環(huán)節(jié)一樣起到了必不可少的作用枣申。
在評判HBase性能時,所有這些因素都有影響看杭;在優(yōu)化集群時忠藤,需要查看所有這些因素。
(1)硬件選擇
總的原則是楼雹,根據(jù)業(yè)務(wù)情況和集群規(guī)模大小選擇合理的硬件模孩。
(2)網(wǎng)絡(luò)配置
基于當(dāng)前階段硬件的典型分布式系統(tǒng)都會受到網(wǎng)絡(luò)的限制,HBase也不例外贮缅。在節(jié)點(diǎn)和機(jī)架頂置交換機(jī)之間建議采用10Gb以太網(wǎng)交換機(jī)榨咐。千萬不要過于滿額配置地使用網(wǎng)絡(luò),否則在高負(fù)載時谴供,會影響HBase應(yīng)用系統(tǒng)的性能块茁。
(3)操作系統(tǒng)
一般情況下,只要使用Hadoop和HBase,操作系統(tǒng)通常選擇Linux数焊∮捞剩可以選擇Red Hat Enterprise Linux,CentOS佩耳,也可以選擇成功部署過的其他操作系統(tǒng)遂蛀。
(4)本地文件系統(tǒng)
本地Linux文件系統(tǒng)在HBase集群體系里起到了重要作用,并且嚴(yán)重影響到HBase的性能干厚。雖然EXT4是推薦使用的本地文件系統(tǒng)李滴,但沒有大規(guī)模使用,相反EXT3和XFS已經(jīng)在生產(chǎn)系統(tǒng)里得到成功使用蛮瞄,建議使用EXT3和XFS作為本地文件系統(tǒng)所坯。
(5)HDFS
根據(jù)業(yè)務(wù)訪問特點(diǎn)優(yōu)化
根據(jù)業(yè)務(wù)訪問特點(diǎn),將Hbase的工作負(fù)載大致分為以下四類:
(1)隨機(jī)讀密集型
對于隨機(jī)讀密集型工作負(fù)載挂捅,高效利用緩存和更好地索引會給HBase系統(tǒng)帶來更高的性能芹助。
(2)順序讀密集型
對于順序讀密集型工作負(fù)載,讀緩存不會帶來太多好處籍凝;除非順序讀的規(guī)模很小并且限定在一個特定的行鍵范圍內(nèi)周瞎,否則很可能使用緩存會比不使用緩存需要更頻繁地訪問硬盤。
(3)寫密集型
寫密集型工作負(fù)載的優(yōu)化方法需要有別于讀密集型負(fù)載饵蒂。緩存不再起到重要作用声诸。寫操作總是進(jìn)入MemStore,然后被刷寫生成新的Hfile退盯,以后再被合并彼乌。獲得更好寫性能的辦法是不要太頻繁刷寫、合并或者拆分渊迁,因?yàn)樵谶@段時間里IO壓力上升慰照,系統(tǒng)會變慢。
(4)混合型
對于完全混合型工作負(fù)載琉朽,優(yōu)化方法會變得復(fù)雜些毒租。優(yōu)化時,需要混合調(diào)整多個參數(shù)來得到一個最優(yōu)的組合箱叁。
(1)JVM垃圾回收優(yōu)化
(2)本地memstore分配緩存優(yōu)化
(3)Region拆分優(yōu)化
(4**)Region合并優(yōu)化**
(5)Region預(yù)先加載優(yōu)化
(6)負(fù)載均衡優(yōu)化
(7)啟用壓縮
(8)GZIP墅垮、snappy、lzo耕漱,推薦snappy,壓縮比稍差于lzo算色;但是壓縮速度高于lzo,并且與lzo有差不多的 解壓縮速度。
(9)進(jìn)行預(yù)分區(qū)螟够,從而避免自動split灾梦,提高h(yuǎn)base響應(yīng)速度
(10)避免出現(xiàn)region熱點(diǎn)現(xiàn)象峡钓,啟動按照table級別進(jìn)行balance
HBase Shell 提供了大多數(shù)的 HBase 命令, 通過 HBase Shell 用戶可以方便地創(chuàng)建、刪除及修改表, 還可以向表中添加數(shù)據(jù)若河、列出表中的相關(guān)信息等能岩。
在啟動 HBase 之后,用戶可以通過下面的命令進(jìn)入 HBase Shell 之中,命令如下所示:
[hadoop@CDHNode1 ~]$hbase shell
1
2
輸入 help 可以看到命令分組。(注意命令都是小寫牡肉,有大小寫的區(qū)分)
部分命令
下邊分組舉例 Shell 的各種操作捧灰。
查詢 HBase 服務(wù)器狀態(tài) status淆九。
查詢hbase版本 version
1统锤、 創(chuàng)建一個表
create ‘table1’, ‘tab1_id’, ‘tab1_add’, ‘tab1_info’
2、 列出所有的表
3炭庙、 獲得表的描述
describe “table1”
4饲窿、 刪除一個列族 disable alter enable?注意刪除前,需要先把表disable
disable ‘table1’
alter ‘table1’, {NAME=>’tab1_add’, METHOD=>’delete’}
enable ‘table1’
5焕蹄、 查看表是否存在?
exists ‘table2’
6逾雄、 判斷表是否為‘enable’
is_enabled ‘table1’
7舌菜、 刪除一個表
disable ‘table1’
drop ‘table1’
1士葫、 插入幾條記錄
put ‘member’, ‘scutshuxue’, ‘info:age’, ‘24’
put ‘member’, ‘scutshuxue’, ‘info:birthday’, ‘1987-06-17’
put ‘member’, ‘scutshuxue’, ‘info:company’, ‘a(chǎn)libaba’
put ‘member’, ‘scutshuxue’, ‘a(chǎn)ddress:contry’, ‘china’
put ‘member’, ‘scutshuxue’, ‘a(chǎn)ddress:province’, ‘zhejiang’
put ‘member’, ‘scutshuxue’, ‘a(chǎn)ddress:city’, ‘hangzhou’
put命令比較簡單运挫,只有這一種用法:?
hbase> put ‘t1′, ‘r1′, ‘c1′, ‘value’, ts1
t1指表名纸巷,r1指行鍵名燎斩,c1指列名匕垫,value指單元格值雏门。ts1指時間戳泞莉,一般都省略掉了鼎姐。
2钾麸、 全表掃描 scan
3、 獲得數(shù)據(jù) get
1) 獲得一行的所有數(shù)據(jù)
2) 獲得某行炕桨,某列族的所有數(shù)據(jù)
3) 獲得某行饭尝,某列族,某列的所有數(shù)據(jù)
4献宫、 更新一條記錄 put(把scutshuxue年齡改為99)
put ‘member’, ‘scutshuxue’, ‘info:age’, 99
5钥平、 刪除 delete、 deleteall
1) 刪除行’scutshuxue’, 列族為‘info’ 中age的值
delete ‘member’, ‘scutshuxue’, ‘info:age’
2) 刪除整行
deleteall ‘member’, ‘scutshuxue’
6姊途、 查詢表中有多少行
count ‘member’
7涉瘾、 給‘xiaoming’這個id增加’info:age’字段,并使用counter實(shí)現(xiàn)遞增
incr ‘member’, ‘xiaoming’, ‘info:age’
8吭净、 將整個表清空
truncate ‘member’
可以看出睡汹,HBase 是通過先對表執(zhí)行 disable,然后再執(zhí)行 drop 操作后重建表來實(shí)現(xiàn) truncate 的功能的寂殉。