Extract Fact Table Distinct Columns(MR) 流程和源碼解析

Extract Fact Table Distinct Columns job 進行統計估算和字典編碼、範圍計算,具體主要做3件事情:1、HLL估算統計每個cuboid的結果條數;2、所有非Derived維度列的範圍(min-max);3、所有需要字典編碼的列進行字典編碼;這3部分內容都會存儲到HDFS上,共後續步驟使用。本文所有的講解根據MR實現進行講解,Spark大家對照思路進行分析。

  1. 執行入口類: MapReduceExecutable.doWork 中調用job類的run方法即調用FactDistinctColumnsJob.run

  2. 輸入數據:
    (1)、採樣的數據比例,kylin.job.sampling-percentage,default 100,已經第一步flatTable中的數據。

  3. 輸出目錄:
    (1)、/user/prod_kylin/kylin_engine/BIGDATA_KYLIN-kylin_meadata_test/kylin-jobId/cubeName/fact_distinct_columns/

  4. MR Mapper:
    (1)、FactDistinctColumnsMapper.java
    (2)、inputFormat 爲flat table(flatTableInputFormat)
    (3)、Mapper輸出:
    a、需要字典列的每列在此mapper中不同的值,輸出一個selfKey(1個字節的reduce編號+某行此列的值+數據類型),value爲null;
    b、每個mapper中所有非Derived維度列且不屬於a中的列的每列出現的最大值和最小值,輸出一個selfKey(1個字節的reduce編號+此列的max值(會min值)+數據類型),value爲null,每個mapper會輸出某列兩個此類型輸出,一個max一個min;
    c、每個mapper對每個cubid的估算值,輸出一個selfKey(固定第一個字節爲輸出的類型(-1表示爲 HLL(HyperLogLog)類型的Reduce編號計算規則,具體參見partitioner計算reduce編號) + 某個cubid(8個字節) +數據類型(此處固定爲0)),value爲此mapper對此cubid的估算值;

  5. MR Combiner: CombinerFactDistinctColumnsCombiner
    由於Mapper的3種輸出,其中dict列的value爲空,只需要去重key值即可;hll因爲每個cubid就一個所以在combiner沒有做任何處理; max和min每個mapper也只有一個也沒有在commbiner做任何處理;

  6. MR Partitioner:
    (1)、 PartitionerClass:FactDistinctColumnPartitioner.java
    根據mapper key的第一個字節除hll外其他的就是存儲的實際的reduce編號直接返回即可,hll類型的則根據這個cubid%hllreducecount(計算hll總的reduce數),然後用nDimReducers的個數加上cubid%hllreducecount值即爲此cubid的reduce編號,通常hllreducecount爲1,即所有的cubid的hll計算均在一個reduce中完成,同一個cuboid總會分配到同一個reduce計算hll。

計算Reduce編號源碼:

    @Override
    public int getPartition(SelfDefineSortableKey skey, Text value, int numReduceTasks) {
        Text key = skey.getText();
        if (key.getBytes()[0] == FactDistinctColumnsReducerMapping.MARK_FOR_HLL_COUNTER) {//key的第一個字節如果是-1的情況表示是HLL
            Long cuboidId = Bytes.toLong(key.getBytes(), 1, Bytes.SIZEOF_LONG);
            return reducerMapping.getReducerIdForCuboidRowCount(cuboidId);
        } else {
            return BytesUtil.readUnsigned(key.getBytes(), 0, 1);
        }
    }

計算某個cuboid HLL Reduce 編號源碼:

public int getReducerIdForCuboidRowCount(long cuboidId) {
        int rowCounterId = (int) (Math.abs(cuboidId) % nCuboidRowCounters);
        return nDimReducers + rowCounterId;
    }
  1. MR Reducer:
    根據Mapper的輸入進行需要字典列的字典構建、計算所有非derived維度列max和Min、HLL估算的統計值。
    (1)、FactDistinctColumnsReducer.java
    (2)、MultipleOutputs:
    HLL估算統計結果輸出:
    輸出路徑:baseDir/statistics/statistics-r-0000x
    輸出內容:共有3+cuboid.length行記錄,其中==前3行的內容分別爲:
    == key=-1(表示mapper重疊率),value=合併前的每個mapper對每個cuboid 的估算的rowcount和/合併每個mapper對每個cuboid估算的rowcount後的和;key=-2(表示此reduce的輸入的mapper數量),value即mapper的數量;
    key=0(表示抽樣的百分比),value爲抽樣的百分比,這是咱們從配置文件中配置的默認是14%。
    其他行的內容爲每個cuboid及其對應的估算結果。
    所有非Derived維度列的範圍:
    輸出路徑:baseDir/colName/colName.dci-r-0000x
    輸出內容: 每個reduce只有兩行內容,某列此reduce max和min值,第一行爲Min值,第二行爲Max值,key爲空即只有一個字段。
    所有需要字典編碼列字典編碼內容:
    輸出路徑:baseDir/colName/colName.rldict-r-0000x
    輸出內容: 只有一行記錄,即某列此reduce的字典值,key爲空即只有一個字段。

  2. 名詞解釋:
    某個cube的所有需要編碼的列:
    (1)、此cube維度列的編碼類型爲dict的列(Rowkeys中Encoding,同時需要排除掉此列爲MR HIVE類型的列或derived的列、Extended的列);
    在這裏插入圖片描述
    (2)、度量的類型爲Bitmap(bitmap且列類型爲bigint類型,如果此列是MR HIVE類型則也不包含)、Raw、TopN(topN measuer且此列爲dict列或者未配置encoding);排除MR HIVE的列的度量類型爲Bitmap且該列類型爲bigint類型的列或Raw或TopN且此列爲dict列或者未配置encoding。
    在這裏插入圖片描述

ShardByColumns:
在這裏插入圖片描述
Global Dictionaries
全局字典列且此列的Build Class類型爲GlobalDictionaryBuilder或SegmentAppendTrieDictBuilder類型。
在這裏插入圖片描述

發佈了46 篇原創文章 · 獲贊 10 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章