Hbase rowKey 最佳實踐 和 mysql id 對比

個人渣記錄僅為自己搜尋用發表於2017-09-18

http://geek.csdn.net/news/detail/202994

先說下為什麼 rowKey 那麼重要.

mysql:    innodb , 最好要有自增 id ,這樣確儲存儲的時候疊加,而不是節點分裂.

             分表最好是 hash, 而且 id 還是自增.

             不採用 按id (日期) 進行歸檔的方式. 自增歸檔比較麻煩.

hbase: 

             1.由於採用 split 的方式, 範圍 region split 分裂的方式.

              2. 採用 lsm log struct merge 的方式,記憶體中亂序合併. 不介意 rowKey 亂序.

           故 hase 正常情況下反而希望 rowKey 非自增,而且是亂序的.

            6個拆分策略 ,都是和範圍相關的. 可以預分配.

如 nosql 的前世今生中所說,

附: rowKey 設計實踐

HBase在滴滴出行的應用場景和最佳實踐


HBase在滴滴主要存放了以下四種資料型別:

  1. 統計結果、報表類資料:主要是運營、運力情況、收入等結果,通常需要配合Phoenix進行SQL查詢。資料量較小,對查詢的靈活性要求高,延遲要求一般。
  2. 原始事實類資料:如訂單、司機乘客的GPS軌跡、日誌等,主要用作線上和離線的資料供給。資料量大,對一致性和可用性要求高,延遲敏感,實時寫入,單點或批量查詢。
  3. 中間結果資料:指模型訓練所需要的資料等。資料量大,可用性和一致性要求一般,對批量查詢時的吞吐量要求高。
  4. 線上系統的備份資料:使用者把原始資料存在了其他關聯式資料庫或檔案服務,把HBase作為一個異地容災的方案。

使用場景介紹

場景一:訂單事件

這份資料使用過滴滴產品的使用者應該都接觸過,就是App上的歷史訂單。近期訂單的查詢會落在Redis,超過一定時間範圍,或者當Redis不可用時,查詢會落在HBase上。業務方的需求如下:

  1. 線上查詢訂單生命週期的各個狀態,包括status、event_type、order_detail等資訊。主要的查詢來自於客服系統。
  2. 線上歷史訂單詳情查詢。上層會有Redis來儲存近期的訂單,當Redis不可用或者查詢範圍超出Redis,查詢會直接落到HBase。
  3. 離線對訂單的狀態進行分析。
  4. 寫入滿足每秒10K的事件,讀取滿足每秒1K的事件,資料要求在5s內可用。
圖1  訂單流資料流程
圖1 訂單流資料流程

按照這些要求,我們對Rowkey做出了下面的設計,都是很典型的scan場景。

訂單狀態表

Rowkey:reverse(order_id) + (MAX_LONG - TS) 
Columns:該訂單各種狀態

phil 注: reverse的好處是讓 Rowkey 不在自增.


訂單歷史表

Rowkey:reverse(passenger_id | driver_id) + (MAX_LONG - TS)
Columns:使用者在時間範圍內的訂單及其他資訊

場景二:司機乘客軌跡

這也是一份滴滴使用者關係密切的資料,線上使用者、滴滴的各個業務線和分析人員都會使用。舉幾個使用場景上的例子:使用者檢視歷史訂單時,地圖上顯示所經過的路線;發生司乘糾紛,客服呼叫訂單軌跡復現場景;地圖部門使用者分析道路擁堵情況。

圖2  司乘軌跡資料流程
圖2 司乘軌跡資料流程

使用者們提出的需求:

  1. 滿足App使用者或者後端分析人員的實時或準實時軌跡座標查詢;
  2. 滿足離線大規模的軌跡分析;
  3. 滿足給出一個指定的地理範圍,取出範圍內所有使用者的軌跡或範圍內出現過的使用者。

其中,關於第三個需求,地理位置查詢,我們知道MongoDB對於這種地理索引有源生的支援,但是在滴滴這種量級的情況下可能會發生儲存瓶頸,HBase儲存和擴充套件性上沒有壓力但是沒有內建類似MongoDB地理位置索引的功能,沒有就需要我們自己實現。通過調研,瞭解到關於地理索引有一套比較通用的GeohHash演算法 。

GeoHash是將二維的經緯度轉換成字串,每一個字串代表了某一矩形區域。也就是說,這個矩形區域內所有的點(經緯度座標)都共享相同的GeoHash字串,比如說我在悠唐酒店,我的一個朋友在旁邊的悠唐購物廣場,我們的經緯度點會得到相同的GeoHash串。這樣既可以保護隱私(只表示大概區域位置而不是具體的點),又比較容易做快取。

圖3  GeoHash示意圖
圖3 GeoHash示意圖

但是我們要查詢的範圍和GeohHash塊可能不會完全重合。以圓形為例,查詢時會出現如圖4所示的一半在GeoHash塊內,一半在外面的情況(如A、B、C、D、E、F、G等點)。這種情況就需要對GeoHash塊內每個真實的GPS點進行第二次的過濾,通過原始的GPS點和圓心之間的距離,過濾掉不符合查詢條件的資料。

圖4   範圍查詢時,邊界GeoHash塊示意圖
圖4 範圍查詢時,邊界GeoHash塊示意圖

