HBase架構(gòu)的組成
HBase大體上按照master-slave架構(gòu)可以分解成三種類型的服務(wù)瓮床。Region server服務(wù)于數(shù)據(jù)的讀和寫。當有數(shù)據(jù)需要被訪問左电,client與HBase RegionServer直接通訊阴汇。Region assignment瞎惫,DDL(create,delete tables)操作由HBase Master處理胎源。Zookeeper棉钧,可以理解成HDFS的一部分,用來維護集群狀態(tài)涕蚤。
Hadoop DataNode存儲由RegionServer管理的數(shù)據(jù)宪卿。所有HBase數(shù)據(jù)存儲在HDFS的文件中的诵。RegionServer搭配DataNodes來使用,這樣可以使用HBase的Locality特性(就是把RegionServer負責管理數(shù)據(jù)其中一份副本放在本地的DataNode)佑钾。HBase在數(shù)據(jù)被寫入時本地會存儲一份副本西疤,但是當一個Region被挪到其他RS上,Region數(shù)據(jù)直到下一次compaction才會被寫到本地DN休溶。
NameNode負責管理由物理文件構(gòu)成的data block所產(chǎn)生的metadata信息代赁。
Regions
HBase表會按照key range被水平的拆分成一個個的“Regions”。一個Region包含這張表從start key到end key之間的所有數(shù)據(jù)行(類似于Mysql應(yīng)對海量數(shù)據(jù)所使用的分庫分表策略)兽掰,并且對這個范圍內(nèi)的數(shù)據(jù)讀寫提供服務(wù)芭碍。一個RegionServer可對大概1000個Region提供服務(wù)(1000是一個默認值,可使用配置項修改孽尽,超過這個值后將不能split)窖壕。
HBase HMaster
Region assignment,DDL(create杉女,delete表)等操作由HBase的Master負責處理瞻讽。
一個Master具體負責的任務(wù)如下:
- 協(xié)調(diào)RegionServer
在啟動階段assigning region,或者recovery和balancing階段重新assigning regions
監(jiān)控集群上所有RegionServer實例(通過監(jiān)聽zookeeper上的通知消息方式實現(xiàn)) -
管理操作
create, delete, update表等操作熏挎。
ZooKeeper: 集群協(xié)調(diào)器
HBase使用Zookeeper來作為分布式服務(wù)協(xié)調(diào)器速勇,用來維護集群中的狀態(tài)。Zookeeper維護Server的存活和可用坎拐,也會通知server異常后的事件烦磁。Zookeeper使用內(nèi)部的一致性協(xié)議(paxos)來維護共享的狀態(tài)。但是要注意要有三臺或者五臺(奇數(shù))機器來提供一致性服務(wù)廉白。
組件們是如何協(xié)同工作的
Zookeeper用來協(xié)調(diào)分布式系統(tǒng)中各成員的共享狀態(tài)信息个初。RegionServer和active的HMaster與ZooKeeper之間會保持一個session通訊。Zookeeper通過臨時znode的方式維護各組件的心跳猴蹂。
每個RegionServer創(chuàng)建一個臨時znode院溺。HMaster監(jiān)控這些znode來發(fā)現(xiàn)可用的RegionServer,并且也通過監(jiān)控這些Znodes來得知那些Server異常磅轻。HMasters之間通過創(chuàng)建臨時znode的方式競爭active master(具體來說就是在zk上成功創(chuàng)建znode則為active珍逸,失敗的為backup)。Active HMaster向Zookeeper發(fā)送心跳聋溜,Backup HMaster在zk上監(jiān)控Active HMaster的失敗通知谆膳。
如果一個RegionServer或者Active HMaster發(fā)送心跳失敗,session則會超時撮躁,臨時znode會被刪除漱病。所有的Listeners會受到關(guān)于刪除失敗znode的時間通知。Active HMaster監(jiān)聽RegionServer,并會進行RegionServer失敗后的恢復(fù)工作杨帽。Backup HMaster監(jiān)聽Active HMaster的失敗信息漓穿,如果Active HMaster發(fā)生異常,Backup HMaster會成為Active注盈。
HBase第一次Read或Write
在HBase上有一張?zhí)貏e的catalog表被成為META表晃危,它管理所有region在集群中的位置信息。ZooKeeper存儲META表的位置信息老客。
下面是一個client第一次讀或?qū)憰r發(fā)生的事情:
- client通過zk獲得META表所在的RegionServer僚饭。
- client與持有META表的Regionserver通訊,在.META表中查詢所希望訪問的rowkey所在的RegionServer胧砰。client會緩存數(shù)據(jù)表和META的位置信息鳍鸵。
- client通過前面所拿到的rowkey所在的RegionServer信息,與其通信拿到所需要的數(shù)據(jù)朴则。
后面的read权纤,client會使用之前從META表中取回的位置信息來讀取rowkey钓简。這樣則不會再次重新訪問META表乌妒,除非由于Region被移動走而沒有訪問到;這種情況下會重新訪問META表并更新cache外邓。
HBase Meta Table
- META表是一張HBase表撤蚊,存儲了整個集群中所有region的信息
- META表像是一張B樹結(jié)構(gòu)
-
META表按下面的結(jié)構(gòu)存儲:
-Key:region start key,region encode id
-Value:RegionServer
RegionServer的組成
一個RegionServer通常在一個HDFS的DataNode運行损话,并且有如下的組件:
- WAL:Write Ahead Log是HDFS上的一個文件侦啸。WAL用來存儲還沒有被持久化到存儲層的新數(shù)據(jù);用來作RS異常時的恢復(fù)工作中丧枪。
- BlockCache:是一個讀緩存光涂。在內(nèi)存中存儲了頻繁被訪問的數(shù)據(jù)。當BlockCache空間將要用光時會進行evict操作拧烦,清理訪問最少的數(shù)據(jù)
- MemStore:是一個寫緩存忘闻。存儲了還未被寫到磁盤上的新數(shù)據(jù)。在寫到磁盤之前它是經(jīng)過排序的恋博。每個column family的每個region會持有一個Memstore齐佳。
-
HFile將排序過的KeyValue存儲在磁盤上
HBase寫步驟1
當請求put一行數(shù)據(jù),第一步是將數(shù)據(jù)寫到write-ahead log债沮,即WAL:
- WALEdits會被append到WAL文件的最末端炼吴,并存儲在磁盤上
-
WAL用來在集群掛掉時恢復(fù)還未被持久化到HFile的數(shù)據(jù)。
HBase寫步驟2
一旦數(shù)據(jù)寫到了WAL疫衩,它也會被放置在MemStore硅蹦。之后,client發(fā)出的put請求會受到一條ack信息,表示寫入成功童芹。
HBase MemStore
MemStore在內(nèi)存中存儲update數(shù)據(jù)并排序(字典序正序)命爬,并按照同樣的方式存儲在一個HFile中。每個column family的一個Region有一個MemStore辐脖。數(shù)據(jù)的update則在column family的范圍內(nèi)排序饲宛。
HBase Region Flush
當MemStore積累了足夠的數(shù)據(jù)后,會將整個排序后的結(jié)果寫到HDFS上的一個新的HFile嗜价。HBase每個column falimy有多個HFile艇抠,包含了真實的cell,或者KeyValue實例久锥。這些文件被創(chuàng)建為排序后的KeyValue edits形式家淤,并隨著時間的推移,flush到磁盤瑟由。
這里要注意一個問題絮重,HBase中的column family有一個數(shù)量的限制。這是因為每個CF的每個Region持有一個MemStore歹苦,無論哪個MemStore寫滿數(shù)據(jù)青伤,所有的MemStore都會做flush操作。在這個過程中保存一個最近寫文件時用到的sequence id殴瘦,這樣系統(tǒng)可以知道存儲了多少文件狠角。
最高的sequence id會作為一個meta變量存儲在每個HFile上,用來響應(yīng)當時寫到了哪個id蚪腋,可以從哪個id繼續(xù)丰歌。在Region startup階段,sequence id會被讀取屉凯,最高的sequence id用來寫新的edits立帖。
HBase HFile
數(shù)據(jù)在HFile中按照排序過的Key/Values存儲。當MemStore積累了足夠的數(shù)據(jù)悠砚,整個排序過的KeyValue會被重寫成HDFS上一個新的HFile晓勇。這個過程是一次順序?qū)懭耄俣群芸炝ú荆苊饬艘苿哟疟P的磁頭宵蕉。
HBase HFile結(jié)構(gòu)
一個HFile包含了一個多層的Index結(jié)構(gòu),這樣避免了HBase查找數(shù)據(jù)時要將所有Index加載到內(nèi)存节榜。這個多層Index結(jié)構(gòu)類似于b+樹:
- Key value對按增序存儲
- Index通過rowkey指向Key value寫成的64K block塊(64K可在建表時動態(tài)修改羡玛,更大有助于順序scan,更小有助于get)
- 每個block都有指向自己的Leaf index
- 每個block的last key會被放在intermediate index中
-
root index指向intermediate index
HFile的Trailer指向meta block宗苍,trailer被寫在hfile文件的最后稼稿。trailer也包含像bloom filter和time range信息薄榛。Bloom filters幫助確定文件中是否不包含指定的rowkey。Time range信息幫助在讀操作時跳過過期的文件让歼。
HFile Index
剛才討論的Index敞恋,會在HFile被打開時被加載到內(nèi)存。對在單磁盤的seek操作性能提升有幫助谋右。
HBase Read Merge 1
我們已經(jīng)知道硬猫,一行數(shù)據(jù)KeyValue單元格可能被存儲在多個位置,row單元格已經(jīng)被持久化在HFile中改执,近期更新的單元格在MemStore啸蜜,近期被讀取的單元格存儲在BlockCache。這樣的話辈挂,當讀一行數(shù)據(jù)衬横,系統(tǒng)如何返回對應(yīng)的單元格回來?總的來說會在BlockCache终蒂,MemStore蜂林,HFile之間進行一次Read Merge操作,具體步驟如下:
- 首先拇泣,scanner從BlockCache中讀取Row cell噪叙。近期被讀過的Key values會在這里被緩存,并且當BlockCache空間不足時讀取最少的數(shù)據(jù)將被evicted出BlockCache
- 接下來挫酿,scanner在MemStore中查找數(shù)據(jù)
-
如果scanner沒有在MemStore和BlockCache找到所有的數(shù)據(jù)時(這里提出一個問題构眯,HBase通過什么條件判斷讀寫緩存中的數(shù)據(jù)不是要查詢的全部愕难?)早龟,HBase會使用BlockCache index和Bloom filter加載可能包含數(shù)據(jù)的HFile到內(nèi)存,來查找目標單元格猫缭。
HBase Read Merge 2
如之前所討論的葱弟,每個MemStore會有多個HFile,這意味著一次讀猜丹,多個文件可能會被檢查芝加,將會影響到整體性能。這就是所謂的“讀放大”射窒。
HBase Minor Compaction
HBase會自動挑選小一點的HFiles并重寫為一個相對大一些的HFile藏杖。這個過程稱為minor compaction。Minor compaction通過將過小的存儲文件重寫成更大的文件的方式減少文件數(shù)量脉顿,并在過程中進行歸并排序蝌麸。
HBase Major Compaction
Major compaction重寫并合并每個CF中的一個region內(nèi)的所有HFiles,并且在過程中艾疟,丟掉被刪除和已經(jīng)過期的單元格来吩。這個過程會提升度性能敢辩;但是,當major compaction重寫所有文件時弟疆,大量的磁盤和網(wǎng)絡(luò)I/O會在過程中產(chǎn)生戚长。這個過程叫做“寫放大”
Major compactions可被系統(tǒng)定時自動執(zhí)行。因為寫放大的關(guān)系怠苔,major compaction經(jīng)常在周末或者夜間執(zhí)行同廉。一次Major compaction也會重寫由于server掛掉或load balancing交接過來的region數(shù)據(jù)到本地。
Region = Continguous Keys
我們對region進行一次快速回顧:
- 一張HBase table可被水平的拆分成一個或多個region柑司。一個region包含一段連續(xù)的恤溶,在startkey和endkey之間有序(字典序正序)的數(shù)據(jù)
- 每個Region最大1GB(可配置,社區(qū)默認1G)
- 一張表的一個Region唄一臺RegionServer持有帜羊,向client提供服務(wù)
-
一個RegionServer可以對1000個Region進行管理(這些region可能會屬于不同的HBase table)
Region Split
起初每張表一個Region咒程。當一個Region增長的過于大時,會split成兩個child region讼育。兩個chlid region帐姻,持有original region的一半數(shù)據(jù),并行的在與original region相同的RegionServer中打開奶段,之后split操作會報告給HMaster饥瓷。并且由于load balancing的關(guān)系,HMaster可能會將新Region assign到其他RegionServer上痹籍。
Read Load Balancing
Split起初會發(fā)生在閾值相同的RegionServer上呢铆,但是由于load balancing的原因,HMaster可能會將新Region移動到其他Server蹲缠。結(jié)果是新的Region使用遠端的HDFS DataNode來提供服務(wù)棺克,直到下一次Major Compaction才會將數(shù)據(jù)寫到本地。
HDFS Data Replication 1
所有write和read操作會優(yōu)先通過主節(jié)點线定。HDFS會復(fù)制WAL和HFile blocks娜谊。HFile block repication會自動發(fā)生。HBase依賴HDFS提供數(shù)據(jù)安全性斤讥。當數(shù)據(jù)寫到HDFS時纱皆,一份數(shù)據(jù)寫到RegionServer本地的Datanode,之后復(fù)制到第二個節(jié)點芭商,最后拷貝到第三個節(jié)點派草。
HDFS Data Replication 2
WAL文件和HFile被持久化在磁盤并被replicated。這是HBase恢復(fù)MemStore中沒有被持久化為HFile的數(shù)據(jù)并保障數(shù)據(jù)安全的方式铛楣。
HBase Crash Recovery
當一臺RegionServer異常近迁,上面的Region在recovery過程執(zhí)行完成之前會是不可用狀態(tài)。Zookeeper會在RegionServer失去心跳時決定Node異常蛉艾。HMaster之后會被通知钳踊,得知RegionServer掛掉的消息衷敌。
當HMaster檢測到RegionServer掛掉,HMaster會重新assign掛掉RegionServer上的所有Region到可用的RegionServer上拓瞪。為了恢復(fù)掛掉RegionServer的Memstore中沒有被持久化到磁盤上的edit信息缴罗,HMaster會將屬于掛掉RegionServer的WAL按照新的RegionServer拆分成新的文件存儲到datanode。每個RegionServer使用各自的split WAL回訪數(shù)據(jù)祭埂,重建出那個region的Memstore的信息面氓。
Data Recovery
WAL文件包含一系列的edits數(shù)據(jù),每個edit代表依次put或delete操作蛆橡。Edits會按時間順序重寫舌界,這樣,為了持久化泰演,新的數(shù)據(jù)被追加到WAL的最后呻拌,存儲在磁盤。
如果掛機發(fā)生在數(shù)據(jù)仍然在內(nèi)存中并且還沒被持久化到HFile時會發(fā)生什么睦焕?WAL已經(jīng)被replay藐握。replay會將舊的edits寫到新的WAL中,并在當前的Memstore中排序垃喊。最后猾普,MemStore被flush,將數(shù)據(jù)寫到HFile本谜。
總結(jié):HBase架構(gòu)的優(yōu)點
HBase提供如下優(yōu)點:
- 強一致性模型:當一次write操作范圍初家,所有的read操作看到的都是相同的value
- 自動擴展:Region在過大時會自動split。使用HDFS進行數(shù)據(jù)多副本化乌助。
- 內(nèi)置的Recovery:使用Write Ahead Log(類似于文件系統(tǒng)的日志溜在,mysql的binlog)
- 與Hadoop生態(tài)整合:在HBase上的MapReduce會非常簡單
總結(jié):HBase架構(gòu)的缺點
HBase的強一致模型帶來如下問題:
- WAL replay過程過于慢
- Server Crash和Recovery過程過于慢和復(fù)雜
- Major Compaction 帶來的I/O風暴。