HBASE中column family的設(shè)計(jì),rowkey的設(shè)計(jì),以及row key的設(shè)計(jì)原則問題

HBASE中column family的設(shè)計(jì),rowkey的設(shè)計(jì),以及row key的設(shè)計(jì)原則問題
原創(chuàng)道法—自然 最后發(fā)布于2018-09-07 23:57:28 閱讀數(shù) 2136 收藏
展開
一、Hbase中的每條記錄的結(jié)構(gòu)

Hbase的表組成:一個(gè)表可以理解成是行的集合,行(記錄)是列族的集合,列族是列的集合。

(1) 列族column family:它是column的集合,在創(chuàng)建表的時(shí)候就指定,不能頻繁修改。值得注意的是,列族的數(shù)量越少越好,因?yàn)檫^多的列族相互之間會影響,生產(chǎn)環(huán)境中的列族一般是一個(gè)到兩個(gè)。

數(shù)據(jù)的持久化文件HFile中是按照Key-Value存儲的,同一個(gè)列族的所有列存儲在同一個(gè)底層存儲文件里。Hbase的數(shù)據(jù)在HDFS中的路徑結(jié)構(gòu)如下:

hdfs://h201:8020/hbase/data/{名字空間}/{表名}/{區(qū)域名稱}/{列族名稱}/${文件名}

舉例:/hbase/data/ns1/t1/a4d63a61a8da24a863bff3c8d7cd20de/f1/c2a7fa8c41304b9e9b8b24b4a89171ce

其中{區(qū)域名稱}是t1的region, 由每張表切割形成,一張表由若干個(gè)region組成,不同的region分到不同的region server以便均衡負(fù)載

(2) 列column:和列族的限制數(shù)量不同,列族可以包含很多個(gè)列,前面說的“幾十億行*百萬列”就是這個(gè)意思。

(3) 列的值value:存在單元格(cell)中。每一列的值允許有多個(gè)版本,由timestamp來區(qū)分不同版本。多個(gè)版本產(chǎn)生原因:向同一行下面的同一個(gè)列多次插入數(shù)據(jù),每插入一次就有一個(gè)對應(yīng)版本的value。

從以下示例中可以看出habse存儲的數(shù)據(jù)格式

hbase(main):010:0>scan 'ns1:t1',{STARTROW => 'row1', LIMIT => 5}

ROW                           COLUMN+CELL                                                                                                                        

row10                         column=f1:age,timestamp=1490608685532,value=\x00\x00\x00\x0A

row10                         column=f1:id,timestamp=1490608685532,value=\x00\x00\x00\x0A

row10                         column=f1:name,timestamp=1490608685532,value=tonykidkid10

row100                        column=f1:age,timestamp=1490608685532,value=\x00\x00\x00\x00

row100                        column=f1:id,timestamp=1490608685532,value=\x00\x00\x00d

row100                        column=f1:name,timestamp=1490608685532,value=tonykidkid100

row1000                       column=f1:age,timestamp=1490608685532,value=\x00\x00\x00\x00

row1000                       column=f1:id,timestamp=1490608685532,value=\x00\x00\x03\xE8

row1000                       column=f1:name,timestamp=1490608685532,value=tonykidkid1000 

row1001                       column=f1:age,timestamp=1490608685532,value=\x00\x00\x00\x01

row1001                       column=f1:id,timestamp=1490608685532,value=\x00\x00\x03\xE9

row1001                       column=f1:name,timestamp=1490608685532,value=tonykidkid1001 

row1002                       column=f1:age,timestamp=1490608685532,value=\x00\x00\x00\x02

row1002                       column=f1:id,timestamp=1490608685532,value=\x00\x00\x03\xEA

row1002                       column=f1:name,timestamp=1490608685532,value=tonykidkid1002

5 row(s) in0.0550 seconds

以row1002這一條記錄來說明——

     row1002是row key .row key在hbase里是唯一的,而且只出現(xiàn)一次,否則就是在更新同一行。也就是說有幾個(gè)不同的row key就有幾條不同的記錄。我們可以通過不同的行健來增加多行記錄。行健的唯一性這個(gè)特性類似于關(guān)系型數(shù)據(jù)庫的主鍵。
column=f1:name, timestamp=1490608685532,value=tonykidkid1002表示列族f1包含name列,“列族+列名”決定了不同的列。

Timestamp是時(shí)間戳,表示此列對應(yīng)值的版本, 默認(rèn)VERSIONS=1,value就是列族f1下name的值了。

需要明確的一點(diǎn),hbase是通過3個(gè)維度來對記錄進(jìn)行快速定位:行健 + (列族+列名) + 時(shí)間戳,即:

                   row key àcolumn family + qualifier à timestamp

結(jié)合上面的例子,t1表的每一行有3個(gè)column, 分別是age,id, name. 比如我想查rowkey為row1002的name的值,命令行下的查詢語法:

hbase(main):021:0>get 'ns1:t1', 'row1002' ,'f1:name'

