用大白话彻底搞懂 HBase RowKey 详细设计
來源 |?且聽_風(fēng)吟
來源 | CSDN 博客,責(zé)編 | Carol
封圖?| CSDN 付費(fèi)下載于東方 IC
前言
RowKey作為HBase的核心知識(shí)點(diǎn),RowKey設(shè)計(jì)會(huì)影響到數(shù)據(jù)在HBase中的分布,還會(huì)影響我們查詢效率,所以RowKey的設(shè)計(jì)質(zhì)量決定了HBase的質(zhì)量。是咱們大數(shù)據(jù)從業(yè)者必知必會(huì)的,自然也是面試必問的考察點(diǎn)。
那么rowkey到底是什么呢?原理是什么呢?怎么設(shè)計(jì)RowKey呢?使用場(chǎng)景是怎樣的呢?有哪些設(shè)計(jì)原則呢?又如何進(jìn)行優(yōu)化呢?
下面就讓我們帶著這些問題,一起探索RowKey的世界!
RowKey的概念
RowKey從字面意思來看是行鍵的意思,咱們知道HBase可以理解為一個(gè)nosql(not only sql)數(shù)據(jù)庫,既然是數(shù)據(jù)庫,那么咱們?nèi)粘J褂米疃嗟木褪窃鰟h改查(curd)。其實(shí)在增刪改查的過程中RowKey就充當(dāng)了主鍵的作用,它和眾多的nosql數(shù)據(jù)庫一樣,可以唯一的標(biāo)識(shí)一行記錄。
RowKey行鍵 (RowKey)可以是任意字符串,在HBase內(nèi)部,RowKey保存為字節(jié)數(shù)組。存儲(chǔ)時(shí),數(shù)據(jù)按照RowKey的字典序(byte order)排序存儲(chǔ)。設(shè)計(jì)RowKey時(shí),要充分利用排序存儲(chǔ)這個(gè)特性,將經(jīng)常一起讀取的行存儲(chǔ)放到一起。
RowKey的特點(diǎn)小結(jié)如下:
RowKey類似于主鍵,可以唯一的標(biāo)識(shí)一行記錄;
由于數(shù)據(jù)按照RowKey的字典序(byte order)排序存儲(chǔ),因此HBase中的數(shù)據(jù)永遠(yuǎn)都是有序的。
RowKey可以由用戶自己指定,只要保證這個(gè)字符串不重復(fù)就可以了。
知識(shí)點(diǎn)補(bǔ)充:在HBase中檢索數(shù)據(jù)時(shí)使用到RowKey的一共有三種方式:
get:通過指定單個(gè)RowKey來獲取對(duì)應(yīng)的唯一一條記錄;
like:通過RowKey的range來進(jìn)行匹配;
scan:通過設(shè)置startRow和stopRow參數(shù)來進(jìn)行范圍匹配(注意:如果不設(shè)置就是全表掃描)。
RowKey的作用
要了解RowKey的作用,首先我們需要知道在HBase中,一個(gè)Region就相當(dāng)于一個(gè)數(shù)據(jù)分片,每個(gè)Region都有StartRowKey和StopRowKey(用來表示 Region存儲(chǔ)的RowKey的范圍),HBase表里面的數(shù)據(jù)是按照RowKey來分散存儲(chǔ)到不同的Region里面的。
為了避免熱點(diǎn)現(xiàn)象咱們需要將數(shù)據(jù)記錄均衡的分散到不同的Region中去,因此需要RowKey滿足這種散列的特點(diǎn)。此外,在數(shù)據(jù)讀寫過程中也是與RowKey密切相關(guān)的。RowKey的作用可以歸納如下:
Hbase在讀寫數(shù)據(jù)時(shí)需要通過RowKey找到對(duì)應(yīng)的Region;
MemStore和HFile中的數(shù)據(jù)都是按照 RowKey 的字典序排序。
那到底啥是熱點(diǎn)現(xiàn)象呢?咱們接著分析!
熱點(diǎn)現(xiàn)象
4.1、熱點(diǎn)現(xiàn)象怎么產(chǎn)生
我們知道HBase中的行是按照rowkey的字典順序排序的,這種設(shè)計(jì)優(yōu)化了 scan操作,可以將相關(guān)的行以及會(huì)被一起讀取的行存取在臨近位置,便于 scan讀取。
然而萬事萬物都有兩面性,在咱們實(shí)際生產(chǎn)中,當(dāng)大量請(qǐng)求訪問HBase集群的一個(gè)或少數(shù)幾個(gè)節(jié)點(diǎn),造成少數(shù)RegionServer的讀寫請(qǐng)求過多,負(fù)載過大,而其他RegionServer負(fù)載卻很小,這樣就造成熱點(diǎn)現(xiàn)象(吐槽:其實(shí)和數(shù)據(jù)傾斜類似,還整這么高大上的名字)。
掌握了熱點(diǎn)現(xiàn)象的概念,我們就應(yīng)該知道大量的訪問會(huì)使熱點(diǎn)Region所在的主機(jī)負(fù)載過大,引起性能下降,甚至導(dǎo)致Region不可用。所以我們?cè)谙騂Base中插入數(shù)據(jù)的時(shí)候,應(yīng)優(yōu)化RowKey的設(shè)計(jì),使數(shù)據(jù)被寫入集群的多個(gè)region,而不是一個(gè)。盡量均衡地把記錄分散到不同的Region中去,平衡每個(gè)Region的壓力。
其實(shí)RowKey的優(yōu)化主要就是在解決怎么避免熱點(diǎn)現(xiàn)象。那么有哪些避免熱點(diǎn)現(xiàn)象的方法呢?各有什么缺點(diǎn)?帶著問題,接著往下看。
4.2、如何避免熱點(diǎn)現(xiàn)象(RowKey的優(yōu)化)
在日常使用中,主要有3個(gè)方法來避免熱點(diǎn)現(xiàn)象,分別是反轉(zhuǎn),加鹽和哈希。聽起來很奇怪,下面咱們逐個(gè)舉例詳細(xì)分析:
4.2.1、反轉(zhuǎn)(Reversing)
第一種咱們要分析的方法是反轉(zhuǎn),顧名思義它就是把固定長(zhǎng)度或者數(shù)字格式的 rowkey進(jìn)行反轉(zhuǎn),反轉(zhuǎn)分為一般數(shù)據(jù)反轉(zhuǎn)和時(shí)間戳反轉(zhuǎn),其中以時(shí)間戳反轉(zhuǎn)較常見。
適用場(chǎng)景:
比如咱們初步設(shè)計(jì)出的RowKey在數(shù)據(jù)分布上不均勻,但RowKey尾部的數(shù)據(jù)卻呈現(xiàn)出了良好的隨機(jī)性(注意:隨機(jī)性強(qiáng)代表經(jīng)常改變,沒意義,但分布較好),此時(shí),可以考慮將RowKey的信息翻轉(zhuǎn),或者直接將尾部的bytes提前到RowKey的開頭。反轉(zhuǎn)可以有效的使RowKey隨機(jī)分布,但是反轉(zhuǎn)后有序性肯定就得不到保障了,因此它犧牲了RowKey的有序性。
缺點(diǎn):
利于Get操作,但不利于Scan操作,因?yàn)閿?shù)據(jù)在原RowKey上的自然順序已經(jīng)被打亂。
舉例:
比如咱們通常會(huì)有需要快速獲取數(shù)據(jù)的最近版本的數(shù)據(jù)處理需求,這時(shí)候就需要把時(shí)間戳作為RowKey來查詢了,但是時(shí)間戳正常情況下是這樣的:
1588610367373 1588610367396前面這部分是相同的,在查詢的時(shí)候就容易造成熱點(diǎn)現(xiàn)象,因此需要使用時(shí)間戳反轉(zhuǎn)的方式來處理。實(shí)際生產(chǎn)中可以用Long.Max_Value - timestamp追加到 key 的末尾,比如 [key][reverse_timestamp], [key]的最新值可以通過scan [key]獲得[key]的第一條記錄,因?yàn)镠Base中RowKey是有序的,所以第一條記錄是最后錄入的數(shù)據(jù)。
常見的場(chǎng)景,比如需要保存一個(gè)用戶的操作記錄,就可以按照操作時(shí)間倒序排序,在設(shè)計(jì)rowkey的時(shí)候,可以這樣設(shè)計(jì)[反轉(zhuǎn)后的userId][Long.Max_Value - timestamp],在查詢用戶的所有操作記錄數(shù)據(jù)的時(shí)候,直接指定反轉(zhuǎn)后的userId,startRow 是[反轉(zhuǎn)后的userId][000000000000],stopRow 是 [反轉(zhuǎn)后的userId][Long.Max_Value - timestamp]。如果需要查詢某段時(shí)間的操作記錄,startRow 是[反轉(zhuǎn)后的userId[Long.Max_Value - 起始時(shí)間], stopRow 是[反轉(zhuǎn)后的userId][Long.Max_Value - 結(jié)束時(shí)間]。
4.2.2、加鹽(Salting)
第二種咱們要介紹的方法是加鹽,玩過密碼學(xué)的可能知道密碼學(xué)里也有加鹽的方法,但是咱們RowKey的加鹽和密碼學(xué)不一樣,它的原理是在原RowKey的前面添加固定長(zhǎng)度的隨機(jī)數(shù),也就是給RowKey分配一個(gè)隨機(jī)前綴使它和之前的RowKey的開頭不同。
適用場(chǎng)景:
比如咱們?cè)O(shè)計(jì)的RowKey是有意義的,但是數(shù)據(jù)類似,隨機(jī)性比較低,反轉(zhuǎn)也沒法保證隨機(jī)性,這樣就沒法根據(jù)RowKey分配到不同的Region里,這時(shí)候就可以使用加鹽的方式了。
需要注意隨機(jī)數(shù)要能保障數(shù)據(jù)在所有Regions間的負(fù)載均衡,也就是說分配的隨機(jī)前綴的種類數(shù)量應(yīng)該和你想把數(shù)據(jù)分散到的那些region的數(shù)量一致。只有這樣,加鹽之后的rowkey才會(huì)根據(jù)隨機(jī)生成的前綴分散到各個(gè)region中,避免了熱點(diǎn)現(xiàn)象。
缺點(diǎn):
大白話來理解就是加了鹽就嘗不到原有的味道了。因?yàn)樘砑拥氖请S機(jī)數(shù),添加后如果還基于原RowKey查詢,就無法知道隨機(jī)數(shù)是什么,那樣在查詢的時(shí)候就需要去各個(gè)可能的Region中查找,同時(shí)加鹽對(duì)于讀取是利空的。并且加鹽這種方式增加了讀寫時(shí)的吞吐量。
4.2.3、哈希(Hashing)
最后介紹大家最熟悉的哈希方法,不管是學(xué)的啥技術(shù),都會(huì)涉及到哈希,也都大同小異,比較簡(jiǎn)單。
這里的哈希是基于RowKey的完整或部分?jǐn)?shù)據(jù)進(jìn)行Hash,而后將哈希后的值完整替換或部分替換原RowKey的前綴部分。這里說的hash常用的有MD5、sha1、sha256 或 sha512 等算法。
適用場(chǎng)景:
其實(shí)哈希和加鹽的適用場(chǎng)景類似,但是由于加鹽方法的前綴是隨機(jī)數(shù),用原rowkey查詢時(shí)不方便,因此出現(xiàn)了哈希方法,由于哈希是使用各種常見的算法來計(jì)算出的前綴,因此哈希既可以使負(fù)載分散到整個(gè)集群,又可以輕松讀取數(shù)據(jù)。
缺點(diǎn):
與反轉(zhuǎn)類似,哈希也打亂了RowKey的自然順序,因此也不利于Scan。
RowKey設(shè)計(jì)原則
通過前面的分析我們應(yīng)該知道了HBase中RowKey設(shè)計(jì)的重要性了,為了幫助我們?cè)O(shè)計(jì)出完美的RowKey,HBase提出了RowKey的設(shè)計(jì)原則,一共有四點(diǎn):長(zhǎng)度原則、唯一原則、排序原則,散列原則。
RowKey在字段的選擇上,需要遵循的最基本原則是唯一原則,因?yàn)镽owKey必須能夠唯一的識(shí)別一行數(shù)據(jù)。無論應(yīng)用的負(fù)載特點(diǎn)是什么樣,RowKey字段都應(yīng)該首先考慮最高頻的查詢場(chǎng)景。數(shù)據(jù)庫通常都是以如何高效的讀取和消費(fèi)數(shù)據(jù)為目的,而不僅僅是數(shù)據(jù)存儲(chǔ)本身。然后再結(jié)合具體的負(fù)載特點(diǎn),再對(duì)選取的RowKey字段值進(jìn)行改造,結(jié)合RowKey的優(yōu)化,也就是避免熱點(diǎn)現(xiàn)象的那些方法來優(yōu)化就可以了。
5.1、長(zhǎng)度原則
RowKey本質(zhì)上是一個(gè)二進(jìn)制碼的流,可以是任意字符串,最大長(zhǎng)度為64kb,實(shí)際應(yīng)用中一般為10-100byte,以byte[]數(shù)組形式保存,一般設(shè)計(jì)成定長(zhǎng)。官方建議越短越好,不要超過16個(gè)字節(jié),原因可以概括為如下幾點(diǎn):
影響HFile的存儲(chǔ)效率:HBase里的數(shù)據(jù)在持久化文件HFile中其實(shí)是按照Key-Value對(duì)形式存儲(chǔ)的。這時(shí)候如果RowKey很長(zhǎng),比如達(dá)到了200byte,那么僅僅1000w行的記錄,只考慮RowKey就需占用近2GB的空間,極大的影響了HFile的存儲(chǔ)效率。
降低檢索效率:由于MemStore會(huì)緩存部分?jǐn)?shù)據(jù)到內(nèi)存中,如果RowKey比較長(zhǎng),就會(huì)導(dǎo)致內(nèi)存的有效利用率降低,也就不能緩存更多的數(shù)據(jù),從而降低檢索效率。
6字節(jié)是64位操作系統(tǒng)的最佳選擇:64位系統(tǒng),內(nèi)存8字節(jié)對(duì)齊,控制在16字節(jié),8字節(jié)的整數(shù)倍利用了操作系統(tǒng)的最佳特性。
5.2、唯一原則
其實(shí)唯一原則咱們可以結(jié)合HashMap的源碼設(shè)計(jì)或者主鍵的概念來理解,由于RowKey用來唯一標(biāo)識(shí)一行記錄,所以必須在設(shè)計(jì)上保證RowKey的唯一性。
需要注意:由于HBase中數(shù)據(jù)存儲(chǔ)的格式是Key-Value對(duì)格式,所以如果向HBase中同一張表插入相同RowKey的數(shù)據(jù),則原先存在的數(shù)據(jù)會(huì)被新的數(shù)據(jù)給覆蓋掉(和HashMap效果相同)。
5.3、排序原則
HBase會(huì)把RowKey按照ASCII進(jìn)行自然有序排序,所以反過來我們?cè)谠O(shè)計(jì)RowKey的時(shí)候可以根據(jù)這個(gè)特點(diǎn)來設(shè)計(jì)完美的RowKey,好好的利用這個(gè)特性就是排序原則。
5.4、散列原則
散列原則用大白話來講就是咱們?cè)O(shè)計(jì)出的RowKey需要能夠均勻的分布到各個(gè)RegionServer上。
比如設(shè)計(jì)RowKey的時(shí)候,當(dāng)Rowkey 是按時(shí)間戳的方式遞增,就不要將時(shí)間放在二進(jìn)制碼的前面,可以將 Rowkey 的高位作為散列字段,由程序循環(huán)生成,可以在低位放時(shí)間字段,這樣就可以提高數(shù)據(jù)均衡分布在每個(gè)Regionserver實(shí)現(xiàn)負(fù)載均衡的幾率。
結(jié)合前面分析的熱點(diǎn)現(xiàn)象的起因,思考:
如果沒有散列字段,首字段只有時(shí)間信息,那就會(huì)出現(xiàn)所有新數(shù)據(jù)都在一個(gè) RegionServer上堆積的熱點(diǎn)現(xiàn)象,這樣在做數(shù)據(jù)檢索的時(shí)候負(fù)載將會(huì)集中在個(gè)別RegionServer上,不分散,就會(huì)降低查詢效率。
HBase里的RowKey是按照字典序存儲(chǔ),因此在設(shè)計(jì)RowKey時(shí),咱們要充分利用這個(gè)排序特點(diǎn),將經(jīng)常一起讀取的數(shù)據(jù)存儲(chǔ)到一塊,將最近可能會(huì)被訪問的數(shù)據(jù)放在一塊。如果最近寫入HBase表中的數(shù)據(jù)是最可能被訪問的,可以考慮將時(shí)間戳作為row key的一部分,由于是字典序排序,所以可以使用Long.MAX_VALUE - timestamp作為row key,這樣能保證新寫入的數(shù)據(jù)在讀取時(shí)可以被快速找到。
總結(jié)
看到這里RowKey的各個(gè)方面應(yīng)該都已經(jīng)搞懂了,本文從RowKey的原理,可能出現(xiàn)的問題,如何優(yōu)化及各個(gè)優(yōu)化措施對(duì)應(yīng)的缺點(diǎn)和適用的場(chǎng)景,設(shè)計(jì)原則等角度對(duì)RowKey進(jìn)行了詳細(xì)全面的解析,相信一定能對(duì)你有所幫助。
如果您對(duì)我的文章感興趣,歡迎關(guān)注點(diǎn)贊收藏,如果您有疑惑或發(fā)現(xiàn)文中有不對(duì)的地方,還請(qǐng)不吝賜教,非常感謝!!
本文為 CSDN 博主「且聽_風(fēng)吟?」原創(chuàng),首發(fā)于 CSDN 博客,轉(zhuǎn)載請(qǐng)經(jīng)授權(quán)。原文鏈接:https://blog.csdn.net/qq_26803795/article/details/105994960
?
推薦閱讀
后端程序員必備:書寫高質(zhì)量SQL的30條建議
螞蟻金服高要求的領(lǐng)域建模能力,對(duì)研發(fā)來說到底指什么?
Redis 6.0 新特性:多線程連環(huán) 13 問!
AI 修復(fù) 100 年前晚清影像喜提熱搜,有穿越內(nèi)味兒了!
你現(xiàn)在從事的程序員還有多久會(huì)消失?牛津大學(xué)研究員幫你算了算
一次對(duì)語音技術(shù)的徹底批判
到底是哪些人在玩鏈游?| 《區(qū)塊鏈游戲玩家研究報(bào)告》
真香,朕在看了!
總結(jié)
以上是生活随笔為你收集整理的用大白话彻底搞懂 HBase RowKey 详细设计的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云+X案例展 | 民生类:云途腾助力城建
- 下一篇: 技术差的程序员,90%都输在这点上!骨灰