1. 程式人生 > >為什麼在 HBase 中不建議單表列簇超過 3 個

為什麼在 HBase 中不建議單表列簇超過 3 個

開發十年,就只剩下這套架構體系了! >>>   

首先,我們來看一張 HBase 的儲存結構圖(圖片來源於網路),如下:

HBase 的資料儲存節點叫做 HRegionServer,每個 HRegionServer 管理很多個 HRegion,Region 是HBase你們資料管理的最小單元,不同的 Region 存放在不同的 HRegionServer 機器上。

每個 HRegion 由一個 HLog 和 一個或者多個 Store 組成。每個 Store 由儲存一個列簇 (columns family) 。 每個Strore又由一個memStore和 零個至多個StoreFile 組成。memStore 儲存在記憶體中, StoreFile 儲存在HDFS上。

說到這裡,我們可以很明顯的感知到,多個 Region 會造成效能問題,具體是什麼效能問題,接著往下看……但我們在想一個問題,Region 少一點繞開效能問題行不行。筆者直接告訴你,也不行!為什麼? Region 數目太少就會妨礙可擴充套件性,導致單個 Region 變得很大降低了並行度。

 

回到正題,我們在定義 HBase 表的時候,在沒有配置“hbase.hregion.max.filesize”的情況下,預設單個 Region 的大小為:10 * 1024 * 1024 * 1024,但寫入資料量超過該值,會造成 Region 的 split 動作。這個 RegionSplitPolicy 策略有如下幾種方式:

  • ConstantSizeRegionSplitPolicy : 這個是版本為 0.94.0 的預設region split 策略。根據公式min(r^2*flushSize,maxFileSize ) 確定split的maxFileSize,其中 r 為線上 Region個數,maxFileSize由hbase.hregion.max.filesize指定。
  •  
  • IncreasingToUpperBoundRegionSplitPolicy : 僅僅當region大小超過常量值(hbase.hregion.max.filesize大小)時,才進行拆分。
  •  
  • DelimitedKeyPrefixRegionSplitPolicy : 保證以分隔符前面的字首為splitPoint,保證相同RowKey字首的資料在一個Region中 。
  •  
  • KeyPrefixRegionSplitPolicy :保證具有相同字首的 Row 在一個Region中(要求設計中字首具有同樣長度)。指定 Rowkey 字首位數劃分 
    Region ,通過讀取 table 的 prefix_split_key_policy.prefix_length 屬性,該屬性為數字型別,表示字首長度,在進行 split 時,按此長度對splitPoint進行擷取。此種策略比較適合固定字首的 Rowkey。當table中沒有設定該屬性,或其屬性不為 Integer 型別時,指定此策略效果等同與使用IncreasingToUpperBoundRegionSplitPolicy。

在建表的時候可以直接手動分配分割槽方式,以避免熱點資料,也可以通過配置分割槽策略,通過配置檔案的方式生成的效果是全域性的,這點需要注意!

 

上面說了 HBase 的分割槽策略,接下來我們回到正題, 進行 Region Split 的條件為:1. 該 Region 下所有的 StoreFile 中最大的 StoreFile 檔案的大小超過閥值即進行 Split 在檔案層次上,不同的列族,儲存在不同的檔案中。但是不同的列族,可能會共享一個 Region。(問題點就在這裡了)

 

舉個例子:比如你有 A ,B 兩個列蔟,A 列蔟 有 1000w 行資料,B 列蔟有 10w 
行資料,也就是說 A 列簇儲存的資料量是 B 列簇儲存資料量的 100 倍。 A 列簇會發生多次 Split 動作,提升 A 列簇的併發性,而 B 列簇由於跟 A 列簇共同屬於一個 Region ,也會被動的 Split 掉了! B 列簇被 Split 後,單 Region 所持有的資料量變少了,這樣的話,就導致了掃描 B 列簇的效能下降很多。

 

其次,存在多個列簇的時候,由於它們是共享的同一個 Region,如果其中的一個 列簇觸發了 flush 動作,相應關聯的其他列簇也會進行 flush 。導致系統整體產生更多的 IO , 耗費資源 。

 

我們總結一下:

主要有兩點:

1. 多列簇導致持有資料量最少的列簇掃描效能下降,主要是因為資料太分散。

2. 系統產生更多的 IO ,耗費資源;

 

部落格地址:https://www.firegod.cn/2019/03/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8-hbase-%E4%B8%AD%E4%B8%8D%E5%BB%BA%E8%AE%AE%E5%8D%95%E8%A1%A8%E5%88%97%E7%B0%87%E8%B6%85%