COLUMN                 CELL                                                          

 f1:name               timestamp=1490608685532,value=tonykidkid1002                 

1 row(s) in0.0420 seconds

         或者這樣查也是對的:

hbase(main):022:0>get 'ns1:t1', 'row1002' , {COLUMN => 'f1:name'}

COLUMN                 CELL                                                           

 f1:name               timestamp=1490608685532,value=tonykidkid1002                 

1 row(s) in0.0300 seconds

二、Hbase中的行健Row Key

我們知道HBase是采用Key-Value格式來存儲數(shù)據(jù),那么Row key就是Key-Value中的Key了,key不能重復(fù),所以表示唯一一行。

Rowkey是表記錄在hbase表中的唯一標(biāo)識,作為檢索表記錄的唯一“主鍵”。hbase加載數(shù)據(jù)時(shí),也是根據(jù)row key的二進(jìn)制順序由小到大進(jìn)行的。

Row key的最大長度為64KB,它是一段二進(jìn)制碼流(byte[ ]),所以任何數(shù)據(jù)類型都可以用來做row key,內(nèi)容可以由我們用戶自定義、自設(shè)計(jì)。

HBase根據(jù)Row key來進(jìn)行檢索,系統(tǒng)通過找到某個(gè)Row key (或者某個(gè) Row key 范圍)所在的Region,然后將查詢數(shù)據(jù)的請求路由到該Region獲取此條記錄。HBase的檢索有3種方式:

1,通過get方式,指定rowkey獲取唯一一條記錄

2,通過scan方式,設(shè)置起始行和結(jié)束行參數(shù)進(jìn)行范圍匹配

3,全表掃描,即直接掃描整張表中所有行記錄

Hbase對記錄的排序row key可以是任意的字節(jié)數(shù)組byte []

row key按照字典順序排序的規(guī)則:在字典順序中按照二進(jìn)制逐個(gè)字節(jié)、從左到右對比每一個(gè)row key,例如row1001小于row1002,rowxxa小于rowxxb等等。這種設(shè)計(jì)優(yōu)化了scan,可以將相關(guān)的行以及會被一起讀取的行存在相近位置,便于scan。

三、Hbase中的 “熱點(diǎn)”問題

hbase中的熱點(diǎn)現(xiàn)象:

我們知道,檢索habse的記錄首先要通過row key來定位數(shù)據(jù)行。當(dāng)大量的client訪問hbase集群的一個(gè)或少數(shù)幾個(gè)節(jié)點(diǎn),造成少數(shù)region server的讀/寫請求過多、負(fù)載過大,而其他region server負(fù)載卻很小,就造成了“熱點(diǎn)”現(xiàn)象。

熱點(diǎn)的危害:

大量訪問會使熱點(diǎn)region所在的單個(gè)主機(jī)負(fù)載過大,引起性能下降甚至region不可用。

熱點(diǎn)產(chǎn)生原因:

有大量連續(xù)編號的row key ==> 大量row key相近的記錄集中在個(gè)別region
==> client檢索記錄時(shí),對個(gè)別region訪問過多 ==> 此region所在的主機(jī)過載
==> 熱點(diǎn)

明白了熱點(diǎn)原因就可以從row key著手解決,下面幾個(gè)方法可以使用,目的就一個(gè):盡量均衡地把每一條記錄分散到不同的region里去!

下面是一些常見的避免熱點(diǎn)的方法以及它們的優(yōu)缺點(diǎn):

加鹽

這里所說的加鹽不是密碼學(xué)中的加鹽,而是在rowkey的前面增加隨機(jī)數(shù),具體就是給rowkey分配一個(gè)隨機(jī)前綴以使得它和之前的rowkey的開頭不同。給多少個(gè)前綴?這個(gè)數(shù)量應(yīng)該和我們想要分散數(shù)據(jù)到不同的region的數(shù)量一致(類似hive里面的分桶)。加鹽之后的rowkey就會根據(jù)隨機(jī)生成的前綴分散到各個(gè)region上,以避免熱點(diǎn)。

哈希

哈希會使同一行永遠(yuǎn)用一個(gè)前綴加鹽。哈希也可以使負(fù)載分散到整個(gè)集群,但是讀卻是可以預(yù)測的。使用確定的哈希可以讓客戶端重構(gòu)完整的rowkey,可以使用get操作準(zhǔn)確獲取某一個(gè)行數(shù)據(jù)。

反轉(zhuǎn)

第三種防止熱點(diǎn)的方法是反轉(zhuǎn)固定長度或者數(shù)字格式的rowkey。這樣可以使得rowkey中經(jīng)常改變的部分(最沒有意義的部分)放在前面。這樣可以有效的隨機(jī)rowkey,但是犧牲了rowkey的有序性。

反轉(zhuǎn)rowkey的例子:以手機(jī)號為rowkey,可以將手機(jī)號反轉(zhuǎn)后的字符串作為rowkey,從而避免諸如139、158之類的固定號碼開頭導(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ù)。

