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

HBase求生之路(優化篇)

在這裏插入圖片描述


熱點問題

什麼叫熱點問題,什麼叫預分區?什麼叫RowKey設計?三里屯VIP帶你慢慢了解三個問號小朋友。

什麼叫做預分區?大家都知道我Hbase建立一張表,會有一個Region,有這麼一個分區的概念,正常情況下,我們的Region是不是會隨着數據量的增長,會進行分裂Split,它這個分裂是不是自動分裂的,最開始只有一個,後來纔會逐漸變成多個Region,它自己去分裂,其實是有一些不好的地方,哪些地方不好?

第一點:最開始我只有一個Region,那麼我的讀寫請求都要發往這一個Region,雖然我們HBase是一個分佈式NOSQL數據庫,但是你只有一個Region的時候和分佈式沒多大關係,你的讀寫請求還是發往一個Region的,我支持的吞吐量差一些,畢竟只有一個Region,我如果採用自動分裂的話,我在分裂的時候不會那麼及時的分裂的,只有等到這個Region達到一定的大小之後,纔會進行分裂,說白了,我經過一定的時間,我纔會有多個Region,我們的表,在很長一段時間內,我們的Region的個數,會很少,我讀寫的併發量上不去,尤其是我們自動分裂裏面的達到默認大小固定十個G,當1個region中的某個Store下所有StoreFile的總大小超過hbase.hregion.max.filesize,該Region就會進行拆分(0.94版本之前),也就是說,我要等一個Region中的Store大小達到10個G,它纔會分裂,很長一段時間,只會有很少的一些Region,分裂的很慢。這樣會導致我們的併發量上不去。 而且,我們Region分裂的時候,產生新的Region的時候,我們的RowKey範圍是我們控制不了的,人家自己選擇一個RowKey範圍,然後就分裂了,這樣有什麼不好呢?我們分裂完畢之後會請求新的Region,和老的Region沒什麼事了,但是我們自動分裂的不好就會導致,只往一個Region中,我們就會出現某一個Region負載過重,這就會很容易出現我們的Region熱點問題。俗稱:數據傾斜。

什麼時候會出現熱點問題?比如說我們的RowKey,RowKey是我們自己設置的,我們在工作的時候,可能會有這種業務需求,或者要求,需要將時間戳作爲我們的RowKey,因爲後續可能會需要我們的時間過濾我們的數據,我們假設就以時間戳作爲RowKey,建表的時候也沒有預分區,普通建表,一個分區,我這個數據往這個Region中寫的時候,是不是都往這個Region中去寫?隨着時間增長,它分裂了,它一個Region分裂成了兩個Region。

在這裏插入圖片描述
上圖兩個Region,RowKey範圍已經劃分,第一個0到20,第二個20到40,我們再寫數據的時候會往哪裏去寫?因爲我們是時間戳作爲RowKey,拿肯定時間戳越來越大,就會都往第二個裏面去寫,然後第二個也越來越大了,又分裂了。然後又變成兩個,然後又向它的第二個裏面去寫,然後又分裂,這就是很典型的Region熱點問題。

預分區


所謂預分區,就是在們建立表的時候指明,我們這張表要有幾個分區。每個分區,它的RowKey範圍是什麼?這個就是所謂的預分區,創建預分區表又幾種方式呢?


第一種:手動設定預分區

create+表名+列族+第二個列族(可加可不加看自己)+SPLITS+箭頭+數組。

啓動Hadoop集羣、zk集羣,然後輸入以下命令。 [fxy@hadoop101 hbase]$ bin/start-hbase.sh [fxy@hadoop101 hbase]$ bin/hbase shell hbase> create '表名','列族',SPLITS => ['1000','2000','3000','4000']
create 'partition','info',SPLITS => ['1000','2000','3000','4000']

在這裏插入圖片描述

數組相當於分區鍵,四個值會分成五個區。從負無窮到1000,1000到2000,2000到3000,3000到4000,4000到正無窮。

在這裏插入圖片描述

我們建立完之後,應該有五個分區纔對。

我們打開HBase的Master的界面,我們看一下,我們可以簡單的看一下每個分區的情況,我們可以在頁面中觀察的到。

