HBase 性能優化筆記

1 hbase.hregion.max.filesize應該設置多少合適html

2 autoflush=false的影響數據庫

3 從性能的角度談table中family和qualifier的設置緩存

4 hbase.regionserver.handler.count詳解網絡

1 hbase.hregion.max.filesize應該設置多少合適
默認值:256M
說明:Maximum HStoreFile size. If any one of a column families' HStoreFiles has grown to exceed this value, the hosting HRegion is split in two.性能

HStoreFile的最大值。若是任何一個Column Family(或者說HStore)的HStoreFiles的大小超過這個值,那麼,其所屬的HRegion就會Split成兩個。測試

調優this

hbase中hfile的默認最大值(hbase.hregion.max.filesize)是256MB,而google的bigtable論文中對tablet的最大值也推薦爲100-200MB,這個大小有什麼祕密呢?
  衆所周知hbase中數據一開始會寫入memstore,當memstore滿64MB之後,會flush到disk上而成爲storefile。當storefile數量超過3時,會啓動compaction過程將它們合併爲一個storefile。這個過程當中會刪除一些timestamp過時的數據,好比update的數據。而當合並後的storefile大小大於hfile默認最大值時,會觸發split動做,將它切分紅兩個region。
  lz進行了持續insert壓力測試,並設置了不一樣的hbase.hregion.max.filesize,根據結果獲得以下結論:值越小,平均吞吐量越大,但吞吐量越不穩定;值越大,平均吞吐量越小,吞吐量不穩定的時間相對更小。google

  爲何會這樣呢?推論以下:線程

    a 當hbase.hregion.max.filesize比較小時,觸發split的機率更大,而split的時候會將region offline,所以在split結束的時間前,訪問該region的請求將被block住,客戶端自我block的時間默認爲1s。當大量的region同時發生split時,系統的總體訪問服務將大受影響。所以容易出現吞吐量及響應時間的不穩定現象
    b 當hbase.hregion.max.filesize比較大時,單個region中觸發split的機率較小,大量region同時觸發split的機率也較小,所以吞吐量較之小hfile尺寸更加穩定些。可是因爲長期得不到split,所以同一個region內發生屢次compaction的機會增長了。compaction的原理是將原有數據讀一遍並重寫一遍到hdfs上,而後再刪除原有數據。無疑這種行爲會下降以io爲瓶頸的系統的速度,所以平均吞吐量會受到一些影響而降低。
    綜合以上兩種狀況,hbase.hregion.max.filesize不宜過大或太小,256MB或許是一個更理想的經驗參數。對於離線型的應用,調整爲128MB會更加合適一些,而在線應用除非對split機制進行改造,不然不該該低於256MBserver

2 autoflush=false的影響

  不管是官方仍是不少blog都提倡爲了提升hbase的寫入速度而在應用代碼中設置autoflush=false,而後lz認爲在在線應用中應該謹慎進行該設置。緣由以下:

  a autoflush=false的原理是當客戶端提交delete或put請求時,將該請求在客戶端緩存,直到數據超過2M(hbase.client.write.buffer決定)或用戶執行了hbase.flushcommits()時才向regionserver提交請求。所以即便htable.put()執行返回成功,也並不是說明請求真的成功了。假如還沒有達到該緩存而client崩潰,該部分數據將因爲未發送到regionserver而丟失。這對於零容忍的在線服務是不可接受的。

  b autoflush=true雖然會讓寫入速度降低2-3倍,可是對於不少在線應用來講這都是必須打開的,也正是hbase爲何讓它默認值爲true的緣由。當該值爲true時,每次請求都會發往regionserver,而regionserver接收到請求後第一件事就是寫hlog,所以對io的要求是很是高的,爲了提升hbase的寫入速度,應該儘量高地提升io吞吐量,好比增長磁盤、使用raid卡、減小replication因子數等

3 從性能的角度談table中family和qualifier的設置
  對於傳統關係型數據庫中的一張table,在業務轉換到hbase上建模時,從性能的角度應該如何設置family和qualifier呢?
  最極端的,①每一列都設置成一個family,②一個表僅有一個family,全部列都是其中的一個qualifier,那麼有什麼區別呢?

  從讀的方面考慮:
  family越多,那麼獲取每個cell數據的優點越明顯,由於io和網絡都減小了。

  若是隻有一個family,那麼每一次讀都會讀取當前rowkey的全部數據,網絡和io上會有一些損失。

  固然若是要獲取的是固定的幾列數據,那麼把這幾列寫到一個family中比分別設置family要更好,由於只需一次請求就能拿回全部數據。

  從寫的角度考慮:

  首先,內存方面來講,對於一個Region,會爲每個表的每個Family分配一個Store,而每個Store,都會分配一個MemStore,因此更多的family會消耗更多的內存。
  其次,從flush和compaction方面說,目前版本的hbase,在flush和compaction都是以region爲單位的,也就是說當一個family達到flush條件時,該region的全部family所屬的memstore都會flush一次,即便memstore中只有不多的數據也會觸發flush而生成小文件。這樣就增長了compaction發生的機率而compaction也是以region爲單位的,這樣就很容易發生compaction風暴從而下降系統的總體吞吐量
  第三,從split方面考慮,因爲hfile是以family爲單位的,所以對於多個family來講,數據被分散到了更多的hfile中,減少了split發生的機率。這是把雙刃劍。更少的split會致使該region的體積比較大,因爲balance是以region的數目而不是大小爲單位來進行的,所以可能會致使balance失效。而從好的方面來講,更少的split會讓系統提供更加穩定的在線服務。而壞處咱們能夠經過在請求的低谷時間進行人工的split和balance來避免掉。
     所以對於寫比較多的系統,若是是離線應該,咱們儘可能只用一個family好了,但若是是在線應用,那仍是應該根據應用的狀況合理地分配family

4 hbase.regionserver.handler.count

 RegionServer端開啓的RPC監聽器實例個數,也即RegionServer可以處理的IO請求線程數。默認是10.

 此參數與內存息息相關。該值設置的時候,以監控內存爲主要參考。

 對於 單次請求內存消耗較高的Big PUT場景(大容量單次PUT或設置了較大cache的scan,均屬於Big PUT)或ReigonServer的內存比較緊張的場景,能夠設置的相對較小。

 對於 單次請求內存消耗低,TPS(TransactionPerSecond,每秒事務處理量)要求很是高的場景,能夠設置的相對大些。

相關文章
相關標籤/搜索