Apache HBase region拆分
本篇文章主要分享Apache HBase如何通過regions實現負載均衡以及如何管理region拆分。
HBase以表的形式儲存多行資料。表被劃分為”regions“。Regions分佈在叢集的不同節點上,通過RegionServer程序被客戶端呼叫。一個region由一組連線的Key組成,從一個start key開始,以end key結尾。Region之間不會overlap,這意味著一個固定的row key在某一個時刻只屬於一個固定的region。一個region在某一個固定的時刻只會屬於一個Region Server,這保證了HBase對於單個row的強一致性。與-ROOT-和.META.一起,表上的regions形成一個3級B-Tree結構,以便高效地定位表中的一行資料。
Region由多個Stores組成,一個store對應一個列族(Column Family)。一個store由1個mestore及0個或多個store files組成。每個列族的資料儲存和獲取都是相互獨立的。
表由多個regions組成,這些regions分佈在多個Region Server上面。因此,regions是一種把讀寫請求分佈到不同的Region Server的物理機制。當表被建立時,HBase預設只會分配一個region。這意味著,初始狀態時所有的請求都會在一個Region Sever上,而無論當前有多少個Region Server。
預拆分(Pre-splitting)
自動拆分(Auto splitting)
不管是否使用預拆分,一旦region達到一個指定的上限,它會自動拆分為2個regions。如果使用HBase 0.94版本,可以通過配置決定HBase什麼時候拆分region,以及如何通過RegionSplitPolicy API計算拆分點。拆分機制包括多種,如 ConstantSizeRegionSplitPolicy, IncreasingToUpperBoundRegionSplitPolicy, 以及KeyPrefixRegionSplitPolicy。
ConstantSizeRegionSplitPolicy是在0.94版本以前預設的而且是唯一的拆分策略。當store的size達到配置的”hbase.hregion.max.filesize”(預設值為10G)時觸發拆分操作。這個拆分策略在當你完成預拆分步驟並且希望獲得相對低的region個數時候是十分理想的方案。
在0.94版本中,預設的拆分策略是IncreasingToUpperBoundRegionSplitPolicy。這種策略使用的最大store file size依據 Min(R^2 * “hbase.hregion.memstore.flush.size”, “hbase.hregion.max.filesize”),R代表同一臺Region Server節點上的region的個數。比如,在預設memstore flush size為128MB且預設的max store size為10G時,第一個region在128MB時拆分,隨著region個數的增加,將會使用512MB,1152MB,2GB,3.2GB,4.6GB,6.2GB等作為拆分點。在達到9個region之後,拆分的size會超過”hbase.hregion.max.filesize“,之後便都使用10GB作為拆分的size。
KeyPrefixRegionSplitPolicy是HBase一個新奇物。你可以配置row keys的字首的長度來進行分組,這種策略確保regions不會在一組有相同字首行的中間拆分。如果對keys設定了字首,可以使用這個拆分策略保證有相同rowkey字首的行落在一個region中。這個分組的方法有時候也稱為”Entity Groups”或”Row Groups”。
可以通過配置”hbase.regionserver.region.split.polity”來配置預設拆分策略,或者直接配置在表的定義裡面。
如果正在做pre-splitting,希望手動管理region拆分,也可以禁用region拆分,通過設定”hbase.region.max.filesize“為一個很高的值並且把拆分策略設為ConstantSizeRegionSplitPolicy。但需要設定一個安全的閾值如100GB,這樣regions增長不會超過Region Server的能力。可以考慮禁用自動拆分並依賴於初始region的設定(來源於預分割槽),比如,當使用統一的對key進行雜湊計算時,可以確保讀/寫負載以及資料儲存
分散到每個region中。
強制拆分(Force splits)
HBase允許從客戶端強制拆分一個線上的表。比如,HBase shell可以用來拆分一個表的所有regions,或者拆分一個region,如下
hbase(main):024:0> split 'b07d0034cbe72cb040ae9cf66300a10c', 'b'
0 row(s) in 0.1620 seconds
通過監控HBase的負載,如果發現某些regions負載不均衡,可以考慮手動拆分這些regions來均衡負載從而提升效能。另外一個需要強制拆分的原因是當發現初始的預拆分不正確的時候而且關閉了自動拆分。