HBase求生之路-----HBase優化(二)

RowKey設計

設計手段

1. 生成隨機數、hash、散列值

比如:
原本rowKey爲1001的,SHA1後變成:dd01903921ea24941c26a48f2cec24e0bb0e8cc7
原本rowKey爲3001的,SHA1後變成:49042c54de64a1e9bf0b33e00245660ef92dc7bd
原本rowKey爲5001的,SHA1後變成:7b61dec07e02c188790670af43e717f0f46e8913
在做此操作之前,一般我們會選擇從數據集中抽取樣本,來決定什麼樣的rowKey來Hash後作爲每個分區的臨界值

2. 字符串

    20170524000001轉成10000042507102
    20170524000002轉成20000042507102

3. 字符串拼接

20170524000001_a12e
20170524000001_93i7

設計思想

我們HBase實時項目可能用的會多一些,HBase可能會存實時數據的明細,比如:網站的訪問記錄,我們會實時的寫入到HBase的一張表中。

假設我們現在有這麼個需求,我們將網站的訪問記錄實時的寫入這個表中。

統計網站每分鐘的訪問次數,也就是PV,隨着時間的變化,我們網站PV的變化。那這個表我們後期怎麼分析我們想要的這個結果呢?去表裏找到每分鐘的訪問記錄,然後進行一個統計,比如19:19分這個時間節點,我們拿出來,看有多少條,是這樣的,19:20有多少個訪問,我又統計一個值,然後形成折線圖或者其他的圖都可以。

那麼這張表,我們怎麼設計?要求:不能有Region熱點問題。


如果用預分區?我們的分區鍵是什麼?我們的RowKey怎麼設計?

我們的RowKey必須是唯一性的這個要注意,我RowKey設計的時候,我後期一起查的數據,要保證他們在寫的時候就寫到一起了,我們查數據一般有兩種方式,一種是get,get這個無所謂了,get某一行,咋搞都行,如果是scan,我們需要掃描一個範圍,那麼我們就要保證我們想查詢的一部分數據,寫的時候就寫到了一起,如果不寫到一起我們就需要跨越多個Region去找這個數據,性能就會很差。

我們設計預分區也好,設計RowKey也好,首先要滿足我們的業務需求,我們最好是將同一分鐘的數據一起查出來,然後再去統計看有多少,怎樣更方便的查出來同一分鐘的訪問次數呢?我們後期查詢的數據我們寫的時候儘量都寫到一起,方便我們後期scan我們之前也說了。 怎麼放?同一分鐘數據放一起?怎麼搞,我們數據在不在一起,和我們的RowKey肯定要前綴相同,我們存的話肯定挨着存,挨着存的話就會在一起。最簡單的方式就是以時間戳作爲我們的RowKey,我們時間戳就不寫成毫秒數了,攜程年月日的方式。

在這裏插入圖片描述

那麼這個會不會出現我們所謂的Region熱點問題呢?肯定會的,咱麼設計RowKey的時候一定要極力的避免上圖中的設計,這種RowKey叫做單調遞增的RowKey,這樣的RowKey一般都會造成Region的熱點問題,每次都會遞增然後寫着寫着就要分裂,所以上圖雖然能達到我們的數據寫一起,但是要Pass。如果這樣設計還有一點就是違背了我們RowKey的唯一性原則,很有可能又不同的用戶同一毫秒訪問我們的網站,那麼這兩條訪問記錄就會變成一條數據,HBase特性,兩條一樣的RowKey寫進來的數據,相當於修改。

我們可以加一個UserID。

在這裏插入圖片描述

還有一種是我們公司常用的一種方式,就是加鹽,或者加Hash。

在這裏插入圖片描述

那麼不符合業務需求了,我們怎麼辦?我們是要將同一時間的數據都放在一起,這加個隨機數,數據就不會在一起了,查詢的時候效率就不高了,單純的加隨機數就不行了。

我們需要加一個有規律的隨機數。不能找非常隨機的數rand()這個。

在這裏插入圖片描述
如果變成上面的樣子,我們行不行?我們能保證同一分鐘的hashCode是一樣的,這個是沒問題的,那就是說,同一分鐘的數據能在一起了,能保證這個了,那麼問題來了,我們的分區,怎麼設計呢?怎樣將我們不同的數據,均勻的分到不同的分區裏面呢?

我們在這裏有一個非常通用的方式去做,就是取餘,我們用hashCode除個分區數,比如我分五個區。

在這裏插入圖片描述
雖然我們前面寫了一大串,但是我們得到的結果並不多,要麼0,要麼1,要麼2等等等等,就是一個數字而已。對RowKey的長度也沒有很大的影響,那我們好比5個分區,我們的分區鍵怎麼設計?1,2,3,4這就可以,四個分區鍵,我們可以分成5個區。

在這裏插入圖片描述
首先我們這個能不能滿足我們的業務需求?是能的。我們同一分鐘的數據在一起呢。
我們的RowKey這麼設計,那麼我查詢的時候怎麼查?
比如我們想查詢2020年06月26號15點55分的數據。
這時候我們肯定要用到scan(),然後我們肯定還有StartRow還有StopRow。

我們肯定要將前綴求出來,scan(“202006261555”.hashCode()%5),後面還得拼上時間,最後變成:scan(“202006261555”.hashCode()%5_202006261555),這個就是我們的StartRow,StopRow差不多也這麼寫,但是我們要注意我們最後要拼接一個較大的字符,用豎線就可以,

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章