HBase Compaction策略

StripeCompactionPolicy

Stripes表示條紋,意爲將Region分爲多個條紋區間分別做compact,類似於將Region分爲多個Sub-Region。
適用場景:

  1. Region較大:相對於較小的Region而言,對MemStore和Region的管理帶來的負擔更小。
  2. 新產生的行鍵不均勻分佈在各Region:如基於時間序列的行鍵生成方式,新生成的數據行均分佈在Region的同一個Sub-Region區間,只有新產生的那一部分行鍵相關數據會被合併,舊的數據行會很少合併或者根本不合並。

DateTieredCompactionPolicy

按時間分層合併,顧名思義,該合併策略與時間相關,適用於數據寫入基於時間產生且無更新刪除,數據讀取會指定數據讀取區間,並且讀取新產生的數據的頻率較大。
按時間分層合併策略通過感知需要合併的HFile的數據寫入相關時間戳,並不會將新老數據合併爲一個大的HFile,而是按時間分層結構來組織合併HFile,所以不同時間寫入的相鄰行鍵數據可能被放入不同的HFile,這樣對基於時間區間的掃描效率是一個很大的提升,但是對基於行鍵的區間掃描效率會是一個很不友好的策略。

RatioBasedCompactionPolicy

基於比列的合併策略,該策略在0.98版本之前是HBase默認的策略,之後的版本使用了基於比例策略的一個改進版本(ExploringCompactionPolicy),如果是Major合併,那麼該策略會將所有的StoreFile文件合併爲一個大的文件,如果是Minor合併,使用如下策略選擇需要合併的文件:
前提:假設最老的StoreFile文件大小最大,選擇待合併的文件按時間排序,最舊的文件排最前。
配置項hbase.hstore.compaction.ratio合併參數,命名爲R
配置項hbase.hstore.compaction.min最小待合併文件數,命名爲A。
配置項hbase.hstore.compaction.max最大待合併文件數,命名爲B。
配置項hbase.hstore.compaction.min.size最小合併文件總大小,命名爲C,以R=0.1,A=3,B=5,C=20,待合併的文件爲O=[50,40,30,30,20,10,5]爲例子

  1. 計算一個待合併文件總大小的數組fileSizes[i,i+A-1) ,得到X = [150, 120, 90, 65, 35, 15, 5]。
  2. 從舊到新文件,逐一判斷文件大小是否滿足 fileSizes[i] > Math.max(C, (X[i + 1] * R)) ,當條件不滿足後,i即爲待合併的文件開始位置,該步驟是爲了過濾掉大的文件,此處得到i=4。
  3. 最後得到需要合併的文件列表爲O.subList(4,O.size-1),得出結果爲[20, 10, 5]。

簡化後的代碼片段如下所示

package com.mt.hbase.chpt07.compact;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * @author pengxu
 * @Date 2018/12/9.
 */
public class RatioCompactPolicy {

    public static List<integer> applyCompactionPolicy(List<integer> candidates , boolean mayBeStuck){
        int minFileToCompact = 3;
        int maxFileToCompact = 5;
        int minCompactSize = 20;
        double ratio = 0.1;
        int start = 0;
        // get store file sizes for incremental compacting selection.
        final int countOfFiles = candidates.size();
        long[] fileSizes = new long[countOfFiles];
        long[] sumSize = new long[countOfFiles];
        for (int i = countOfFiles - 1; i >= 0; --i) {
            fileSizes[i] = candidates.get(i);
            // calculate the sum of fileSizes[i,i+maxFilesToCompact-1) for algo
            int tooFar = i + maxFileToCompact - 1;
            sumSize[i] = fileSizes[i] + ((i + 1 < countOfFiles) ? sumSize[i + 1] : 0) - ((tooFar
                    < countOfFiles) ? fileSizes[tooFar] : 0);
        }

        while (countOfFiles - start >= minFileToCompact &&
                fileSizes[start] > Math.max(minCompactSize, (sumSize[start + 1] * ratio))) {
            ++start;
        }
        if (start < countOfFiles) {
            System.out.println("Default compaction algorithm has selected " + (countOfFiles - start)
                    + " files from " + countOfFiles + " candidates");
        } else if (mayBeStuck) {
            // We may be stuck. Compact the latest files if we can.
            int filesToLeave = candidates.size() - minFileToCompact;
            if (filesToLeave >= 0) {
                start = filesToLeave;
            }
        }
        System.out.println("sumSize=" + Arrays.toString(sumSize));
        System.out.println("start=" + start);
        candidates.subList(0, start).clear();
        System.out.println("fileToCompact =" + candidates);
        return candidates;
    }

    public static void main(String[] args) {
        int[] candidateIntArray = new int[] { 50, 40, 30, 30, 20, 10, 5 };
        List<integer> candidateList = new LinkedList<integer>();
        for(Integer candidate : candidateIntArray){
            candidateList.add(candidate);
        }
        applyCompactionPolicy(candidateList,true);

    }

}

ExploringCompactionPolicy

該策略繼承自RatioBasedCompactionPolicy,其選擇待合併的文件列表算法非常簡單,即根據上述參數(最小待合併文件數、最大待合併文件數、合併參數、合併文件總大小)組合計算出一個文件數最多,文件總數最小的文件區間組合,這個計算類似用一個滑動窗口去計算窗口內文件數量與大小的比例,文件越小數量越多則爲最優解。

FIFOCompactionPolicy

該策略繼承自ExploringCompactionPolicy,僅僅選擇所有數據均已經過期的StoreFile文件進行合併,所以表的列族需要指定數據的TTL,故該合併策略僅適用於臨時存儲數據,經過處理後會被全部丟棄的場景。


HBase從1.2.X開始到2.0.X,默認的壓縮策略都是RatioBasedCompactionPolicy,可以通過如下兩種方式修改默認的壓縮策略:

  1. 修改hbase-site.xml配置項hbase.hstore.engine.class,該修改會應用到整個HBase集羣。
  2. 執行表修改語句alter 's_behavior', CONFIGURATION => {'hbase.hstore.engine.class' => 'rg.apache.hadoop.hbase.regionserver.DefaultStoreEngine'},該修改方式只對語句指定的表生效
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章