逐層構建算法算法
咱們知道,一個N維的Cube,是由1個N維子立方體、N個(N-1)維子立方體、N*(N-1)/2個(N-2)維子立方體、......、N個1維子立方體和1個0維子立方體構成,總共有2^N個子立方體組成,在逐層算法中,按維度數逐層減小來計算,每一個層級的計算(除了第一層,它是從原始數據聚合而來),是基於它上一層級的結果來計算的。
好比,[Group by A, B]的結果,能夠基於[Groupby A, B, C]的結果,經過去掉C後聚合得來的;這樣能夠減小重複計算;當 0維度Cuboid計算出來的時候,整個Cube的計算也就完成了。併發
下圖爲一個四維Cube的構建過程:app
此算法的Mapper和Reducer都比較簡單。Mapper以上一層Cuboid的結果(Key-Value對)做爲輸入。因爲Key是由各維度值拼接在一塊兒,從其中找出要聚合的維度,去掉它的值成新的Key,而後把新Key和Value輸出,進而HadoopMapReduce對全部新Key進行排序、洗牌(shuffle)、再送到Reducer處;Reducer的輸入會是一組有相同Key的Value集合,對這些Value作聚合計算,再結合Key輸出就完成了一輪計算。oop
每一輪的計算都是一個MapReduce任務,且串行執行; 一個N維的Cube,至少須要N次MapReduceJob。編碼
問題:spa
對HDFS的讀寫操做較多;Cube有比較多維度的時候,所須要的MapReduce任務也相應增長; 該算法的效率較低code
該算法的主要思想是,對Mapper所分配的數據塊,將它計算成一個完整的小Cube 段(包含全部Cuboid);每一個Mapper將計算完的Cube段輸出給Reducer作合併,生成大Cube,也就是最終結果;以下圖所示:blog
爲了節省存儲資源,Kylin對維度值進行了字典編碼。例如城市維度將beijing
和shanghai
依次編碼爲0和1。排序
HBase KV存儲:在計算cuboid過程當中,會將Hive表的數據轉化爲HBase的KV形式。Rowkey的具體格式是cuboid id + 具體的維度值
(最新的Rowkey中爲了併發查詢還加入了ShardKey),例如維度組合是(year,city),因此cuboid id就是00000011,cuboid是8位,具體維度值是1994和shanghai,加入維度值對應的字典編碼也是11,因此HBase的Rowkey就是0000001111,對應的HBase Value就是sum(priece)
的具體值。ci
全部的cuboid計算完成後,會將cuboid轉化爲HBase的KeyValue
格式生成HBase的HFile,最後將HFile load進cube對應的HBase表中。
Cube的構建包含以下步驟,由任務引擎來調度執行。
1)建立臨時的Hive平表(從Hive讀取數據)。
2)計算各維度的不一樣值,並收集各Cuboid的統計數據。
3)建立並保存字典。
4)保存Cuboid統計信息。
5)建立HTable。
6)計算Cube(一輪或若干輪MapReduce)。
7)將Cube的計算結果轉成HFile。 8)加載HFile到HBase。(RowKey爲:Cuboid ID + 維度值,Value爲度量值) 9)更新Cube元數據。(變動Cube狀態) 10)垃圾回收。(刪除臨時表)