在這裏插入圖片描述
往下拉,我們會看到Tables中的User Tables。還告訴我們Online Regions在線的分區有五個。

在這裏插入圖片描述
我們點進去看一下五個分區長什麼樣子。點擊partition。點擊Table Regions。會發現有五個分區。

在這裏插入圖片描述

前面的Name是一個Region的名字,一個隨機的字符串,後面有Start Key與 End Key。其實這裏的信息就相當於我們meta表中的信息了。


第二種:16進制序列預分區

我指明分區的個數NUMREGIONS => 15,分區鍵自己指定 SPLITALGO => ‘HexStringSplit’,SPLITALGO代表的是生成分區鍵的算法是什麼,後面的Hex十六進制,意思是十六進制字符串作爲我們的分區鍵。

create 'partition2','info',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}

在這裏插入圖片描述
我們到HBase中走一波,然後看一下效果。

在這裏插入圖片描述
在這裏插入圖片描述

我們點進去,看一下partition的Tables什麼樣子。

在這裏插入圖片描述

分區鍵全是十六進制的形式。這裏相當於每個分區都是一個八位的十六進制,那我們的RowKey會是什麼樣子呢?八位16進制數最大就是八個f,我現在是15個分區,15個分區再16進制裏除以f就可以了,我們還會發現八個3那個分區減去八個2,等於八個1,八個4減去八個3也是八個1,我們每個分區比前一個都多八個1,如果分成十個分區我們除以10就好了,那個就得自己去算了。八個f除以f等於八個1,就是這麼來的

假設我們,有一個abc這樣的RowKey,那麼它會進入到哪個分區(哪個Region)?很顯然它會進入到下面這個Region中。

在這裏插入圖片描述

但是我們能讓它進入到這個Region麼?答案是不能!如果我們今天以十六進制字符串爲分區鍵的話,那麼我們今天就不能讓RowKey以字符串的形式存在了。假設我今天abc了,那我還會有什麼f開頭的,z開頭的,那麼這些都比e要大,那麼這些數據都會進入到最後一個分區,又數據傾斜了。很顯然我們不能以普通字符串爲RowKey了。

那麼假設我的RowKey就想用abc,我怎麼處理以下比較合適呢?我應該將abc轉成16進制。
怎麼轉?

Bytes.toHex(Bytes.toBytes("abc")) 可以試一道,代碼複製粘貼即可 輸出結果:616263 61就是a 62是b 63是c

結論:如果採用16進制分區,那麼RowKey也要搞成16進制字符串


第三種:文件設置預分區

關閉HBaseShell客戶端窗口。

這個騷操作就相當於把分區鍵寫道文件當中了。

首先我們準備一個文件在集羣上。

[fxy@hadoop101 hbase]$ vim split.txt

在這裏插入圖片描述
我們寫這個分區鍵的時候,我們的分區鍵順序有沒有什麼要求?沒有要求,HBase很聰明,它會自己排序的。

我們啓動Hbase Shell的時候也要在當前路徑!!!
我們啓動Hbase Shell的時候也要在當前路徑!!!
我們啓動Hbase Shell的時候也要在當前路徑!!!

[fxy@hadoop101 hbase]$ bin/hbase shell
hbase(main):003:0> create 'partition3','info',SPLITS_FILE => 'split.txt'

在這裏插入圖片描述
在這裏插入圖片描述
我們去看一下WEB頁面,看一下partition3中的分區情況。

在這裏插入圖片描述
點進去看一下。

在這裏插入圖片描述

使用JAVA的API創建預分區表
//自定義算法,產生一系列Hash散列值存儲在二維數組中 byte[][] splitKeys = 某個散列值函數 //創建HbaseAdmin實例 HBaseAdmin hAdmin = new HBaseAdmin(HbaseConfiguration.create()); //創建HTableDescriptor實例 HTableDescriptor tableDesc = new HTableDescriptor(tableName); //通過HTableDescriptor實例和散列值二維數組創建帶有預分區的Hbase表 hAdmin.createTable(tableDesc, splitKeys);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章