盡量減少行和列的大小

在HBase中,value永遠(yuǎn)和它的key一起傳輸?shù)摹.?dāng)具體的值在系統(tǒng)間傳輸時(shí),它的rowkey,列名,時(shí)間戳也會一起傳輸。如果你的rowkey和列名很大,HBase storefiles中的索引(有助于隨機(jī)訪問)會占據(jù)HBase分配的大量內(nèi)存,因?yàn)榫唧w的值和它的key很大??梢栽黾觔lock大小使得storefiles索引再更大的時(shí)間間隔增加,或者修改表的模式以減小rowkey和列名的大小。壓縮也有助于更大的索引。

其他辦法

列族名的長度盡可能小,最好是只有一個(gè)字符。冗長的屬性名雖然可讀性好,但是更短的屬性名存儲在HBase中會更好。也可以在建表時(shí)預(yù)估數(shù)據(jù)規(guī)模,預(yù)留region數(shù)量,例如create 'myspace:mytable’, SPLITS => [01,02,03,,...99]

總結(jié)一下,row key的設(shè)計(jì)原則應(yīng)當(dāng)遵循以下幾點(diǎn)

(1)rowkey唯一原則

必須在設(shè)計(jì)上保證其唯一性,rowkey是按照二進(jìn)制字節(jié)數(shù)組排序存儲的,因此,設(shè)計(jì)rowkey的時(shí)候,要充分利用這個(gè)排序的特點(diǎn),將經(jīng)常讀取的數(shù)據(jù)存儲到一塊,將最近可能會被訪問的數(shù)據(jù)放到一塊。所以設(shè)計(jì)rwo key時(shí)盡量把體現(xiàn)業(yè)務(wù)特征的信息、業(yè)務(wù)上有唯一性的信息編進(jìn)row key。

(2)rowkey長度原則

rowkey是一個(gè)二進(jìn)制碼流,可以是任意字符串,最大長度 64kb ,實(shí)際應(yīng)用中一般為10-100byte,以byte[] 形式保存,一般設(shè)計(jì)成定長。建議越短越好,不要超過16個(gè)字節(jié),2個(gè)原因——

原因1:

數(shù)據(jù)的持久化文件HFile中是按照(Key,Value)存儲的,如果rowkey過長,例如超過100byte,那么1000萬行的記錄計(jì)算,僅row key就需占用100*1000萬=10億byte,近1Gb。這樣會極大影響HFile的存儲效率!

原因2:

MemStore將緩存部分?jǐn)?shù)據(jù)到內(nèi)存,若 rowkey字段過長,內(nèi)存的有效利用率就會降低,就不能緩存更多的數(shù)據(jù),從而降低檢索效率。
目前操作系統(tǒng)都是64位系統(tǒng),內(nèi)存8字節(jié)對齊,控制在16個(gè)字節(jié),8字節(jié)的整數(shù)倍利用了操作系統(tǒng)的最佳特性。

(3)rowkey散列原則

如果rowkey按照時(shí)間戳的方式遞增,不要將時(shí)間放在二進(jìn)制碼的前面,建議將rowkey的高位作為散列字段,由程序隨機(jī)生成,低位放時(shí)間字段,這樣將提高數(shù)據(jù)均衡分布在每個(gè)RegionServer,以實(shí)現(xiàn)負(fù)載均衡的幾率。如果沒有散列字段,首字段直接是時(shí)間信息,所有的數(shù)據(jù)都會集中在一個(gè)RegionServer上,這樣在數(shù)據(jù)檢索的時(shí)候負(fù)載會集中在個(gè)別的RegionServer上,造成熱點(diǎn)問題,會降低查詢效率。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • [TOC] 一、RowKey 的作用 HBase 由于其存儲和讀寫的高性能,在 OLAP 即時(shí)分析中越來越發(fā)揮重要...
    w1992wishes閱讀 2,376評論 1 1
  • 一、Region 概念 Region是表獲取和分布的基本元素,由每個(gè)列族的一個(gè)Store組成。對象層級圖如下: T...
    達(dá)微閱讀 1,585評論 0 1
  • 1. Hbase基本概念 一. 為什么要用hbase 相比于HDFS HDFS適合批處理場景, 但不支持?jǐn)?shù)據(jù)的隨機(jī)...
    lj72808up閱讀 595評論 0 0
  • 一、簡介 Hbase:全名Hadoop DataBase,是一種開源的,可伸縮的,嚴(yán)格一致性(并非最終一致性)的分...
    菜鳥小玄閱讀 2,592評論 0 12
  • 《海上鋼琴師》——是一部向傳統(tǒng)致敬的影片。故事發(fā)生在1900,20世紀(jì)是一個(gè)大踏步前進(jìn)的時(shí)代,工業(yè)化、機(jī)械化、現(xiàn)代...
    子揚(yáng)哦閱讀 395評論 0 0

友情鏈接更多精彩內(nèi)容