HBase之rowkey設計原則和方法

2021-10-02 02:35:43 字數 3519 閱讀 6802

rowkey設計原則和方法

rowkey設計首先應當遵循三大原則:

rowkey長度原則

rowkey是乙個二進位製碼流,可以為任意字串,最大長度為64kb,實際應用中一般為10-100bytes,它以byte形式儲存,一般設定成定長。

一般越短越好,不要超過16個位元組,注意原因如下:

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

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

rowkey雜湊原則

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

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

rowkey唯一原則

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

所以良好的rowkey設計,應當遵循三大原則,並且能讓資料分散,從而避免熱點問題。本節介紹幾種常用的rowkey設計方法,以供同學們學習。

注意:本節理論知識較多,不過都是大資料崗位面試中常見問題,希望同學們認真研讀。

1.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-

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

1.3 雜湊

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

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

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

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

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

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

1.4 反轉

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

Hbase之Rowkey設計原則

hbase是三維有序儲存的,通過rowkey 行鍵 column key column family和qualifier 和timestamp 時間戳 這個三個維度可以對hbase中的資料進行快速定位。hbase中rowkey可以唯一標識一行記錄,在hbase查詢的時候,有以下幾種方式 通過get方...

hbase實踐之Rowkey設計之道

筆者從一開始接觸hbase就在思考rowkey設計,希望rowkey設計得好,能夠支援查詢的需求。使用hbase一段時間後,再去總結一些hbase的設計方法,無外乎以下幾種 本質上都是避免熱點問題。那麼如何根據查詢場景設計rowkey?rowkey設計之道是什麼?hbase通過分治策略將資料分散到1...

HBase學習之HBase的RowKey設計原則

hbase是三維有序儲存的,通過rowkey 行鍵 column key column family和qualifier 和timestamp 時間戳 這個三個維度可以對hbase中的資料進行快速定位。hbase中rowkey可以唯一標識一行記錄,在hbase查詢的時候,有以下幾種方式 通過get方...