全部產品
Search
文件中心

ApsaraDB for HBase:如何設計Rowkey

更新時間:Jul 06, 2024

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]
  • 問題三:資料足夠分散,會存在堆積的熱點現象嗎?

    散列的目的是將資料分散到不同的分區,不至於產生熱點使某一台伺服器終止,其他伺服器空閑,充分發揮分布式和並發的優勢。

    最佳設計樣本:
    • 設計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)]
  • 問題四:Rowkey可以再短點嗎?

    短的Rowkey可以減少資料量,提高資料查詢和資料寫入效率。

    最佳設計樣本:
    • 使用Long或Int代替String,例如'2015122410' => Long(2015122410)
    • 使用編碼代替名稱,例如'淘寶' => tb
  • 問題五:使用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設計為[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]