天天看點

Hbase資料熱點和傾斜問題

介紹

Hbase每一條記錄是按照rowkey做為唯一辨別符設計的,rowkey按照字典順序排序,友善資料讀取掃描。衆所周知,資料是存儲在Region中,每個Region都包含rowkey開始和結束範圍,資料rowkey在哪個範圍尋找對應的Region進行存儲。

Region存儲範圍樣例:

Region start-rowkey end-rowkey
region-01 1 10 存儲rowkey在1-10範圍内的資料
region-02 11 20 存儲rowkey在11-20範圍内的資料
region-03 21 30 存儲rowkey在21-30範圍内的資料

以上就是資料在各個Region中的存儲方式,這種設計在給資料讀寫帶來友善的同時,也帶來了一些其他負面問題。

資料熱點(Hotspotting)

Hbase資料按照rowkey進行存儲,雖然為查詢資料提供了極大便利,但同時也産生了其他問題,比如資料熱點(Hotspotting)問題。當大部分rowkey集中在某個範圍時,會導緻某幾個Region資料量很大,其他Region資料量很少,這就是資料傾斜問題。是以整個叢集壓力都集中在某幾個Region上,導緻讀寫性能大幅度下降,這就是資料熱點問題。資料熱點問題嚴重情況下會導緻Region下線,甚至整個叢集當機。

為了避免以上現象,我們需要将資料盡可能的均勻分布在各個Region中,是以Hbase中rowkey的設計至關重要。

rowkey設計原則

了解Hbase資料的存儲原理和rowkey的作用之後,rowkey的設計就成為了重中之重。通常rowkey設計要遵循長度、散列、唯一三大原則。

長度:rowkey是以ByteArray進行存儲,可以是任意字元。rowkey設計越短越好,建議在16位元組以下。由于在底層資料檔案中是按照key-value形式存儲的,如果rowkey按照100位元組,1000萬條資料,那麼僅rowkey就占用了将近1GB空間。

散列:散列性原則是通過rowkey将資料均勻分布在各個Region中,避免資料傾斜和熱點問題。

唯一:rowkey代表每一行記錄的主鍵,必須具有唯一性。

資料傾斜和熱點問題

資料傾斜和熱點是一個很常見的問題,往往給生産和維護帶來了很大困擾。那麼如何有效的避免或減少這種問題呢?答案就是優化rowkey設計,官方提供了以下幾種優化方案:

參考網址:官方網址 第35章節Rowkey Design

Salting

原理:一句話簡單描述為在rowkey前邊加上随機值,其中随機值數量是region的個數。

假設有四個rowkey

foo0001、foo0002、foo0003、foo0004

我們想要均勻分布在四個region中,假設有a、b、c、d四個salt,每個salt都在不同的region上。加入salt後rowkey就變成了

a-foo0003、b-foo0001、c-foo0004、d-foo0002

每一個rowkey都增加了随機salt字首,這樣就能減輕資料傾斜問題

缺點:由于資料增加了随機字首salt,是以查詢就變得更加複雜

Hashing

原理:為了彌補随機字首對查詢帶來的影響,引申出了一種one-way hash方法,保證相同的rowkey永遠都有相同的字首salt。

還是上邊的例子,這次将salt換成hash(rowkey),這樣同一個rowkey生成的salt永遠一樣,保障了查詢性能。

Reversing the Key

原理:将rowkey中經常變化的數字部分或者固定長度的部分做為字首,這樣增加了散列性,能夠有效減緩資料傾斜問題。

缺點:有可能喪失了原來rowkey的有序性,對資料查詢帶來影響。

建表時預分區

在建表時根據資料量和資料分布情況,合理的設定Region數量,設計合适的rowkey。這樣一方面能有效避免資料傾斜問題,還能防止Region頻繁分裂和合并帶來額外的IO開銷。

缺點:這種方式有很大的局限性,隻适合有限的資料量或者增長緩慢的場景。

byte[][] splitKeys = {
		Bytes.toBytes("01"),
		Bytes.toBytes("02"),
		Bytes.toBytes("03"),
		Bytes.toBytes("04")
};
List<String> families = new ArrayList<>();
families.add("f1");
hbaseManager.createTable("test", families, splitKeys);
           

水準一般,能力有限,大資料國小生一枚。文章主要用于個人學習和總結,如果能給他人帶來幫助,純屬意外。

繼續閱讀