在通過 HBase Shell create 命令創建表時,可以使用多種選項來對錶進行預分區。最簡單的方法是在創建表時指定一個拆分點數組。
注意:當將字符串文本指定爲拆分點時,這些拆分點將基於字符串的底層字節表示創建拆分點。
因此,當指定一個 split point 爲'10'時,實際上是在指定字節分割'\x31\30'。
split point 將定義n+1個區域,其中n是分割點的數量。最小的 region 將包含從可能的最小鍵到第一個拆分點鍵的所有鍵(不包括第一個key)。下一個 region 將包含從第一個拆分點到下一個拆分點的鍵,但不包含下一個拆分點的鍵。以此類推直到分裂完成。最後一個 region 將從最後一個分割點定義到最大可能的鍵。
hbase>create 't1','f',SPLITS => ['10','20','30']
在下面的例子中,創建了一個列簇 f 的表 t1,預分4個區,第一個 region 包含從 '\x00' - '\x30' 的所有 key('\x31' 是 ASCII碼中的 1)。
可以使用 SPLITS_FILE 來指定一個文本文件,文件內寫入拆分點。在本例中,從與本地文件系統上的本地路徑對應的文件中讀取分割。文件中的每一行都指定一個 split point key。
hbase>create 't14','f',SPLITS_FILE=>'splits.txt'
其他選項是根據所需的區域數量和分割算法自動計算分割。HBase 提供了基於均勻分割或基於十六進制鍵來分割鍵範圍的算法,也可以提供自己的分割算法來細分鍵範圍。
# 基於隨機算法創建一個有4默認個分區的表
hbase>create 't2','f1', { NUMREGIONS => 4 , SPLITALGO => 'UniformSplit' }
# 基於 hex keys 創建一個有5個默認分區的表
hbase>create 'app_second_card_trmnl_info_m_hbase_new_fenqu2','f1', { NUMREGIONS => 500, SPLITALGO => 'HexStringSplit' }
NUMREGIONS說明:
hbase 默認 HFile 的大小爲 10G(hbase.hregion.max.filesize=10737418240=10G
)
源數據爲 Hive:推薦分區數 ≈ HDFS大小 / 10G * 10 *1.2
HexStringSplit、UniformSplit、DecimalStringSplit說明:
- UniformSplit(佔用空間小,rowkey前綴完全隨機):將可能的鍵的空間平均分割的聚合體。當鍵是近似一致的隨機字節時(例如散列),建議使用這個。行是範圍爲 00 => FF 的原始字節值,用0右填充以保持相同的 memcmp()順序。對於byte[]環境來說,這是一種自然的算法,可以節省空間,但是對於可讀性來說,它並不一定是最簡單的。
- HexStringSplit(佔用空間大,rowkey是十六進制的字符串作爲前綴的):HexStringSplit 是一個典型的
RegionSplitter.SplitAlgorithm來
選擇 region 邊界。HexStringSplit region 邊界的格式是MD5校驗和或任何其他均勻分佈的十六進制值的ASCII表示形式。Row是十六進制編碼的長值,其範圍爲“00000000”=>“FFFFFFFF”,並左填充0,以使其在字典上保持與二進制相同的順序。由於這種分割算法使用十六進制字符串作爲鍵,所以在 shell 中方便讀寫,但是佔用更多的空間,而且可能不夠直觀。 - DecimalStringSplit:rowkey是10進制數字字符串作爲前綴的
HBase Shell 實際上是一個 Ruby 環境,您可以使用簡單的 Ruby 腳本來計算分割算法。
# generate splits for long (Ruby fixnum) key range from start to end key
hbase(main):070:0> def gen_splits(start_key,end_key,num_regions)
hbase(main):071:1> results=[]
hbase(main):072:1> range=end_key-start_key
hbase(main):073:1> incr=(range/num_regions).floor
hbase(main):074:1> for i in 1 .. num_regions-1
hbase(main):075:2> results.push([i*incr+start_key].pack("N"))
hbase(main):076:2> end
hbase(main):077:1> return results
hbase(main):078:1> end
hbase(main):079:0>
hbase(main):080:0> splits=gen_splits(1,2000000,10)
=> ["\000\003\r@", "\000\006\032\177", "\000\t'\276", "\000\f4\375", "\000\017B<", "\000\022O{", "\000\025\\\272", "\000\030i\371", "\000\ew8"]
hbase(main):081:0> create 'test_splits','f',SPLITS=>splits
0 row(s) in 0.2670 seconds
=> Hbase::Table - test_splits
注意:HBase Shell 命令 truncate 刪除並使用默認選項重新創建表,默認選項將丟棄任何預拆分。如果需要重置預分區表,則必須刪除並顯式重新創建該表,以重新指定自定義分區選項。
總結:建表時,對錶進行預分區,可以防止單分區一次寫入數據過大,hbase 集羣本身還沒來得及自動分裂,導致 region 宕掉的問題。