1. 程式人生 > >Region拆分策略

Region拆分策略

Region 概念

Region是表獲取和分佈的基本元素,由每個列族的一個Store組成。物件層級圖如下:

Table       (HBase table)
    Region       (Regions for the table)
         Store          (Store per ColumnFamily for each Region for the table)
              MemStore        (MemStore for each Store for each Region for the table)
              StoreFile       (StoreFiles for each Store for each Region for the table)
                    Block     (Blocks within a StoreFile within a Store for each Region for the table)

Region 大小

Region的大小是一個棘手的問題,需要考量如下幾個因素。

  • Region是HBase中分散式儲存和負載均衡的最小單元。不同Region分佈到不同RegionServer上,但並不是儲存的最小單元。
  • Region由一個或者多個Store組成,每個store儲存一個columns family,每個Strore又由一個memStore和0至多個StoreFile 組成。memStore儲存在記憶體中, StoreFile儲存在HDFS上。
  • HBase通過將region切分在許多機器上實現分散式。也就是說,你如果有16GB的資料,只分了2個region, 你卻有20臺機器,有18臺就浪費了。
  • region數目太多就會造成效能下降,現在比以前好多了。但是對於同樣大小的資料,700個region比3000個要好。
  • region數目太少就會妨礙可擴充套件性,降低並行能力。有的時候導致壓力不夠分散。這就是為什麼,你向一個10節點的HBase叢集匯入200MB的資料,大部分的節點是idle的。
  • RegionServer中1個region和10個region索引需要的記憶體量沒有太多的差別。

最好是使用預設的配置,可以把熱的表配小一點(或者受到split熱點的region把壓力分散到叢集中)。如果你的cell的大小比較大(100KB或更大),就可以把region的大小調到1GB。region的最大大小在hbase配置檔案中定義:

 <property>
    <name>hbase.hregion.max.filesize</name>
    <value>10 * 1024 * 1024 * 1024</value>
  </property>

說明:

  1. 當region中的StoreFile大小超過了上面配置的值的時候,該region就會被拆分,具體的拆分策略見下文。
  2. 上面的值也可以針對每個表單獨設定,例如在hbase shell中設定:
create 't','f'
disable 't'
alter 't', METHOD => 'table_att', MAX_FILESIZE => '134217728'
enable 't'

Region 拆分策略

Region的分割操作是不可見的,因為Master不會參與其中。RegionServer拆分region的步驟是,先將該region下線,然後拆分,將其子region加入到META元資訊中,再將他們加入到原本的RegionServer中,最後彙報Master。

執行split的執行緒是CompactSplitThread。

自定義拆分策略

可以通過設定RegionSplitPolicy的實現類來指定拆分策略,RegionSplitPolicy類的實現類有:

ConstantSizeRegionSplitPolicy
	IncreasingToUpperBoundRegionSplitPolicy
		DelimitedKeyPrefixRegionSplitPolicy
		KeyPrefixRegionSplitPolicy

對於split,並不是設定了hbase.hregion.max.filesize(預設10G)為很大就保證不split了,需要有以下的演算法:

  • IncreasingToUpperBoundRegionSplitPolicy,0.94.0預設region split策略。根據公式min(r^2*flushSize,maxFileSize)確定split的maxFileSize,其中r為線上region個數,maxFileSize由hbase.hregion.max.filesize指定。
  • ConstantSizeRegionSplitPolicy,僅僅當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。

IncreasingToUpperBoundRegionSplitPolicy

這是0.94.0預設region split策略。根據根據公式min(r^2*flushSize,maxFileSize)確定split的maxFileSize,這裡假設flushSize為128M:

第一次拆分大小為:min(10G,1*1*128M)=128M
第二次拆分大小為:min(10G,3*3*128M)=1152M
第三次拆分大小為:min(10G,5*5*128M)=3200M
第四次拆分大小為:min(10G,7*7*128M)=6272M
第五次拆分大小為:min(10G,9*9*128M)=10G
第五次拆分大小為:min(10G,11*11*128M)=10G

可以看到,只有在第四次之後的拆分大小才為10G

配置拆分策略

你可以在hbase配置檔案中定義全域性的拆分策略,設定hbase.regionserver.region.split.policy的值即可,也可以在建立和修改表時候指定:

// 更新現有表的split策略
HBaseAdmin admin = new HBaseAdmin( conf);
HTable hTable = new HTable( conf, "test" );
HTableDescriptor htd = hTable.getTableDescriptor();
HTableDescriptor newHtd = new HTableDescriptor(htd);
newHtd.setValue(HTableDescriptor. SPLIT_POLICY, KeyPrefixRegionSplitPolicy.class .getName());// 指定策略
newHtd.setValue("prefix_split_key_policy.prefix_length", "2");
newHtd.setValue("MEMSTORE_FLUSHSIZE", "5242880"); // 5M
admin.disableTable( "test");
admin.modifyTable(Bytes. toBytes("test"), newHtd);
admin.enableTable( "test");

說明:

  1. 上面的不同策略可以在不同的業務場景下使用,特別是第三種和第四種一般關注和使用的比較少。
  2. 如果想關閉自動拆分改為手動拆分,建議同時修改hbase.hregion.max.filesizehbase.regionserver.region.split.policy值。