rowKey設計原則 設計方法

2022-06-27 16:12:08 字數 3845 閱讀 1426

(1)rowkey 長度原則:

rowkey是乙個二進位製碼流,可以為任意字串,最大長度為64kb,實際應用中一般為10-100bytes,它以byte形式儲存,一般設定成定長。一般越短越好,不要超過16個位元組,注意原因如下:

1、目前作業系統都是64位系統,記憶體8位元組對齊,控制在16位元組,8位元組的整數倍利用了作業系統的最佳特性。

2、hbase將部分資料載入到記憶體當中,如果rowkey過長,記憶體的有效利用率就會下降。

2)rowkey 雜湊原則:

如果rowkey按照時間戳的方式遞增,不要將時間放在二進位製碼的前面,建議將rowkey的高位位元組採用雜湊字段處理,由程式隨即生成。低位放時間字段,這樣將提高資料均衡分布,各個regionserver負載均衡的機率。

如果不進行雜湊處理,首字段直接使用時間資訊,所有該時段的資料都將集中到乙個regionserver當中,這樣當檢索資料時,負載會集中到個別regionserver上,造成熱點問題,會降低查詢效率。

3)rowkey 唯一原則:

必須在設計上保證其唯一性,rowkey是按照字典順序排序儲存的,因此,設計rowkey的時候,要充分利用這個排序的特點,將經常讀取的資料儲存到一塊,將最近可能會被訪問的資料放到一塊。但是這裡的量不能太大,如果太大需要拆分到多個節點上去。

所以良好的rowkey設計,應當遵循三大原則,並且能讓資料分散,從而避免熱點問題。

(1)加鹽:

這裡所說的加鹽並非密碼學中的加鹽,而是在rowkey的前面分配隨機數,當給rowkey隨機字首後,它就能分布到不同的region中,這裡的字首應該和你想要資料分散的不同的region的數量有關。

為了讓同學們更好的理解加鹽(salting)這個rowkey設計方法。我們以電信公司為例。當我們去電信公司列印**詳單也就是聯絡歷史。對於聯絡歷史來說,每個人每月可能都有很多聯絡歷史,而使用電信的使用者也是億計。這種資訊,我們就能存入hbase當中。

對於聯絡歷史,我們有什麼資訊需要儲存呢?首先,肯定應該有主叫和被叫,然後有主叫被叫之間的通話時長,以及通話時間。除此之外,還應該有主叫的位置資訊,和被叫的位置資訊。

由此,我們的聯絡歷史表需要記錄的資訊就出來了:主叫、被叫、時長、時間、主叫位置、被叫位置。

我們該如何來設計一張hbase表呢?首先,hbase表是依靠rowkey來定位的,我們應該將盡可能多的將查詢的資訊編入rowkey當中。hbase的元資料表mate表就給我們了乙個很好的示例。它包括了namespace,表名,startkey,時間戳,計算出來的碼(用於分散資料)。

所以,當我們設計聯絡歷史的rowkey時,需要將能唯一確定該條記錄的資料編入rowkey當中。即是需要將主叫、被叫、時間編入。

如下所示:

17765657979 18688887777 201806121502 #主叫,被叫,時間
但是我們能否將我們設計的rowkey真正應用呢?當然是可以的,但是熱點問題便會隨之而來。

例如你的**是以177開頭,電信的hbase集群有500臺,你的資料就只可能被存入一台或者兩台機器的region當中,當你需要列印自己的聯絡歷史時,就只有一台機器為你服務。而若是你的資料均勻分散到500機器中,就是整個集群為你服務。兩者之間效率速度差了不止乙個數量級。

注意:由於我們的regionserver就只有一台,沒有集群環境,所以我們只介紹方法和理論操作,不提供實際結果

因為我們設定整個hbase集群有500臺,所以我們隨機在0-499之間中隨機數字,新增到rowkey首部。

如下所示: 

12 17765657979 18688887777 201806121502 #隨機數,主叫,被叫,時間
在插入資料時,判斷首部隨機數字,選擇對應的region存入,由於rowkey首部數字隨機,所以資料也將隨機分布到不同的regionserver中。這樣就能很好的避免熱點問題了。

補充:

1、加鹽後的資料如何讀取

(2)預分割槽

通常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-

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

(3)雜湊

細心的同學可能會發現,在我們剛剛提出的加鹽與預分割槽rowkey設計方法中,並沒有完整運用到rowkey設計的雜湊原則。

更一步思考下,我們會發現如果只運用加鹽與預分割槽rowkey設計方法,資料會真正無序隨即分布在hbase集群當中,這並沒有讓我們利用到hbase根據字典順序排序的這一特點。

由此,雜湊這一設計理念便順理成章的出現在我們眼前。

同樣以電信聯絡歷史為例,我們想將某一天的聯絡歷史存入同一region當中,所以我們利用雜湊函式算出雜湊值,再模以我們需要存入region數量,我們就能將相同輸入的資料,存入同一region當中。

在主叫,被叫,時間rowkey當中,我們將callerid(主叫)與 20180612(某一天的時間)作為參賽,傳入雜湊函式當中,將得到的雜湊值模以500,餘數新增到rowkey首部中,再結合預分割槽設計方法,就能將資料均勻分布到regionserver當中。

同時,我們還能將相同rowkey的資料收集到一台節點上,在避免熱點問題的情況下,充分利用hbase字典排序的優點。

(4)反轉

對於以手機號碼這樣比較固定開頭的rowkey(例如開頭177,159,138),但是它的後幾位都是隨機的,沒有規律的。我們可以將手機號反轉之後作為rowkey,這樣就避免了熱點問題。

這就是rowkey設計的另一種方法反轉,通過反轉固定長度或者數字格式的rowkey。這樣可以使得rowkey中經常改變的部分(最沒有意義的部分)放在前面。這樣可以有效的隨機rowkey,但是犧牲了rowkey的有序性。

使用hbase查詢訂單歷史:

**部落格:

4、hbase的scan 的 row key設計策略

hbase查詢scan優化和row設計策略

rowkey設計原則

rowkey是二進位製碼流,可以是任意字串,最大長度64kb。一 rowkey長度原則 建議越短越好,因為如果要儲存多行資料的話,單憑rowkey就要占用很多的儲存空間,這樣會嚴重影響hfile的儲存效率。二 rowkey雜湊原則 如果rowkey按照時間戳的方式遞增,不要將時間放在二進位製碼的前面...

rowkey設計原則和方法

rowkey是乙個二進位製碼流,可以為任意字串,最大長度為64kb,實際應用中一般為10 100bytes,它以byte形式儲存,一般設定成定長。一般越短越好,不要超過16個位元組,注意原因如下 1 目前作業系統都是64位系統,記憶體8位元組對齊,控制在16位元組,8位元組的整數倍利用了作業系統的最...

HBase之rowkey設計原則和方法

rowkey設計原則和方法 rowkey設計首先應當遵循三大原則 rowkey長度原則 rowkey是乙個二進位製碼流,可以為任意字串,最大長度為64kb,實際應用中一般為10 100bytes,它以byte形式儲存,一般設定成定長。一般越短越好,不要超過16個位元組,注意原因如下 1 目前作業系統...