HBase性能優化方法總結(一):表的設計

本文主要是從HBase應用程序設計與開發的角度,總結幾種經常使用的性能優化方法。有關HBase系統配置級別的優化,可參考:淘寶Ken Wu同窗的博客html

下面是本文總結的第一部份內容:表的設計相關的優化方法。apache

1. 表的設計

1.1 Pre-Creating Regions

默認狀況下,在建立HBase表的時候會自動建立一個region分區,當導入數據的時候,全部的HBase客戶端都向這一個region寫數據, 直到這個region足夠大了才進行切分。一種能夠加快批量寫入速度的方法是經過預先建立一些空的regions,這樣當數據寫入HBase時,會按照 region分區狀況,在集羣內作數據的負載均衡。數組

有關預分區,詳情參見:Table Creation: Pre-Creating Regions,下面是一個例子:緩存

複製代碼

   createTable(HBaseAdmin admin, HTableDescriptor table, [][] splits)
 IOException {
   {
    admin.createTable(table, splits);
     ;
  }  (TableExistsException e) {
    logger.info("table " + table.getNameAsString() + " already exists");
         ;  
  }
}

  [][] getHexSplits(String startKey, String endKey,  numRegions) {
  [][] splits =  [numRegions-1][];
  BigInteger lowestKey =  BigInteger(startKey, 16);
  BigInteger highestKey =  BigInteger(endKey, 16);
  BigInteger range = highestKey.subtract(lowestKey);
  BigInteger regionIncrement = range.divide(BigInteger.valueOf(numRegions));
  lowestKey = lowestKey.add(regionIncrement);
  ( i=0; i < numRegions-1;i++) {
    BigInteger key = lowestKey.add(regionIncrement.multiply(BigInteger.valueOf(i)));
    [] b = String.format("%016x", key).getBytes();
    splits[i] = b;
  }
   splits;
}

複製代碼

1.2 Row Key

HBase中row key用來檢索表中的記錄,支持如下三種方式:性能優化

  • 經過單個row key訪問:即按照某個row key鍵值進行get操做;負載均衡

  • 經過row key的range進行scan:即經過設置startRowKey和endRowKey,在這個範圍內進行掃描;ide

  • 全表掃描:即直接掃描整張表中全部行記錄。性能

在HBase中,row key能夠是任意字符串,最大長度64KB,實際應用中通常爲10~100bytes,存爲byte[]字節數組,通常設計成定長的測試

row key是按照字典序存儲,所以,設計row key時,要充分利用這個排序特色,將常常一塊兒讀取的數據存儲到一塊,將最近可能會被訪問的數據放在一塊。優化

舉個例子:若是最近寫入HBase表中的數據是最可能被訪問的,能夠考慮將時間戳做爲row key的一部分,因爲是字典序排序,因此可使用Long.MAX_VALUE - timestamp做爲row key,這樣能保證新寫入的數據在讀取時能夠被快速命中。

1.3 Column Family

不要在一張表裏定義太多的column family。目前Hbase並不 能很好的處理超過2~3個column family的表。由於某個column family在flush的時候,它鄰近的column family也會因關聯效應被觸發flush,最終致使系統產生更多的I/O。感興趣的同窗能夠對本身的HBase集羣進行實際測試,從獲得的測試結果數 據驗證一下。

1.4 In Memory

建立表的時候,能夠經過HColumnDescriptor.setInMemory(true)將表放到RegionServer的緩存中,保證在讀取的時候被cache命中。

1.5 Max Version

建立表的時候,能夠經過HColumnDescriptor.setMaxVersions(int maxVersions)設置表中數據的最大版本,若是隻須要保存最新版本的數據,那麼能夠設置setMaxVersions(1)。

1.6 Time To Live

建立表的時候,能夠經過HColumnDescriptor.setTimeToLive(int timeToLive)設置表中數據的存儲生命期,過時數據將自動被刪除,例如若是隻須要存儲最近兩天的數據,那麼能夠設置 setTimeToLive(2 * 24 * 60 * 60)。

1.7 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,將它們按照row key進行合併,因爲StoreFile和MemStore都是通過排序的,而且StoreFile帶有內存中索引,一般合併過程仍是比較快的。

實際應用中,能夠考慮必要時手動進行major compact,將同一個row key的修改進行合併造成一個大的StoreFile。同時,能夠將StoreFile設置大些,減小split的發生。

相關文章
相關標籤/搜索