HBase 學習二(最佳實踐).

1、Rowkey 優化

Rowkey 是行的主鍵,它是以字典順序排序的。因此 Rowkey 的設計是相當重要的, 關係到你應用層的查詢效率。數據庫

整規化 Rowkey

有時做爲 Rowkey 的字段長度不同,好比 user_id, 而經過對 Rowkey 進行規整化,可以避免 Rowkey 長度不一致,致使每次請求返回的數據量不一,可將組合的 Rowkey 映射成等長 hash 值。緩存

編碼 Rowkey

若是 Rowkey 是以字符串形式保存,好比日期格式(yyyy-MM-dd HH:mm:ss),會形成大量存儲空間的浪費, 所以能夠對字符串進行數值編碼,將編碼後的數保存到 Rowkey 中。併發

高基維度

若是 Rowkey 由多個字段組成,須要把高基維度放到最前面,也就是 distinct 的字段數量在千萬以上,好比 user_id 放到前面,這樣字段能在過濾中起到很大做用、大幅縮小查詢範圍。負載均衡

加鹽

若是組合 Rowkey 的第一部分是時間戳,HBase又是按照 Rowkey 排序的,極可能鄰近的數據存到一個 HRegionServer 裏,考慮到最新的數據訪問頻率最高,將致使某個 HRegionServer 讀請求負載太重,產生熱點問題,一個可行的方案是 Rowkey 前綴加隨機數,這能夠保證數據均勻分佈,但對數據讀取形成了麻煩。和加鹽相似的方案有對 Rowkey 進行哈希、翻轉Rowkey (常常改變的部分放到前面)等。異步

2、數據熱點問題

數據熱點問題:熱點發生在大量的 client 直接訪問集羣的一個或極少數個節點(訪問多是讀, 寫或者其餘操做)。大量訪問會使熱點 HRegion 所在的單個機器超出自身承受能力,引發性能降低甚至 HRegion 不可用,這也會影響同一個 HRegionServer 上的其餘HRegion,因爲主機沒法服務其餘 HRegion 的請求,形成資源浪費。設計良好的數據訪問模式以使集羣被充分、均衡的利用。分佈式

能夠經過下面方式解決 HRegion 熱點問題:性能

  1. Reverse反轉:針對固定長度的 Rowkey 反轉後存儲,這樣可使 Rowkey 中常常改變的部分放在最前面,能夠有效的隨機 Rowkey。例如手機號比較固定開頭(138、139)的熱點問題。優化

  2. 預分區/Salt加鹽:Salt 是將每個 Rowkey 加一個前綴,前綴使用一些隨機字符,使得數據分散在多個不一樣的 HRegion ,達到 HRegion 負載均衡的目標。好比在一個有 4 個 HRegion (注: 以 [ ,a)、 [a,b)、 [b,c)、 [c, )爲 HRegion 起止) 的 HBase 表中, 加 Salt 前的 Rowkey:abc00一、abc00二、abc003 咱們分別加 a、 b、 c 前綴,加 Salt 後 Rowkey 爲:aabc00一、b-abc00二、c-abc003。能夠看到,加鹽前的 Rowkey 默認會在第2個 HRegion 中, 加鹽後的 Rowkey 數據會分佈在3個 HRegion 中,理論上處理後的吞吐量應是以前的3倍。編碼

  3. Hash 散列或者 Mod:Hash 散列來替代隨機 Salt 前綴的好處是能讓一個給定的行有相同的前綴,這在分散了 HRegion 負載的同時,使讀操做也可以推斷。肯定性Hash(好比 md5 後取前4位作前綴)能讓客戶端重建完整的 RowKey,可使用 get 操做直接 get 想要的行。若是 Rowkey 是數字類型的,也能夠考慮 Mod 方法。設計

3、HBase三維有序

