架構(gòu)組成
HBase采用Master/Slave架構(gòu)搭建集群,它隸屬于Hadoop生態(tài)系統(tǒng),由一下類型節(jié)點(diǎn)組成:HMaster節(jié)點(diǎn)、HRegionServer節(jié)點(diǎn)、ZooKeeper集群,而在底層,它將數(shù)據(jù)存儲于HDFS中,因而涉及到HDFS的NameNode、DataNode等,總體結(jié)構(gòu)如下:

?
在物理上,HBase由master/slave類型體系結(jié)構(gòu)中的三種服務(wù)器組成。RegionServer為讀取和寫入提供數(shù)據(jù)。訪問數(shù)據(jù)時(shí),Client直接與Region Server通信。Region的分配,DDL(創(chuàng)建,刪除表)操作由HMaster處理。作為HDFS一部分的Zookeeper維護(hù)活動集群狀態(tài)。 Hadoop DataNode存儲Region Server正在管理的數(shù)據(jù)。所有HBase數(shù)據(jù)都存儲在HDFS文件中。Region Server與HDFS數(shù)據(jù)節(jié)點(diǎn)并置,從而為Region Server提供的數(shù)據(jù)實(shí)現(xiàn)數(shù)據(jù)局部性。除了Region在Split的時(shí)候,Hbase寫入不是本地的,但是在Hbase在完成compaction之后 HBase數(shù)據(jù)是基于Local寫入的。NameNode維護(hù)構(gòu)成文件的所有物理數(shù)據(jù)塊的元數(shù)據(jù)信息。

山東掌趣網(wǎng)絡(luò)科技
?
Regions
HBase表按RowKey范圍水平劃分為“Region”。一個(gè)Region包含表中該Region的開始鍵和結(jié)束鍵之間的所有行。將Region分配給群集中稱為“Region Server”的節(jié)點(diǎn),這些Region Server為讀取和寫入提供數(shù)據(jù)。Region Server可以服務(wù)大約1,000個(gè)區(qū)域。

山東掌趣網(wǎng)絡(luò)科技
?
HBase HMaster
區(qū)Region分配,DDL(創(chuàng)建,刪除表)操作由HBase Master處理。
HBase Master主要負(fù)責(zé):
Coordinating the region servers
- Assigning regions on startup , re-assigning regions for recovery or load balancing
- Monitoring all RegionServer instances in the cluster (listens for notifications from zookeeper)
Admin functions
- Interface for creating, deleting, updating tables

山東掌趣網(wǎng)絡(luò)科技
?
ZooKeeper
ZooKeeper為HBase集群提供協(xié)調(diào)服務(wù),它管理著HMaster和HRegionServer的狀態(tài)(available/alive等),并且會在它們宕機(jī)時(shí)通知給HMaster,從而HMaster可以實(shí)現(xiàn)HMaster之間的failover,或?qū)﹀礄C(jī)的HRegionServer中的HRegion集合的修復(fù)(將它們分配給其他的HRegionServer)。ZooKeeper集群本身使用一致性協(xié)議(PAXOS協(xié)議)保證每個(gè)節(jié)點(diǎn)狀態(tài)的一致性。

?山東掌趣網(wǎng)絡(luò)科技
?
總結(jié)
Zookeeper用于協(xié)調(diào)分布式系統(tǒng)成員的共享狀態(tài)信息。Region Server和Active的HMaster通過與ZooKeeper的會話連接。 ZooKeeper通過心跳維護(hù)臨時(shí)節(jié)點(diǎn)以進(jìn)行活動會話。

