HBase設計之rowkey設計

HBase應用場景非常廣泛;社區前面有一系列文章。大家可以到社區看看看;張少華同學本篇主要講HBASE最重要的一個基礎知識,rowkey的涉及,非常贊!大力推薦!

社區系列文章:

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

HBase 和 Cassandra的淺談

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



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

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

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 .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的最優化。


分享到:


相關文章: