ApsaraDB for HBase的Rowkey設計在資料分區和資料查詢中很重要,本節介紹設計Rowkey前需要考慮的一些問題以及設計樣本。
問題考慮
- 問題一:Rowkey是唯一的嗎?
相同的Rowkey在HBase中認為是同一條資料的多個版本,查詢時預設返回最新版本的資料,所以通常Rowkey都需要保證唯一,除非用到多版本特性。
最佳設計樣本:Rowkey相當於資料庫的主鍵。Rowkey表示一條記錄。Rowkey可以是一個欄位也可以是多個欄位接起來。Rowkey為[userid]表示每個使用者只有一條記錄, Rowkey為[userid][orderid]表示每個使用者有多條記錄。
- 問題二:滿足哪種查詢情境?Rowkey的設計限制了資料的查詢方式,HBase有兩種查詢方式。
- 根據完整的Rowkey查詢(get方式),例如
SELECT * FROM table WHERE Rowkey = ‘abcde’
。說明 get方式需要知道完整的Rowkey,即組成Rowkey所有欄位的值都是確定的。 - 根據Rowkey的範圍查詢(scan方式),例如
SELECT * FROM table WHERE ‘abc’ < Rowkey <’abcx’
。說明 scan方式需要知道Rowkey左邊的值,例如您使用英文字典查詢pre開頭的所有單詞,也可以查詢prefi開頭的所有單詞,不能查詢中間或結尾為prefi的單詞。
最佳設計樣本:在有限的查詢方式下如何?複雜查詢?以下方法可以幫您實現。- 再建立一張表作為索引表。
- 使用Filter在服務端過濾不需要的資料。
- 使用二級索引。
- 使用反向scan方法實現倒序(將新資料排在前面),
scan.setReverse(true)
。說明 反向scan的效能比正常scan效能差,如果大部分是倒序情境可以體現在Rowkey設計上,例如[hostname][log-event][timestamp] => [hostname][log-event][Long.MAX_VALUE - timestamp]
。
- 根據完整的Rowkey查詢(get方式),例如
- 問題三:資料足夠分散,會存在堆積的熱點現象嗎?
散列的目的是將資料分散到不同的分區,不至於產生熱點使某一台伺服器終止,其他伺服器空閑,充分發揮分布式和並發的優勢。
最佳設計樣本:- 設計md5散列演算法:
[userId][orderid] => [md5(userid).subStr(0,4)][userId][orderid]
。 - 設計反轉:
[userId][orderid] => [reverse(userid)][orderid]
。 - 設計模數:
[timestamp][hostname][log-event] => [bucket][timestamp][hostname][log-event]; long bucket = timestamp % numBuckets
。 - 增加隨機數:
[userId][orderid] => [userId][orderid][random(100)]
。
- 設計md5散列演算法:
- 問題四:Rowkey可以再短點嗎?
短的Rowkey可以減少資料量,提高資料查詢和資料寫入效率。
最佳設計樣本:- 使用Long或Int代替String,例如
'2015122410' => Long(2015122410)
。 - 使用編碼代替名稱,例如
'淘寶' => tb
。
- 使用Long或Int代替String,例如
- 問題五:使用scan方式會查詢出不需要的資料嗎?
會的。情境舉例:table1的Rowkey為
column1+ column2+ column3
,如果您需要查詢column1= host1
的所有資料,使用scan 'table1',{startkey=> 'host1',endkey=> 'host2'}
語句。如果有一條記錄為column1=host12
,那麼此記錄也會查詢出來。最佳設計樣本:- 設計欄位定長,
[column1][column2] => [rpad(column1,'x',20)][column2]
。 - 添加分隔字元,
[column1][column2] => [column1][_][column2]
。
- 設計欄位定長,
常見設計樣本
- 日誌類、時間序列資料。列舉出以下三個情境設計Rowkey。
- 查詢某台機器某個指標某段時間內的資料,Rowkey設計為
[hostname][log-event][timestamp]
。 - 查詢某台機器某個指標最新的幾條資料,Rowkey設計為
timestamp = Long.MAX_VALUE - timestamp; [hostname][log-event][timestamp]
。 - 查詢的資料存在只有時間一個維度或某一個維度資料量巨大的情況,Rowkey設計為
long bucket = timestamp % numBuckets; [bucket][timestamp][hostname][log-event]
。
- 查詢某台機器某個指標某段時間內的資料,Rowkey設計為
- 交易類資料。列舉出以下四個情境設計Rowkey。
- 查詢某個賣家某段時間內的交易記錄,Rowkey設計為
[seller id][timestamp][order number]
。 - 查詢某個買家某段時間內的交易記錄,Rowkey設計為
[buyer id][timestamp][order number]
。 - 根據訂單號查詢,Rowkey設計為
[order number]
。 - 查詢中同時滿足三張表,一張買家維度資料表Rowkey設計為
[buyer id][timestamp][order number]
。一張賣家維度資料表Rowkey設計為[seller id][timestamp][order number]
。一張訂單索引表Rowkey設計為[order number]
。
- 查詢某個賣家某段時間內的交易記錄,Rowkey設計為