HBase中Memstore存在的意義以及多列族引起的問題和設計

大資料學習與分享發表於2020-12-02

Memstore存在的意義

HBase在WAL機制開啟的情況下,不考慮塊快取,資料日誌會先寫入HLog,然後進入Memstore,最後持久化到HFile中。HFile是儲存在hdfs上的,WAL預寫日誌也是,但Memstore是在記憶體的,增加Memstore大小並不能有效提升寫入速度,為什麼還要將資料存入Memstore中呢?

  1. Memstore在記憶體中維持資料按照row key順序排列,從而順序寫入磁碟
  2. 由於hdfs上的檔案不可修改,為了讓資料順序儲存從而提高讀取率,HBase使用了LSM樹結構來儲存資料,資料會先在Memstore中整理成LSM樹,最後再刷寫到HFile上
  3. 優化資料的儲存,比如一個資料新增後就馬上刪除了,這樣在刷寫的時候就可以直接不把這個資料寫到HFile上

需要注意一點:資料讀取不一定都是先讀取Memstore,再讀取磁碟。一般在讀取HBase資料時,我們會開啟快取機制BlockCache,讀取資料時會先讀取該快取,獲取不到資料時會讀Memstore和HFile。

這也是筆者一直強調為什麼HBase資料最終持久化到hdfs上,但讀寫效能卻優於hdfs的主要原因之一:HBase通過多種機制將磁碟隨機讀寫轉為順序讀寫。

多列族引起的問題和設計

HBase叢集的每個region server會負責多個region,每個region又包含多個store,每個store包含Memstore和StoreFile。HBase表中,每個列族對應region中的一個store。預設情況下,只有一個region,當滿足一定條件,region會進行分裂。如果一個HBase表中設定過多的列族,則可能引起以下問題:

  1. 一個region中存有多個store,當region分裂時導致多個列族資料存在於多個region中,查詢某一列族資料會涉及多個region導致查詢效率低(這一點在多個列族儲存的資料不均勻時尤為明顯)
  2. 多個列族則對應有多個store,那麼Memstore也會很多,因為Memstore存於記憶體,會導致記憶體的消耗過大
  3. HBase中的壓縮和快取flush是基於region的,當一個列族出現壓縮或快取重新整理時會引起其他列族做同樣的操作,列族過多時會涉及大量的IO開銷

所以,我們在設計HBase表的列族時,遵循以下幾個主要原則,以減少檔案的IO、定址時間:

  1. 列族數量,要儘可能的少
  2. 列族名字可讀性好,但不能過長。原因可類比於HBase row key設計原則


關聯文章:

深入探討HBASE

HBase高階特性、rowkey設計以及熱點問題處理


 

關注微信公眾號:大資料學習與分享,獲取更對技術乾貨

相關文章