Hfile 是 HBase 中 KeyValue 數據的存儲格式。從 HBase 物理數據模型中能夠看出,HBase 是面向列表(簇)的存儲。每一個 Cell 由 {row key,column(=< family> + < label>),version} 惟一肯定的單元,他們組合在一塊兒就是一個 KeyValue。 根據上述描述,這個 KeyValue 中的 key 就是 {row key,column(=< family> + < label>),version} ,而 value 就是 cell 中的值。

HBase 的三維有序存儲中的三維是指:rowkey( 行主鍵),column key(columnFamily+< label>), timestamp(時間戳或者版本號) 三部分組成的三維有序存儲。

Rowkey:咱們在根據 rowkey 範圍查詢的時候,咱們通常是知道 startRowkey,若是咱們經過 scan 只傳 startRowKey:d開頭的,那麼查詢的是全部比 d 大的都查了,而咱們只須要 d 開頭的數據,那就要經過 endRowKey 來限制。咱們能夠經過設定 endRowKey 爲: d 開頭,後面的根據你的 rowkey 組合來設定,通常是加比 startKey 大一位。

column key:column key 是第二維,數據按 rowkey 字典排序後,若是 rowkey 相同,則是根據 column key 來排序的,也是按字典排序。咱們在設計 table 的時候要學會利用這一點。好比咱們的收件箱,有時候須要按主題排序,那咱們就能夠把主題設置爲咱們的 column key,即設計爲「columnFamily+主題」這樣的設計。

timestamp:時間戳,是第三維,這是個按降序排序的,即最新的數據排在最前面。

4、寫入優化

  • put 是否能夠批量提交:使用批量 put 接口能夠減小客戶端到 HRegionServer 之間的 RPC 鏈接數,提升寫入性能。
  • put 是否能夠異步提交:業務若是能夠接受異常狀況下少許數據丟失的話,還可使用異步批量提交的方式提交請求。提交分爲兩階段執行:用戶提交寫請求以後,數據會寫入客戶端緩存,並返回用戶寫入成功;當客戶端緩存達到閾值(默認2M)以後批量提交 HRegionServer。須要注意的是,在某些狀況下客戶端異常的狀況下緩存數據有可能丟失。
  • 寫入請求是否不均衡:若是不均衡,一方面會致使系統併發度較低,另外一方面也有可能形成部分節點負載很高,進而影響其餘業務。分佈式系統中特別懼怕一個節點負載很高的狀況,一個節點負載很高可能會拖慢整個集羣,這是由於不少業務會使用批量提交讀寫請求,一旦其中一部分請求落到該節點沒法獲得及時響應,就會致使整個批量請求超時。
  • 寫入 KeyValue 數據是否太大:KeyValue 大小對寫入性能的影響巨大,一旦遇到寫入性能比較差的狀況,能夠考慮是否因爲寫入 KeyValue 數據太大致使。

5、查詢優化

  • Get 是否能夠批量請求:能夠減小客戶端到 HRegionServer 之間的 RPC 鏈接數,提升查詢性能。
  • 大 scan 緩存是否設置合理:scan 一次須要從服務端返回大量的數據,客戶端發起一次請求,服務端會分多批次返回客戶端,這樣的設計是避免一次性傳輸較多的數據給服務端及客戶端產生較大的壓力。目前數據會加載到本地的緩存中,默認100條數據大小。一些大 scan 須要獲取大量的數據,傳輸數百次甚至數萬的 rpc 請求。這種狀況咱們建議能夠適當放開緩存的大小。
  • 請求指定列簇或者列名:HBase 是列簇數據庫,同一個列簇的數據存儲在一塊,不一樣列簇是分開的,爲了減少 IO,建議指定列簇或者列名。
  • 離線計算訪問 HBase 建議禁止緩存:當離線訪問 HBase 時,每每就是一次性的讀取,此時讀取的數據沒有必要存放在 blockcache 中,建議在讀取時禁止緩存。
相關文章
相關標籤/搜索