HBase 是一種分布式、可擴充套件、海量資料儲存的列式儲存 NoSQL 資料庫,它基於 HDFS,由 ZooKeeper 管理,用於快速訪問資料。
HBase 中的每個區域都維護 startrowkey 和 endrowkey,如果新增的資料與某個區域維護的 rowkey 範圍匹配,則將資料移交給該區域進行維護。 根據這個原則,我們可以提前大致規劃好資料下發的分割槽,以提高HBase的效能。
HBase 中一條資料的唯一識別符號是 rowkey,因此資料儲存在哪個分割槽取決於 rowkey 在哪個預分割槽,設計 rowkey 的主要目的是將資料均勻分布在所有區域,在一定程度上防止資料傾斜。 接下來,我們來談談 Rowkey 的設計原則和常見的設計方案。
1. 設計原則
HBase 中的行按照 rowkey 的字典順序排序,優化了掃瞄操作,可以近距離訪問相關行和將一起讀取的行,方便掃瞄,但糟糕的 rowkey 設計是資料熱點的來源。 當大量客戶端直接訪問集群中的乙個或極少數節點(可能是讀、寫或其他操作)時,就會出現資料熱點。 大量請求會導致熱點區域中的單台機器超出其容量,導致效能下降甚至區域不可用,這也會影響同一區域的其他區域,導致主機無法處理來自其他區域的請求。 以下是 Roekey 的一些設計原則:
1.長度原則
在 HBase 中,要訪問乙個單元格,需要有行鍵、列和列名,如果行鍵和列名太大,會占用大量的記憶體空間,所以行鍵和列的長度應該盡可能短。 rowkey 的最大長度為 64kb,建議越短越好,長度為 10-100,最好是 8 的整數倍。
另外:如果 rowkey 是數值型別,建議使用 long 型別,因為 long 型別是 8 個位元組,8 個位元組可以容納非常大的無符號整數,例如:18446744073709551615。 如果是字串,則儲存為每個字元乙個位元組,這需要三倍的位元組儲存速度。
2.雜湊原理
如果 rowkey 是按照時間戳遞增的,不要把時間放在二進位程式碼的前面,建議用 rowkey 的高位作為程式隨機生成的 hash 字段,把時間字段放在低位,這樣會提高資料均勻分布在各個 regionserver 的概率,實現負載均衡。 如果沒有雜湊字段,則第乙個字段直接是時間資訊,所有資料都會集中在乙個 regionserver 上,這樣在檢索資料時負載會集中在特定的 regionserver 上,造成熱點問題,降低查詢效率。
3.唯一的原則
在設計 rowkey 時,必須保證 rowkey 的唯一性,因為 HBase 中的資料儲存是 key-value 的形式,如果將相同的 rowkey 資料插入到 HBase 的同一張表中,則現有資料會被新資料覆蓋。 而且,行鍵是按字典順序排序和儲存的,所以在設計行鍵時,要充分利用這種排序的特點,將經常讀取的資料儲存到一塊中,把最近可能訪問的資料放在一塊中。
4.分選原理
HBase 會按照 ASCII 的自然順序對行鍵進行排序,所以反過來,我們在設計行鍵時,可以根據這個特徵設計出完美的行鍵,利用好這個特性就是排序原則。
二、常用設計方案
1.反轉金鑰
反轉固定寬度的行鍵或數字行鍵,使變化最頻繁的部分(最低有效位)在前面,反轉分為一般資料反轉和時間戳反轉,其中時間戳反轉更為常見。
適用場景:比如我們最初設計的rowkey在資料分布上是不均勻的,但是rowkey尾部的資料表現出良好的隨機性(注意:強隨機性意味著它變化頻繁,沒有意義,但分布是好的),這時可以考慮翻轉rowkey的資訊,或者直接將尾部的位元組推進到rowkey的開頭。 反轉可以有效地使行鍵隨機分布,但反轉後肯定不能保證順序,因此犧牲了行鍵的有序性。
缺點:它適用於get操作,但不適用於掃瞄操作,因為原始行鍵上資料的自然順序已被打亂。
2. slat
SLAT 為每個 rowkey 新增乙個字首,字首使用一些隨機字元使資料分散在多個不同的區域,以達到區域負載均衡的目的。 由於這種分配是隨機的,因此如果您希望按字典順序檢索行,則需要做更多的工作,這樣,板條會增加寫入的吞吐量,但會以讀取為代價。
適用場景:例如,我們設計的 rowkey 是有意義的,但資料相似,隨機性相對較低,並且無法通過反轉來保證隨機性,因此無法根據rowkey將其分配到不同的區域。
需要注意的是,隨機數應該能夠確保資料在所有區域之間進行負載均衡,這意味著分配的隨機字首數應與要將資料分發到的區域數相同。 只有這樣,才會根據隨機生成的字首將加鹽的行鍵分發到每個區域,避免熱點。
缺點:因為新增的隨機數,如果新增後還是基於原來的rowkey查詢,是不可能知道隨機數是什麼的,所以在查詢的時候需要在每個可能的區域找到它,加鹽不利於讀取。 此外,加鹽會增加讀取和寫入過程中的吞吐量。
3.散 列
使用雜湊雜湊代替隨機鹽字首的優點是給定的行具有相同的字首,這不僅分散了區域的負載,而且縮短了讀取操作,並且確定性雜湊(例如在 md5 之後取前 4 個左字首)允許客戶端重建完整的 rowkey,並直接使用 get 操作來獲取所需的行。 資料量越大,分割槽越均衡,如果 rowkey 是數值型別,也可以考慮 mod 方法。
適用場景:其實雜湊和加鹽的適用場景是差不多的,但是因為加鹽方法的字首是隨機數,不方便用原來的rowkey查詢,所以出現了雜湊方法,因為雜湊是各種常用演算法計算出的字首,所以雜湊不僅可以將負載分攤到整個集群, 但也可以輕鬆讀取資料。
缺點:與反轉類似,雜湊也會破壞行鍵的自然順序,因此不利於掃瞄。
3. 總結
本文闡述了HBase的熱點資料問題,主要由RowKey設計不合理導致,基本設計原則包括RowKey的長度、雜湊、唯一性和排序,常見的幾種設計方案包括板條(拼接)、雜湊、金鑰反轉等。
對於這些行鍵設計方案,單一的設計有時並不能有效解決資料熱點問題,需要結合實際情況綜合運用多種方案,所以程式設計師遇到問題後,需要多做更多的測試,找到適合自己問題的方案。