山東掌趣網(wǎng)絡(luò)科技
每個(gè)RegionServer都會創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn)。 HMaster監(jiān)視這些節(jié)點(diǎn)以發(fā)現(xiàn)可用的Region Server,并且還監(jiān)視這些節(jié)點(diǎn)的服務(wù)器故障。 HMasters試圖創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn)。 Zookeeper確定第一個(gè)Master,并使用它來確保只有一個(gè)Master處于Active狀態(tài)。活動的HMaster將心跳發(fā)送到Zookeeper,非活動的HMaster偵聽活動的HMaster故障的通知。 如果Region Server或Active的HMaster無法發(fā)送心跳,則會話過期,并刪除相應(yīng)的臨時(shí)節(jié)點(diǎn)。更新的偵聽器將被通知已刪除的節(jié)點(diǎn)。Active的HMaster偵聽Region Sever,并在發(fā)生故障時(shí)恢復(fù)Region Server。非活動HMaster偵聽活動的HMaster故障,如果Active的HMaster發(fā)生故障,則非活動的HMaster會變?yōu)榛顒訝顟B(tài)。
HBase首先讀取或?qū)懭?/p>
有一個(gè)稱為META表的特殊HBase目錄表,該表保存集群中Region的位置。 ZooKeeper存儲META表的位置信息。
這是客戶端第一次讀取或?qū)懭際Base時(shí)發(fā)生的情況:
1、客戶端從ZooKeeper獲取托管META表的Region服務(wù)器。
2、客戶端將查詢.META。服務(wù)器以獲取與要訪問的行鍵相對應(yīng)的區(qū)域服務(wù)器。客戶端將該信息與META表位置一起緩存。
3、它將從相應(yīng)的區(qū)域服務(wù)器獲取行。
為了將來讀取,客戶端使用緩存來檢索META位置和先前讀取的行鍵。隨著時(shí)間的流逝,它不需要查詢META表,除非由于區(qū)域移動導(dǎo)致遺漏;然后它將重新查詢并更新緩存。

?山東掌趣網(wǎng)絡(luò)科技
?
META表
hbase:meta表存儲了所有用戶HRegion的位置信息,它的RowKey是:tableName,regionStartKey,regionId,replicaId等,它只有info列族,這個(gè)列族包含三個(gè)列,他們分別是:
info:regioninfo:regionId,tableName,startKey,endKey,offline,split,replicaId;
info:server:HRegionServer對應(yīng)的server:port;
info:serverstartcode:HRegionServer的啟動時(shí)間戳。

?山東掌趣網(wǎng)絡(luò)科技
?HRegion Server
Region Server在HDFS數(shù)據(jù)節(jié)點(diǎn)上運(yùn)行,并具有以下組件:
WAL: 預(yù)寫日志是分布式文件系統(tǒng)上的文件。 WAL用于存儲尚未持久存儲的新數(shù)據(jù)。發(fā)生故障時(shí)用于恢復(fù)。
BlockCache:是讀取緩存。它將經(jīng)常讀取的數(shù)據(jù)存儲在內(nèi)存中。滿時(shí)將逐出最近最少使用的數(shù)據(jù)。
MemStore:是寫緩存。它存儲尚未寫入磁盤的新數(shù)據(jù)。在寫入磁盤之前先對其進(jìn)行排序。每個(gè)區(qū)域的每個(gè)列族都有一個(gè)MemStore。
HRegion:一個(gè)Table可以有一個(gè)或多個(gè)Region,他們可以在一個(gè)相同的HRegionServer上,也可以分布在不同的HRegionServer上,一個(gè)HRegionServer可以有多個(gè)HRegion,他們分別屬于不同的Table。HRegion由多個(gè)Store(HStore)構(gòu)成,每個(gè)HStore對應(yīng)了一個(gè)Table在這個(gè)HRegion中的一個(gè)Column Family,即每個(gè)Column Family就是一個(gè)集中的存儲單元,因而最好將具有相近IO特性的Column存儲在一個(gè)Column Family,以實(shí)現(xiàn)高效讀取(數(shù)據(jù)局部性原理,可以提高緩存的命中率)。HStore是HBase中存儲的核心,它實(shí)現(xiàn)了讀寫HDFS功能,一個(gè)HStore由一個(gè)MemStore 和0個(gè)或多個(gè)StoreFile組成
MemStore(In Memory Sorted Buffer),所有數(shù)據(jù)的寫在完成WAL日志寫后,會 寫入MemStore中,由MemStore根據(jù)一定的算法將數(shù)據(jù)Flush到地層HDFS文件中(HFile),通常每個(gè)HRegion中的每個(gè) Column Family有一個(gè)自己的MemStore。
HFile在HFile中的數(shù)據(jù)是按RowKey、Column Family、Column排序,對相同的Cell(即這三個(gè)值都一樣),則按timestamp倒序排列。

?山東掌趣網(wǎng)絡(luò)科技
?
當(dāng)客戶端發(fā)起一個(gè)Put請求時(shí),首先它從hbase:meta表中查出該P(yáng)ut數(shù)據(jù)最終需要去的HRegionServer。然后客戶端將Put請求發(fā)送給相應(yīng)的HRegionServer,在HRegionServer中它首先會將該P(yáng)ut操作寫入WAL日志文件中(Flush到磁盤中)。

