深入 HBase 架構解析(2)

發表於2015-09-24

前言

這是《深入HBase架構解析(1)》的續,不多廢話,繼續。。。。

 

HBase讀的實現

通過前文的描述,我們知道在HBase寫時,相同Cell(RowKey/ColumnFamily/Column相同)並不保證在一起,甚至刪除一個Cell也只是寫入一個新的Cell,它含有Delete標記,而不一定將一個Cell真正刪除了,因而這就引起了一個問題,如何實現讀的問題?要解決這個問題,我們先來分析一下相同的Cell可能存在的位置:首先對新寫入的Cell,它會存在於MemStore中;然後對之前已經Flush到HDFS中的Cell,它會存在於某個或某些StoreFile(HFile)中;最後,對剛讀取過的Cell,它可能存在於BlockCache中。既然相同的Cell可能儲存在三個地方,在讀取的時候只需要掃瞄這三個地方,然後將結果合併即可(Merge Read),在HBase中掃瞄的順序依次是:BlockCache、MemStore、StoreFile(HFile)。其中StoreFile的掃瞄先會使用Bloom Filter過濾那些不可能符合條件的HFile,然後使用Block Index快速定位Cell,並將其載入到BlockCache中,然後從BlockCache中讀取。我們知道一個HStore可能存在多個StoreFile(HFile),此時需要掃瞄多個HFile,如果HFile過多又是會引起效能問題。


Compaction

MemStore每次Flush會建立新的HFile,而過多的HFile會引起讀的效能問題,那麼如何解決這個問題呢?HBase採用Compaction機制來解決這個問題,有點類似Java中的GC機制,起初Java不停的申請記憶體而不釋放,增加效能,然而天下沒有免費的午餐,最終我們還是要在某個條件下去收集垃圾,很多時候需要Stop-The-World,這種Stop-The-World有些時候也會引起很大的問題,比如參考本人寫的這篇文章,因而設計是一種權衡,沒有完美的。還是類似Java中的GC,在HBase中Compaction分為兩種:Minor Compaction和Major Compaction。

  • Minor Compaction是指選取一些小的、相鄰的StoreFile將他們合併成一個更大的StoreFile,在這個過程中不會處理已經Deleted或Expired的Cell。一次Minor Compaction的結果是更少並且更大的StoreFile。
  • Major Compaction是指將所有的StoreFile合併成一個StoreFile,在這個過程中,標記為Deleted的Cell會被刪除,而那些已經Expired的Cell會被丟棄,那些已經超過最多版本數的Cell會被丟棄。一次Major Compaction的結果是一個HStore只有一個StoreFile存在。Major Compaction可以手動或自動觸發,然而由於它會引起很多的IO操作而引起效能問題,因而它一般會被安排在週末、凌晨等叢集比較閒的時間。

更形象一點,如下面兩張圖分別表示Minor Compaction和Major Compaction。


 

HRegion Split

最初,一個Table只有一個HRegion,隨著資料寫入增加,如果一個HRegion到達一定的大小,就需要Split成兩個HRegion,這個大小由hbase.hregion.max.filesize指定,預設為10GB。當split時,兩個新的HRegion會在同一個HRegionServer中建立,它們各自包含父HRegion一半的資料,當Split完成後,父HRegion會下線,而新的兩個子HRegion會向HMaster註冊上線,處於負載均衡的考慮,這兩個新的HRegion可能會被HMaster分配到其他的HRegionServer中。關於Split的詳細資訊,可以參考這篇文章:《Apache HBase Region Splitting and Merging》。

 

HRegion負載均衡

在HRegion Split後,兩個新的HRegion最初會和之前的父HRegion在相同的HRegionServer上,出於負載均衡的考慮,HMaster可能會將其中的一個甚至兩個重新分配的其他的HRegionServer中,此時會引起有些HRegionServer處理的資料在其他節點上,直到下一次Major Compaction將資料從遠端的節點移動到本地節點。


HRegionServer Recovery

當一臺HRegionServer當機時,由於它不再傳送Heartbeat給ZooKeeper而被監測到,此時ZooKeeper會通知HMaster,HMaster會檢測到哪臺HRegionServer當機,它將當機的HRegionServer中的HRegion重新分配給其他的HRegionServer,同時HMaster會把當機的HRegionServer相關的WAL拆分分配給相應的HRegionServer(將拆分出的WAL檔案寫入對應的目的HRegionServer的WAL目錄中,並並寫入對應的DataNode中),從而這些HRegionServer可以Replay分到的WAL來重建MemStore。



HBase架構簡單總結

在NoSQL中,存在著名的CAP理論,即Consistency(一致性)、Availability(可用性)、Partition Tolerance(分割槽耐受性)不可全得,目前市場上基本上的NoSQL都採用Partition Tolerance以實現資料得水平擴充套件,來處理Relational DataBase遇到的無法處理資料量太大的問題,或引起的效能問題。因而只有剩下C和A可以選擇。HBase在兩者之間選擇了Consistency,然後使用多個HMaster以及支援HRegionServer的failure監控、ZooKeeper引入作為協調者等各種手段來解決Availability問題,然而當網路的Split-Brain(Network Partition)發生時,它還是無法完全解決Availability的問題。從這個角度上,Cassandra選擇了A,即它在網路Split-Brain時還是能正常寫,而使用其他技術來解決Consistency的問題,如讀的時候觸發Consistency判斷和處理。這是設計上的限制。

從實現上的優點:

  • HBase採用強一致性模型,在一個寫返回後,保證所有的讀都讀到相同的資料。
  • 通過HRegion動態Split和Merge實現自動擴充套件,並使用HDFS提供的多個資料備份功能,實現高可用性。
  • 採用HRegionServer和DataNode執行在相同的伺服器上實現資料的本地化,提升讀寫效能,並減少網路壓力。
  • 內建HRegionServer的當機自動恢復。採用WAL來Replay還未持久化到HDFS的資料。
  • 可以無縫的和Hadoop/MapReduce整合。

實現上的缺點:

  • WAL的Replay過程可能會很慢。
  • 災難恢復比較複雜,也會比較慢。
  • Major Compaction會引起IO Storm。
  • 。。。。

 

參考:

https://www.mapr.com/blog/in-depth-look-hbase-architecture#.VdNSN6Yp3qx
http://jimbojw.com/wiki/index.php?title=Understanding_Hbase_and_BigTable
http://hbase.apache.org/book.html 
http://www.searchtb.com/2011/01/understanding-hbase.html 
http://research.google.com/archive/bigtable-osdi06.pdf

相關文章