hbase預分割槽問題

2021-10-21 14:02:20 字數 3032 閱讀 3474

通常hbase會自動處理region拆分,當region的大小到達一定閾值後,region將被拆分成兩個,之後在兩個region都能繼續增長資料。

然而在這個過程當中,會出現兩個問題:

第一點,就是我們所說的熱點問題,資料會繼續往乙個region中寫,出現寫熱點問題;

第二點,則是拆分合併風暴,當使用者的region大小以恆定的速度增長,region的拆分會在同一時間發生,因為同時需要壓縮region中的儲存檔案,這個過程會重寫拆分後的region,這將會引起磁碟i/o上公升 。

壓縮:hbase支援大量的壓縮演算法,而且通常開啟壓縮,因為cpu壓縮和解壓的時間比從磁碟讀寫資料的時間消耗的更短,所以壓縮會帶來效能的提公升。

對於拆分合併風暴,通常我們需要關閉hbase的自動管理拆分。然後手動呼叫hbase的split(拆分)和major_compact(壓縮),對其進行時間控制,來分散i/o負載。但是其中的split操作同樣是高i/o的操作。

所謂預分割槽,就是預先建立hbase表分割槽。這需要我們明確rowkey的取值範圍和構成邏輯。

比如前面我們所列舉的電信**詳單錶。通過加鹽我們得到的 rowkey構成是:隨機數+主叫+被叫+時間,如果我們現在並沒有500臺機器,只有10臺,但是按照我們的計畫,未來將擴充套件到500臺的規模。所以我們仍然設計0到499的隨機數,但是將以主叫177開頭的聯絡歷史分配到十個region當中,所以我們將隨機數均分成十個區域,範圍如下:

-50,50-100,100-150,150-200,200-250,250-300,300-350,350-400,400-450,450-

然後我們將我們的預分割槽存入陣列當中,當插入資料時,先根據插入資料的首部隨機數,判斷分割槽位置,再進行插入資料。同樣,這樣也能使得各台節點負載均衡。

如果在hbase shell中使用create建表時只寫了表名和列族名**,那麼這張表將只有乙個region ,當乙個region的大小超過閾值時會自動split成兩個**,但split操作會帶來資源消耗。region個數太少時,在資料量大、訪問量大,或被批處理程式讀寫情況下效能可能會很差,並且伴隨大批量讀寫而來的gc可能會使regionserver宕機,接著region被transit到其他節點上,將逐步拖垮hbase集群上的所有節點。

所以推薦在建表時進行預分割槽,充分考慮rowkey的分布做出合理的預分割槽方案,要考慮的點包括region的個數、region的大小等。
如果使用mapreduce讀取hbase表資料,map的個數等於該錶region的個數,每個region都會有乙個單獨程序來處理,這個程序會逐條處理region中的每一行資料。舉例來說如果只有乙個region,那麼讀取資料的就只有乙個程序;如果拆成10個資料均勻分布的region,那麼10個map會帶來10倍的效率提公升。

大資料量情況下越發需要並行處理,因此我們往往希望源表的region的個數多一些。但是同時也要考慮集群的承載能力,hbase的region個數上限可以參考官網給出的如下公式,其中rs xmx是regionserver的記憶體堆疊大小,官網建議每台20~24或更小,因為過大的記憶體會導致gc時間過長(gc方式從cms改為g1後可以增大該值,機器記憶體足夠的情況下可以翻倍甚至更大)。

((rs xmx) *hbase.regionserver.global.memstore.size) / (hbase.hregion.memstore.flush.size (# column families))。

即24g0.45/128m=86.4個,在實際使用中很容易超過這個值。另外官網建議每個rs 20~200個regions是比較合理的。因此region個數也不是越多越好,還要考慮集群情況。我們可以在hbase webui上看到這個值。

對於不需要用mr批量讀hbase表,相比需要mr讀的表region個數可以少一些,以此來控制regionserver上region總數。

**region的大小**

單個region最大大小官方**推薦5~10gb**,這是三備份前的資料大小,通過hbase.hregion.max.filesize配置,當超過這個值後region會split,估計好資料量並合理的劃分region會減少不必要的效能損失。甚至設定足夠大的值,日常監控中發現過大後手工做split。

預建region可以在shell中或者程式中實現,網上很多文章,如下是一些例子,不再贅述。要想清楚rowkey的邊界,比如對於全部都是數字開頭的rowkey,分200個region,邊界就是000,005,010……995。
hbase> create 't1'

,'f1'

, splits =

>

['10'

,'20'

,'30'

,'40'

] hbase> create 't1'

,'f1'

, splits_file =

>

'splits.txt'

hbase> create 't1'

,'f1'

, private void createtable()

htabledescriptor tabledesc = new

htabledescriptor(tablenamev)

; hcolumndescriptor columndesc = new

hcolumndescriptor(columnfamilyname)

; tabledesc.addfamily(columndesc)

; admin.createtable(tabledesc, splits())

; system.out.println(

"created table : "

+ tablename + "

successfully.")

;} catch (exception e)

} private static byte splits(

)

rowkey的設計及rowkey如何匹配分配到各個分割槽上?

參考

HBase預分割槽

hbase提供了預分割槽功能,即使用者可以在建立表的時候對錶按照一定的規則分割槽。hbase表在剛剛被建立時,只有1個分割槽 region 當乙個region過大 達到hbase.hregion.max.filesize屬性中定義的閾值,預設10gb 時,表將會進行split,為2個分割槽。表在進行...

HBase預分割槽 UniformSplit

如果某個hbase的表查詢只是以隨機查詢為主,可以用uniformsplit的方式進行,它是按照原始byte值 從0x00 0xff 右邊以00填充。以這種方式分割槽的表在插入的時候需要對rowkey進行乙個技巧性的改造,比如原來的rowkey為rawstr,則需要對其取hashcode,然後進行按...

hbase預分割槽總結

如果知道hbase資料表的key的分布情況,就可以在建表的時候對hbase進行region的預分割槽。這樣做的好處是防止大資料量插入的熱點問題,提高資料插入的效率。1.規劃hbase預分割槽 首先就是要想明白資料的key是如何分布的,然後規劃一下要分成多少region,每個region的startk...