?山東掌趣網(wǎng)絡(luò)科技
?
寫完WAL日志文件后,HRegionServer根據(jù)Put中的TableName和RowKey找到對應(yīng)的HRegion,并根據(jù)Column Family找到對應(yīng)的HStore,并將Put寫入到該HStore的MemStore中。此時(shí)寫成功,并返回通知客戶端。MemStore是一個(gè)In Memory Sorted Buffer,在每個(gè)HStore中都有一個(gè)MemStore,即它是一個(gè)HRegion的一個(gè)Column Family對應(yīng)一個(gè)實(shí)例。它的排列順序以RowKey、Column Family、Column的順序以及Timestamp的倒序,如下所示:

?山東掌趣網(wǎng)絡(luò)科技
?
每一次Put/Delete請求都是先寫入到MemStore中,當(dāng)MemStore滿后會Flush成一個(gè)新的StoreFile(底層實(shí)現(xiàn)是HFile),即一個(gè)HStore(Column Family)可以有0個(gè)或多個(gè)StoreFile(HFile)。有以下三種情況可以觸發(fā)MemStore的Flush動作,需要注意的是MemStore的最小Flush單元是HRegion而不是單個(gè)MemStore。
當(dāng)一個(gè)HRegion中的所有MemStore的大小總和超過了
hbase.hregion.memstore.flush.size的大小,默認(rèn)128MB。此時(shí)當(dāng)前的HRegion中所有的MemStore會Flush到HDFS中。
當(dāng)全局MemStore的大小超過了
hbase.regionserver.global.memstore.upperLimit的大小,默認(rèn)40%的內(nèi)存使用量。此時(shí)當(dāng)前HRegionServer中所有HRegion中的MemStore都會Flush到HDFS中,F(xiàn)lush順序是MemStore大小的倒序,直到總體的MemStore使用量低于
hbase.regionserver.global.memstore.lowerLimit,默認(rèn)38%的內(nèi)存使用量。
當(dāng)前HRegionServer中WAL的大小超過了
hbase.regionserver.hlog.blocksize *
hbase.regionserver.max.logs的數(shù)量,當(dāng)前HRegionServer中所有HRegion中的MemStore都會Flush到HDFS中,F(xiàn)lush使用時(shí)間順序,最早的MemStore先Flush直到WAL的數(shù)量少于
hbase.regionserver.hlog.blocksize *
hbase.regionserver.max.logs
在MemStore Flush過程中,還會在尾部追加一些meta數(shù)據(jù),其中就包括Flush時(shí)最大的WAL sequence值,以告訴HBase這個(gè)StoreFile寫入的最新數(shù)據(jù)的序列,那么在Recover時(shí)就直到從哪里開始。在HRegion啟動時(shí),這個(gè)sequence會被讀取,并取最大的作為下一次更新時(shí)的起始sequence。

?山東掌趣網(wǎng)絡(luò)科技
HFile里面的每個(gè)KeyValue對就是一個(gè)簡單的byte數(shù)組。但是這個(gè)by
te數(shù)組里面包含了很多項(xiàng),并且有固定的結(jié)構(gòu)。我們來看看里面的具體結(jié)構(gòu):

山東掌趣網(wǎng)絡(luò)科技
?
開始是兩個(gè)固定長度的數(shù)值,分別表示Key的長度和Value的長度。緊接著是Key,開始是固定長度的數(shù)值,表示RowKey的長度,緊接著是 RowKey,然后是固定長度的數(shù)值,表示Family的長度,然后是Family,接著是Qualifier,然后是兩個(gè)固定長度的數(shù)值,表示Time Stamp和Key Type(Put/Delete)。Value部分沒有這么復(fù)雜的結(jié)構(gòu),就是純粹的二進(jìn)制數(shù)據(jù)了。
HBase讀實(shí)現(xiàn)
通過上文的描述,我們知道在HBase寫時(shí),相同Cell(
RowKey/ColumnFamily/Column相同)并不保證在一起,甚至刪除一個(gè)Cell也只是寫入一個(gè)新的Cell,它含有Delete標(biāo)記,而不一定將一個(gè)Cell真正刪除了,因而這就引起了一個(gè)問題,如何實(shí)現(xiàn)讀的問題?要解決這個(gè)問題,我們先來分析一下相同的Cell可能存在的位置:首先對新寫入的Cell,它會存在于MemStore中;然后對之前已經(jīng)Flush到HDFS中的Cell,它會存在于某個(gè)或某些StoreFile(HFile)中;最后,對剛讀取過的Cell,它可能存在于BlockCache中。既然相同的Cell可能存儲在三個(gè)地方,在讀取的時(shí)候只需要掃瞄這三個(gè)地方,然后將結(jié)果合并即可(Merge Read),在HBase中掃瞄的順序依次是:BlockCache、MemStore、StoreFile(HFile)。其中StoreFile的掃瞄先會使用Bloom Filter過濾那些不可能符合條件的HFile,然后使用Block Index快速定位Cell,并將其加載到BlockCache中,然后從BlockCache中讀取。我們知道一個(gè)HStore可能存在多個(gè)StoreFile(HFile),此時(shí)需要掃瞄多個(gè)HFile,如果HFile過多又是會引起性能問題。

