Extract Fact Table Distinct Columns job 進行統計估算和字典編碼、範圍計算,具體主要做3件事情:1、HLL估算統計每個cuboid的結果條數;2、所有非Derived維度列的範圍(min-max);3、所有需要字典編碼的列進行字典編碼;這3部分內容都會存儲到HDFS上,共後續步驟使用。本文所有的講解根據MR實現進行講解,Spark大家對照思路進行分析。
-
執行入口類: MapReduceExecutable.doWork 中調用job類的run方法即調用FactDistinctColumnsJob.run
-
輸入數據:
(1)、採樣的數據比例,kylin.job.sampling-percentage,default 100,已經第一步flatTable中的數據。 -
輸出目錄:
(1)、/user/prod_kylin/kylin_engine/BIGDATA_KYLIN-kylin_meadata_test/kylin-jobId/cubeName/fact_distinct_columns/ -
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的估算值; -
MR Combiner: CombinerFactDistinctColumnsCombiner
由於Mapper的3種輸出,其中dict列的value爲空,只需要去重key值即可;hll因爲每個cubid就一個所以在combiner沒有做任何處理; max和min每個mapper也只有一個也沒有在commbiner做任何處理; -
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;
}
-
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爲空即只有一個字段。 -
名詞解釋:
某個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類型。