1. 程式人生 > >HBase工作中的一些優化方法

HBase工作中的一些優化方法

1、表的設計
  • Pre-creating Regions(預分割槽)
    •   預設情況下,在建立Hbase表的時候會自動建立一個region分割槽,當匯入資料的時候,所有的Hbase客戶端都向這一個region寫資料,直到這個region足夠大了才進行切分。一種可以加快批量寫入速度的方法是通過預先建立一些空的regions,這樣當資料寫入Hbase時,會按照region分割槽情況,在叢集內做資料的負載均衡。
  • rowkey:Hbase中rowkey用來檢索表中的記錄,支援一下三種方式
    • 通過單個rowkey訪問:即按照某個rowkey鍵值進行get操作
    • 通過rowkey的range進行scan:通過startRowkey和endRowkey,在這個範圍內進行掃描
    • 全表掃描:即直接掃描整張表中所有行記錄
    • 在Hbase中rowkey可以是任意字串,最大長度64K,一般為10~100bytes,一般設計為定長
    • rowkey規則
      • 越小越好
      • rowkey的設計是要根據實際業務來
      • 雜湊性:
        • 取反
        • Hash
  • column family
    •   不要在Hbase一張表裡定義太多的column family。目前Hbase並不能很好的處理超過2~3個column family的表。因為某個column family在flush的時候,它鄰近的column family也會因關聯效應出發flush,最終導致系統產生更多的I/O。
  • In memory:建立表時,可以通過HColumnDescriptor.setInMemory(true) 將表放到RS的快取中,保證在讀取的時候被chache命中
  • Max version:建立表時,可以通過HColumnDescriptor.setMaxVersions(int maxVersions)設定表中資料的最大版本,如果只需要儲存最新版本的資料,那麼可以設定setMaxVersions(1)
  • Time to live:建立表時,可以通過HColumnDescriptor.setTimeToLive(int timeToLive)設定表中資料的儲存生命週期,國企資料將自動被刪除,例如如果只需要儲存最近兩天的資料,那麼可以設定setTimeToLive(2 * 24 * 60 * 60)
  • Compact & split:
    • 在Hbase中,資料在更新時首先寫入WAL日誌(HLog)和記憶體(MemStore)中,Memstore中的資料是排序的,當memstore累計到一定閥值時,就會建立一個新的Memstore,並且將老的Memstore新增到flush對了,由單獨的執行緒flush到磁碟上,成為一個StoreFile。與此同時,系統會在zookeeper中記錄一個redo point,表示這個時刻之前的變更已經持久化了(minor compact)。
    • StoreFile是隻讀的,一旦建立後就不可以在修改。因此Hbase的更新其實是不斷追加的操作。當一個store中的storeFile達到一定的閥值後,就會進行一個合併(major compact),將對同一個key的修改合併到一起,形成一個大的storeFile,當storeFile的大小達到一定閥值後,又回對storeFile進行分割(split),等分為兩個storeFile。
    • 由於對錶的更新是不斷追加的,處理讀請求是,需要訪問store中全部storeFile和memstore,將他們按照rowkey進行合併,由於storeFile和Memstore都是經過排序的,並且storeFile帶有記憶體中索引,通常合併過程還是比較快的
    • 實際應用中,可以考慮必要時手動進行major compact,將同一個rowkey的修改進行合併形成一個較大的storeFile。同時將storeFile設定大些,減少split的發生
    • Hbase為了防止小檔案(被刷到磁碟的memstore)過多,以保證查詢效率,Hbase需要在必要的時候將這些小的storeFile合併成相對較大的storeFile,這個過程稱之為compact。在Hbase中,主要存在兩種型別的compact:minor compaction和major compaction
      • minor compaction:是較小、很少檔案的合併
      • major compaction:將所有的storeFile合併成一個,觸發major compaction的可能條件有:major_compact命令、majorCompact() API、RS自動執行(相關引數:hbase.hregion.majorcompaction 預設為24小時、hbase.hregion.majorcompaction.jetter 預設0.2、防止RS在同一時間進行major compaction)
      • hbase.hregion.majorcompaction.jetter 作用:對引數hbase.hregion.majorcompaction規定的值起到浮動的作用,假如兩個引數都為預設值24和0.2,那麼major compact最終使用的數值為:19.2~28.8這個範圍
    • 關閉自動 major compaction
    • 手動程式設計 major compaction
    • minor compaction的執行機制要複雜一些,它由一下幾個引數共同決定:
    • hbase.hstore.compaction.min :預設值為 3,表示至少需要三個滿足條件的store file時,minor compaction才會啟動
    • hbase.hstore.compaction.max 預設值為10,表示一次minor compaction中最多選取10個store file
    • hbase.hstore.compaction.min.size 表示檔案大小小於該值的store file 一定會加入到minor compaction的store file中
    • hbase.hstore.compaction.max.size 表示檔案大小大於該值的store file 一定會被minor compaction排除
    • hbase.hstore.compaction.ratio 將store file 按照檔案年齡排序(older to younger),minor compaction總是從older store file開始選擇
2、寫表操作
  • 多個HTable併發寫
  • HTable引數設定
    • Auto flush:HTable.setAutoFlush(false),關閉客戶端的自動flush,這樣可以批量寫入資料到Hbase,而不是有一條put就執行一次更新,只有當put填滿客戶端寫快取時,才實際向Hbase服務端發起寫情趣。預設auto flush是開啟的
    • write buffer:設定客戶端的buffer大小,如果新設的buffer小於當前寫buffer中的資料,buffer將會被flush到服務端
    • WAL Flag
      •   注意:謹慎選擇關閉WAL日誌,因為這樣,如果RS宕機,put/delete的資料將無法根據WAL日誌進行恢復
    • 批量寫
    • 多執行緒併發寫 
3、讀表操作
  • scan caching
    • Hbase的conf配置檔案中配置
    • 通過呼叫HTable.setScannerCaching()進行配置
    • 通過呼叫scan.setCaching() 進行配置
    • 三者的優先順序越來越高階
  • 批量讀
  • 多執行緒併發讀 
  • 快取查詢結果
  • Blockcache
    • Hbase上RS的記憶體分為兩個部分,一部分作為Memstore,主要用來寫,另外一部分作為BlockCache,主要用來讀
    • 寫請求會先寫入memstore,RS會給每個region提供一個memstore,當memstore滿64M以後,會啟動flush重新整理到磁碟。當memstore的總大小超過限制時(heapsize * hbase.regionserver.global.memstore.upperlimit * 0.9),會強行啟動flush程序,從最大的memstore開始flush直到低於限制
    • 讀請求先到memstore中查資料,查不到就到BlockCache中查,再查不到就會到磁碟上讀,並把結果放入BlockCache。由於BlockCache採用LRU策略,因此BlockCache達到上線(heap size * hfile.block.cache.size * 0.85)後,會啟動淘汰機制,淘汰掉最老的一批資料
    • 一個RS上有一個BlockCache和N個Memstore,他們的大小和不能大於等於heapsize * 0.8,否則Hbase不能啟動。預設BlockCache為0.2,memstore為0.4。對於注重讀響應時間的系統,可以將BlockCache設大些,比如BlockCache=0.4,memstore=0.39,以加大快取的命中率