天天看點

HBase設計之rowkey設計

新數倉系列:HBase關鍵能力和特性梳理

HBase 和 Cassandra的淺談

新數倉系列:Hbase周邊生态梳理(1)

HBase由于其存儲和讀寫高性能,在實時查詢中越來越發揮重要的作用,但是由于其屬于NOSQL資料庫類型,對于關系型資料并不适用。HBase查詢隻能通過其rowkey來查詢(我們可以認為是HBase中表的唯一索引)。是以rowkey的設計在使用HBase的設計中尤為重要,另外rowkey設計也關乎到資料庫中資料的存放位置,若rowkey設計不當,在HBase分區中,會引發資料熱點(hotspot)問題出現,即資料通路集中在某個節點或者region,最終會導緻性能降低或者region由于負載大而不可用。

為了防止在寫的操作時出現資料熱點,在設計rowkey時應該讓資料盡可能同時寫入多個region,下面介紹幾種常見的rowkey設計方式。

1

1 . Salt

Salting在HBase中的應用是将每一個rowkey字首指定一随機字元,這樣就使得資料在分散在多個不同的region,達到均衡負載。

若HBase中表region按照每個字母字首來區分,我們來對比rowkey 加salt前後的變化,首先我們給一組未salt前的rowkey:

rk001

rk002

rk003

上述rowkey根據分區來看是在同一個region中,下面我們對上述rowkey加salt處理:

a-rk001

b-rk002

c-rk003

經過處理的rowkey,資料分布在3個region中,理論上此時的吞吐量是未處理之前的3倍。由于字首是随機的在讀這些資料時若要按照字典序查找則需要耗費更多的時間(可能對每個region伺服器發起請求),是以salt增加了寫操作的吞吐量,但卻增加了讀操作的開銷。

2

2 .Hash散列

用hash 散列來替代随機指派字首,能使一個給定的行在salt時有相同的字首,從某種程度上說,這在分散了RegionServer間的負載的同時,也允許在讀操作時能夠預測。确定性hash(deterministic hash )能讓用戶端重建完整的rowkey,可以用get操作直接擷取想要的行。

例如将上述的3個rowkey(未salt)經過hash處理,此處我們采用MD5雜湊演算法,結果如下

f18a79a8eb39267173fd0d113e3282f4

277ba32a1610268cdb7733192010c127

bd1258481401ea1be6377c5aaeae3a1f

若以首個字元作為不同分區,上面幾個資料均衡分布在3個region中。下面是我們實際的一個資料在各個分區的分布情況:

HBase設計之rowkey設計

在上圖的16個分區中,資料基本實作均衡分布,當資料量越來越大的時候,分區的這種均衡會更平衡。

上面介紹的兩種rowkey常用的rowkey設計方法。由于在HBase中資料存儲是k-v形式,若在HBase中同一表的同一列插入相同rowkey(除自帶版本),則原先的資料會被覆寫掉,是以為了保證rowkey的唯一性,在實際的設計中我們可能更多的是結合多種設計方法來實作rowkey的最大優化設計,比如MD5+salt。

HBase的資料讀取主要通過rowkey來查詢擷取資料,我們可以借助Hive、Phoenix等通過SQL方式擷取資料,也可以将索引資料存放在Solr、ElestaticSearch中,間接的查詢資料,但是這樣的方式都沒有通過rowkey來直接查詢資料的性能高,同時實時性也不高,是以我們在rowkey設計時我們應該包含更多可用資訊。這裡我們參考了《大資料之路—阿裡巴巴大資料實踐》一書中講到的設計規則

設計規則:MD5+主次元+次元辨別+子次元1+時間次元+子次元2

例如:賣家ID的MD5前四位+賣家ID+app+一級目錄+date+二級目錄

以MD5的前四位作為rowkey的第一部分,可以把資料散列,讓伺服器負載均衡,避免熱點問題。賣家ID是查詢必傳的這樣就縮小了我們scan的範圍,能夠更快的查詢到我們需要的資料。

最後,rowkey的長度也會關乎到我們的性能,由于HBase屬于列式資料庫,若rowkey長度增加一倍那麼整體的存儲量會成倍增加。是以rowkey的設計沒有固定的模式,在實際的實踐中需要我們參考各種因素來實作rowkey的最優化。