最後依據這個原理,把GeoHash和其他一些需要被索引的維度拼裝成Rowkey,真實的GPS點為Value,在這個基礎上封裝成客戶端,並且在客戶端內部對查詢邏輯和查詢策略做出速度上的大幅優化,這樣就把HBase變成了一個MongoDB一樣支援地理位置索引的資料庫。如果查詢範圍非常大(比如進行省級別的分析),還額外提供了MR的獲取資料的入口。

兩種查詢場景的Rowkey設計如下:

  1. 單個使用者按訂單或時間段查詢: reverse(user_id) + (Integer.MAX_LONG-TS/1000)
  2. 給定範圍內的軌跡查詢:reverse(geohash) + ts/1000 + user_id

場景三:ETA

ETA是指每次選好起始和目的地後,提示出的預估時間和價格。提示的預估到達時間和價格,最初版本是離線方式執行,後來改版通過HBase實現實時效果,把HBase當成一個KeyValue快取,帶來了減少訓練時間、可多城市並行、減少人工干預的好處。
整個E他的過程如下:

  1. 模型訓練通過Spark Job,每30分鐘對各個城市訓練一次;
  2. 模型訓練第一階段,在5分鐘內,按照設定條件從HBase讀取所有城市資料;
  3. 模型訓練第二階段在25分鐘內完成E他的計算;
  4. HBase中的資料每隔一段時間會持久化至HDFS中,供新模型測試和新的特徵提取。

Rowkey:salting+cited+type0+type1+type2+TS
Column:order, feature

圖5  ETA資料流程
圖5 ETA資料流程
 
圖9 DCM,MR Job執行結果統計


附錄: row 設計不合理導致線上問題的調優

調優

首先根據目前17臺機器,50000+的QPS,並且觀察磁碟的I/O利用率和CPU利用率都相當低來判斷:當前的請求數量根本沒有達到系統的效能瓶頸,不需要新增機器來提高效能。如果不是硬體資源問題,那麼效能的瓶頸究竟是什麼?

Rowkey設計問題

現象

開啟HBase的Web端,發現HBase下面各個RegionServer的請求數量非常不均勻,第一個想到的就是HBase的熱點問題,具體到某個具體表上的請求分佈如下:

HBase優化實戰

HBase表請求分佈

上面是HBase下某張表的region請求分佈情況,從中我們明顯可以看到,部分region的請求數量為0,而部分的請求數量可以上百萬,這是一個典型的熱點問題。

原因

HBase出現熱點問題的主要原因無非就是rowkey設計的合理性,像上面這種問題,如果rowkey設計得不好,很容易出現,比如:用時間戳 生成rowkey,由於時間戳在一段時間內都是連續的,導致在不同的時間段,訪問都集中在幾個RegionServer上,從而造成熱點問題。

解決

知道了問題的原因,對症下藥即可,聯絡應用修改rowkey規則,使rowkey資料隨機均勻分佈,效果如下:

HBase優化實戰

Rowkey重定義後請求分佈

建議

對於HBase來說,rowkey的範圍劃定了RegionServer,每一段rowkey區間對應一個RegionServer,我們要保證每段時間內的rowkey訪問都是均勻的,所以我們在設計的時候,儘量要以hash或者md5等開頭來組織rowkey。

Region重分佈

現象

HBase的叢集是在不斷擴充套件的,分散式系統的最大好處除了效能外,不停服橫向擴充套件也是其中之一,擴充套件過程中有一個問題:每次擴充套件的機器的配置是 不一樣的,一般,後面新加入的機器效能會比老的機器好,但是後面加入的機器經常被分配很少的region,這樣就造成了資源分佈不均勻,隨之而來的就是性 能上的損失,如下:

HBase優化實戰

HBase各個RegionServer請求

上圖中我們可以看到,每臺RegionServer上的請求極為不均勻,多的好幾千,少的只有幾十

原因

資源分配不均勻,造成部分機器壓力較大,部分機器負載較低,並且部分Region過大過熱,導致請求相對較集中。

解決

遷移部分老的RegionServer上的region到新加入的機器上,使每個RegionServer的負載均勻。通過split切分部分較大region,均勻分佈熱點region到各個RegionServer上。

HBase優化實戰

HBase region請求分佈

對比前後兩張截圖我們可以看到,Region總數量從1336增加到了1426,而增加的這90個region就是通過split切分大的region得到的。而對region重新分佈後,整個HBase的效能有了大幅度提高。

建議

Region遷移的時候不能簡單開啟自動balance,因為balance主要的問題是不會根據表來進行balance,HBase的自動 balance只會根據每個RegionServer上的Region數量來進行balance,所以自動balance可能會造成同張表的region 會被集中遷移到同一個臺RegionServer上,這樣就達不到分散式的效果。

基本上,新增RegionServer後的region調整,可以手工進行,儘量使表的Region都平均分配到各個RegionServer上,另外一點,新增的RegionServer機器,配置最好與前面的一致,否則資源無法更好利用。

對於過大,過熱的region,可以通過切分的方法生成多個小region後均勻分佈(注意:region切分會觸發major compact操作,會帶來較大的I/O請求,請務必在業務低峰期進行)


HBase Rowkey的雜湊與預分割槽設計



相關文章