?山東掌趣網(wǎng)絡(luò)科技
?
MemStore每次Flush會創(chuàng)建新的HFile,而過多的HFile會引起讀的性能問題,那么如何解決這個(gè)問題呢?HBase采用Compaction機(jī)制來解決這個(gè)問題在HBase中Compaction分為兩種:Minor Compaction和Major Compaction。
Minor Compaction是指選取一些小的、相鄰的StoreFile將他們合并成一個(gè)更大的StoreFile,在這個(gè)過程中不會處理已經(jīng)Deleted或Expired的Cell。一次Minor Compaction的結(jié)果是更少并且更大的StoreFile。
Major Compaction是指將所有的StoreFile合并成一個(gè)StoreFile,在這個(gè)過程中,標(biāo)記為Deleted的Cell會被刪除,而那些已經(jīng)Expired的Cell會被丟棄,那些已經(jīng)超過最多版本數(shù)的Cell會被丟棄。一次Major Compaction的結(jié)果是一個(gè)HStore只有一個(gè)StoreFile存在。Major Compaction可以手動或自動觸發(fā),然而由于它會引起很多的IO操作而引起性能問題,因而它一般會被安排在周末、凌晨等集群比較閑的時(shí)間。

山東掌趣網(wǎng)絡(luò)科技
?
HRegion Split
最初,一個(gè)Table只有一個(gè)HRegion,隨著數(shù)據(jù)寫入增加,如果一個(gè)HRegion到達(dá)一定的大小,就需要Split成兩個(gè)HRegion,這個(gè)大小由
hbase.hregion.max.filesize指定,默認(rèn)為10GB。當(dāng)split時(shí),兩個(gè)新的HRegion會在同一個(gè)HRegionServer中創(chuàng)建,它們各自包含父HRegion一半的數(shù)據(jù),當(dāng)Split完成后,父HRegion會下線,而新的兩個(gè)子HRegion會向HMaster注冊上線,處于負(fù)載均衡的考慮,這兩個(gè)新的HRegion可能會被HMaster分配到其他的HRegionServer中。

山東掌趣網(wǎng)絡(luò)科技
?
在HRegion Split后,兩個(gè)新的HRegion最初會和之前的父HRegion在相同的HRegionServer上,出于負(fù)載均衡的考慮,HMaster可能會將其中的一個(gè)甚至兩個(gè)重新分配的其他的HRegionServer中,此時(shí)會引起有些HRegionServer處理的數(shù)據(jù)在其他節(jié)點(diǎn)上,直到下一次Major Compaction將數(shù)據(jù)從遠(yuǎn)端的節(jié)點(diǎn)移動到本地節(jié)點(diǎn)。
HRegionServer Recovery
當(dāng)一臺HRegionServer宕機(jī)時(shí),由于它不再發(fā)送Heartbeat給ZooKeeper而被監(jiān)測到,此時(shí)ZooKeeper會通知HMaster,HMaster會檢測到哪臺HRegionServer宕機(jī),它將宕機(jī)的HRegionServer中的HRegion重新分配給其他的HRegionServer,同時(shí)HMaster會把宕機(jī)的HRegionServer相關(guān)的WAL拆分分配給相應(yīng)的HRegionServer(將拆分出的WAL文件寫入對應(yīng)的目的HRegionServer的WAL目錄中,并并寫入對應(yīng)的DataNode中),從而這些HRegionServer可以Replay分到的WAL來重建MemStore。

山東掌趣網(wǎng)絡(luò)科技
?山東掌趣網(wǎng)絡(luò)科技