Log表新的RowKey設計,預Split

zping發表於2015-02-27

1 目前Rawlog表的問題

  1. region數量龐大,空region 率大
    • 共有12791個region
    • 11409空region, 比例為89.19%
    • 剩餘的region大小也是極度不均衡,最大的region 287G, <1m的region有129個
  2. 讀寫不均衡
    • 現有的rowkey設計,簡單來說是appid+date的順序序列
    • 簡單來說對於每個appid都有一個寫熱點,這不僅沒有利用到分散式的優點,還會極大的降低整個hbase叢集的服務能力
    • 讀存在同樣的問題,一次讀基本上會集中在一個region上,這對於scan是好的,但目前我們所有的log查詢都是基於mutiget的,還不如分散來的效能好。

2 解決方案

現有的log查詢方案:

  1. 從logindex表獲取log的rowkey
  2. 根據rowkey使用mutiget獲取具體的log

所以不在需要順序的rowkey設計。

  1. 解決region數量龐大的問題
    • 使用預分的region
    • 根據實際資料量,預分出足夠的region, 後續保證儘量少的出現split
  2. 解決空region率,大小不均衡,及讀寫不均衡
    • 這些問題可以一起解決
    • 寫的時候足夠雜湊的(平均)寫到這些region上
    • 理想狀態下各region大小會完全一致
    • 讀寫理想狀態下也會完成一致
    • 可以減少split的次數,理想狀態下不會再出現,同樣減少了該表region的blance出現的次數,理想狀態下不會出現。

現在進行改造的優勢是,我們有生產資料進行支援,金橋是一個全新的叢集,這是一個機會,可以不考慮老資料的遷移(到時福泉與金橋應用並行執行,避免遷移資料)

2.1 預分region的數量

  1. 目前生產rawlog表的大小為2938.5G, 也就是3T,儲存了7天的資料
  2. 考慮到以後的資料增量,以10T為儲存目標,一個region2G, 可以預分5000個region

2.2 如何實現足夠雜湊寫(或對region平均寫)

  1. 理論上可以對region依次寫入一條log, 輪循一遍後,再次從頭輪循,這樣可以達到絕對平均
  2. 實際解決方案, 可以設計一種rowkey結構
hashcode
unique-id
1 ~ 100000 appid + hostip + timestamp + logid
  1. 從通用角度,rowkey 分為兩部分
    1. hashcode: 雜湊值,用於將資料雜湊到各region上
    2. unique-id: 這條資料的一個唯一id, 這個基本上和業務相關
  2. 對於rowlog表
    1. hashcode: 可以是一個1 ~ 100000的int值
    2. unique-id: 可以是一個由appid + hostip + timestamp + logid 組成的唯一id, 也是現有的rowkey設計
  3. 如果預分5000個region, 每個region將佔有20個雜湊值(startKey-endKey):1-20, 21-40, .... 99981-100000

2.3 工作量

  1. 只要修改writer端rowlog的rowkey生成策略
  2. 對於其他地方完全透明
  3. 編碼的話只要兩個小時就足夠了,後續就是支援工作了。
  4. 如何獲取一條log的hashcode, 有幾種方案:
    1. writer每收一條log可以遞增,到達100000,歸1
    2. 也可以每次取1-100000的隨機值,效率最低
    3. 為了去除1-20的連續寫, 可以
      1. 可以分配一個int[100000],裡面存放shuffle後的1-100000的值
      2. 每來一條log從陣列裡取一個值int[i++]
      3. 到達陣列結尾後可以直接從頭再取,或shuffle後再從頭取
      4. 或著一開始就預先shuffle好幾個陣列,待用。

相關文章