HBase性能优化方法总结(一):表的设计
1. 表的設計
1.1 Pre-Creating Regions
默認情況下,在創建HBase表的時候會自動創建一個region分區,當導入數據的時候,所有的HBase客戶端都向這一個region寫數據,直到這個region足夠大了才進行切分。一種可以加快批量寫入速度的方法是通過預先創建一些空的regions,這樣當數據寫入HBase時,會按照region分區情況,在集群內做數據的負載均衡。
有關預分區,詳情參見:Table Creation: Pre-Creating Regions,下面是一個例子:
?
public?static?boolean?createTable(HBaseAdmin admin, HTableDescriptor table, byte[][] splits)
throws?IOException {
??try?{
????admin.createTable(table, splits);
????return?true;
??} catch?(TableExistsException e) {
????logger.info("table " + table.getNameAsString() + " already exists");
????// the table already exists...
????return?false; ?
??}
}
public?static?byte[][] getHexSplits(String startKey, String endKey, int?numRegions) {?//start:001,endkey:100,10region [001,010]
[011,020]
??byte[][] splits = new?byte[numRegions-1][];
??BigInteger lowestKey = new?BigInteger(startKey, 16);
??BigInteger highestKey = new?BigInteger(endKey, 16);
??BigInteger range = highestKey.subtract(lowestKey);
??BigInteger regionIncrement = range.divide(BigInteger.valueOf(numRegions));
??lowestKey = lowestKey.add(regionIncrement);
??for(int?i=0; i < numRegions-1;i++) {
????BigInteger key = lowestKey.add(regionIncrement.multiply(BigInteger.valueOf(i)));
????byte[] b = String.format("%016x", key).getBytes();
????splits[i] = b;
??}
??return?splits;
}
?
1.2?Row Key
HBase中row key用來檢索表中的記錄,支持以下三種方式:
- 通過單個row key訪問:即按照某個row key鍵值進行get操作;
- 通過row key的range進行scan:即通過設置startRowKey和endRowKey,在這個范圍內進行掃描;
- 全表掃描:即直接掃描整張表中所有行記錄。
在HBase中,row key可以是任意字符串,最大長度64KB,實際應用中一般為10~100bytes,存為byte[]字節數組,一般設計成定長的。
row key是按照字典序存儲,因此,設計row key時,要充分利用這個排序特點,將經常一起讀取的數據存儲到一塊,將最近可能會被訪問的數據放在一塊。
舉個例子:如果最近寫入HBase表中的數據是最可能被訪問的,可以考慮將時間戳作為row key的一部分,由于是字典序排序,所以可以使用Long.MAX_VALUE - timestamp作為row key,這樣能保證新寫入的數據在讀取時可以被快速命中。
Rowkey規則:
?
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的發生。
?
hbase為了防止小文件(被刷到磁盤的menstore)過多,以保證保證查詢效率,hbase需要在必要的時候將這些小的store file合并成相對較大的store file,這個過程就稱之為compaction。在hbase中,主要存在兩種類型的compaction:minor ?compaction和major compaction。
minor compaction:的是較小、很少文件的合并。
major compaction 的功能是將所有的store file合并成一個,觸發major compaction的可能條件有:major_compact 命令、majorCompact() API、region server自動運行(相關參數:hbase.hregion.majoucompaction 默認為24 小時、hbase.hregion.majorcompaction.jetter 默認值為0.2 防止region server 在同一時間進行major compaction)。
hbase.hregion.majorcompaction.jetter參數的作用是:對參數hbase.hregion.majoucompaction 規定的值起到浮動的作用,假如兩個參數都為默認值24和0,2,那么major compact最終使用的數值為:19.2~28.8 這個范圍。
?
Timer類,contab
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開始選擇
總結
以上是生活随笔為你收集整理的HBase性能优化方法总结(一):表的设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Zookeeper全解析——Paxos作
- 下一篇: HBase性能优化方法总结(二):写表操