您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)Hbase Rowkey如何設(shè)計(jì)的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
1、表的屬性
(1)最大版本數(shù):通常是3,如果對于更新比較頻繁的應(yīng)用完全可以設(shè)置為1,能夠快速的淘汰無用數(shù)據(jù),對于節(jié)省存儲(chǔ)空間和提高查詢速度有效果。不過這類需求在海量數(shù)據(jù)領(lǐng)域比較小眾。
(2)壓縮算法:可以嘗試一下最新出爐的snappy算法,相對lzo來說,壓縮率接近,壓縮效率稍高,解壓效率高很多。
(3)inmemory:表在內(nèi)存中存放,一直會(huì)被忽略的屬性。如果完全將數(shù)據(jù)存放在內(nèi)存中,那么hbase和現(xiàn)在流行的內(nèi)存數(shù)據(jù)庫memorycached和redis性能差距有多少,尚待實(shí)測。
(4)bloomfilter:根據(jù)應(yīng)用來定,看需要精確到rowkey還是column。不過這里需要理解一下原理,bloomfilter的作用是對一個(gè)region下查找記錄所在的hfile有用。即如果一個(gè)region下的hfile數(shù)量很多,bloomfilter的作用越明顯。適合那種compaction趕不上flush速度的應(yīng)用。
2、rowkey
2.1 排序問題
數(shù)字rowkey的從大到小排序:原生hbase只支持從小到大的排序,這樣就對于排行榜一類的查詢需求很尷尬。那么采用rowkey = Integer.MAX_VALUE-rowkey的方式將rowkey進(jìn)行轉(zhuǎn)換,最大的變最小,最小的變最大。在應(yīng)用層再轉(zhuǎn)回來即可完成排序需求。
2.2 熱點(diǎn)問題
HBase中的行是按照rowkey的字典順序排序的,這種設(shè)計(jì)優(yōu)化了scan操作,可以將相關(guān)的行以及會(huì)被一起讀取的行存取在臨近位置,便于scan。然而糟糕的rowkey設(shè)計(jì)是熱點(diǎn)的源頭。 熱點(diǎn)發(fā)生在大量的client直接訪問集群的一個(gè)或極少數(shù)個(gè)節(jié)點(diǎn)(訪問可能是讀,寫或者其他操作)。大量訪問會(huì)使熱點(diǎn)region所在的單個(gè)機(jī)器超出自身承受能力,引起性能下降甚至region不可用,這也會(huì)影響同一個(gè)RegionServer上的其他region,由于主機(jī)無法服務(wù)其他region的請求。 設(shè)計(jì)良好的數(shù)據(jù)訪問模式以使集群被充分,均衡的利用。
為了避免寫熱點(diǎn),設(shè)計(jì)rowkey使得不同行在同一個(gè)region,但是在更多數(shù)據(jù)情況下,數(shù)據(jù)應(yīng)該被寫入集群的多個(gè)region,而不是一個(gè)。
下面是一些常見的避免熱點(diǎn)的方法以及它們的優(yōu)缺點(diǎn):
加鹽
這里所說的加鹽不是密碼學(xué)中的加鹽,而是在rowkey的前面增加隨機(jī)數(shù),具體就是給rowkey分配一個(gè)隨機(jī)前綴以使得它和之前的rowkey的開頭不同。分配的前綴種類數(shù)量應(yīng)該和你想使用數(shù)據(jù)分散到不同的region的數(shù)量一致。加鹽之后的rowkey就會(huì)根據(jù)隨機(jī)生成的前綴分散到各個(gè)region上,以避免熱點(diǎn)。
哈希
哈希會(huì)使同一行永遠(yuǎn)用一個(gè)前綴加鹽。哈希也可以使負(fù)載分散到整個(gè)集群,但是讀卻是可以預(yù)測的。使用確定的哈??梢宰尶蛻舳酥貥?gòu)完整的rowkey,可以使用get操作準(zhǔn)確獲取某一個(gè)行數(shù)據(jù)
反轉(zhuǎn)
第三種防止熱點(diǎn)的方法時(shí)反轉(zhuǎn)固定長度或者數(shù)字格式的rowkey。這樣可以使得rowkey中經(jīng)常改變的部分(最沒有意義的部分)放在前面。這樣可以有效的隨機(jī)rowkey,但是犧牲了rowkey的有序性。
反轉(zhuǎn)rowkey的例子以手機(jī)號為rowkey,可以將手機(jī)號反轉(zhuǎn)后的字符串作為rowkey,這樣的就避免了以手機(jī)號那樣比較固定開頭導(dǎo)致熱點(diǎn)問題
時(shí)間戳反轉(zhuǎn)
一個(gè)常見的數(shù)據(jù)處理問題是快速獲取數(shù)據(jù)的最近版本,使用反轉(zhuǎn)的時(shí)間戳作為rowkey的一部分對這個(gè)問題十分有用,可以用 Long.Max_Value - timestamp 追加到key的末尾,例如 [key][reverse_timestamp] , [key] 的最新值可以通過scan [key]獲得[key]的第一條記錄,因?yàn)镠Base中rowkey是有序的,第一條記錄是最后錄入的數(shù)據(jù)。比如需要保存一個(gè)用戶的操作記錄,按照操作時(shí)間倒序排序,在設(shè)計(jì)rowkey的時(shí)候,可以這樣設(shè)計(jì)[userId反轉(zhuǎn)][Long.Max_Value - timestamp],在查詢用戶的所有操作記錄數(shù)據(jù)的時(shí)候,直接指定反轉(zhuǎn)后的userId,startRow是[userId反轉(zhuǎn)][000000000000],stopRow是[userId反轉(zhuǎn)][Long.Max_Value - timestamp]如果需要查詢某段時(shí)間的操作記錄,startRow是[user反轉(zhuǎn)][Long.Max_Value - 起始時(shí)間],stopRow是[userId反轉(zhuǎn)][Long.Max_Value - 結(jié)束時(shí)間] rowkey是hbase的key-value存儲(chǔ)中的key,通常使用用戶要查詢的字段作為rowkey,查詢結(jié)果作為value??梢酝ㄟ^設(shè)計(jì)滿足幾種不同的查詢需求。
3、columnfamily
columnfamily盡量少,原因是過多的columnfamily之間會(huì)互相影響。
4、column
對于column需要擴(kuò)展的應(yīng)用,column可以按普通的方式設(shè)計(jì),但是對于列相對固定的應(yīng)用,最好采用將一行記錄封裝到一個(gè)column中的方式,這樣能夠節(jié)省存儲(chǔ)空間。封裝的方式推薦protocolbuffer。
以下會(huì)分場景介紹一些特殊的表結(jié)構(gòu)設(shè)計(jì)方法,只是一些摸索,歡迎討論:
value數(shù)目過多場景下的表結(jié)構(gòu)設(shè)計(jì):
目前我碰到了一種key-value的數(shù)據(jù)結(jié)構(gòu),某一個(gè)key下面包含的column很多,以致于客戶端查詢的時(shí)候oom,bulkload寫入的時(shí)候oom,regionsplit的時(shí)候失敗這三種后果。通常來講,hbase的column數(shù)目不要超過百萬這個(gè)數(shù)量級。在官方的說明和我實(shí)際的測試中都驗(yàn)證了這一點(diǎn)。
有兩種思路可以參考,第一種是單獨(dú)處理這些特殊的rowkey,第二種如下:
可以考慮將column設(shè)計(jì)到rowkey的方法解決。例如原來的rowkey是uid1,,column是uid2,uid3...。重新設(shè)計(jì)之后rowkey為<uid1>~<uid2>,<uid1>~<uid3>...當(dāng)然大家會(huì)有疑問,這種方式如何查詢,如果要查詢uid1下面的所有uid怎么辦。這里說明一下hbase并不是只有g(shù)et一種隨機(jī)讀取的方法。而是含有scan(startkey,endkey)的掃描方法,而這種方法和get的效率相當(dāng)。需要取得uid1下的記錄只需要new Scan("uid1~","uid1~~")即可。
感謝各位的閱讀!關(guān)于“Hbase Rowkey如何設(shè)計(jì)”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。