Apache Kylin 入門 5 - 構建 Cube

Apache Kylin 入門系列目錄算法

因爲業務需求不盡相同,本文不使用具體的案例進行演示,文章會更加傾向於對構建過程當中的選項和注意事項進行全方位闡述。編程

1、Cube Info

Cube Info 界面主要填寫 Cube 的一些基本信息,首先要選擇一個數據模型,而後填寫 Cube 名稱,Cube 名稱全局惟一不能重複;Cube 信息填寫完成後點擊 「Next」 進入下一步。架構

Cube 基本信息填寫

2、Dimensions

Dimensions 是維度選擇界面,從數據模型的維度中選擇一些列做爲 Cube 的維度,這個算是 Cube 構建過程當中第一個比較重要的環節,這裏的設置會影響到生成的 Cuboid 數量,進而影響 Cube 的數據量大小。post

在選擇維度時,每個維度列能夠做爲普通維度(Normal),也能夠做爲衍生維度(Derived)。相對於普通維度來講,衍生維度並不參與維度的 Cuboid,衍生維度對應的外鍵(FK)參與維度 Cuboid,從而下降 Cuboid 數。在查詢時,對衍生維度的查詢會首先轉換爲對外鍵所在維度的查詢,所以會犧牲少許性能(大部分狀況下能夠接受)。性能

維度選擇界面

一、維度選擇的建議:

  1. 做爲 Cube 的維度須要知足下面的條件:可能存在於 where 條件中或者 groupBy 中的維度;
  2. 事實表(Fact Table)只選擇參與查詢的字段,不參與查詢的必定不要勾選(即使是外鍵)
  3. 維度表(Lookup Table)中的主鍵與事實表的外鍵一一對應,推薦勾選事實表的外鍵,維度表的主鍵勾選後選擇爲衍生(Derived)維度;
  4. 對於星型模型而言,維度表的字段每每能夠所有爲衍生字段;
  5. 對於雪花模型而言,若是維度表存在子表,則維度表對於子表的外鍵推薦做爲普通(Normal)維度。

二、特別注意的事項:

  1. 錶鏈接的字段並不是必定要參與 Cuboid 計算;
  2. 錶鏈接的字段若是沒有被勾選,且其外鍵表中沒有任何字段做爲衍生維度,則該錶鏈接字段是不會參與 Cuboid 的;
  3. 一旦被設置爲 Normal 類型,則必定會參與 Cuboid 計算;
  4. 若是維度表存在層級(例如省市縣、日月年等),則推薦分層級的相關字段選擇爲普通(Normal)維度。

維度選擇結果

3、Measures

維度選擇完成後,須要選擇度量聚合的方式,比較常規的聚合方式有:COUNT、SUM、MIN、MAX、PERCENTILE,下面將詳細介紹其餘幾種聚合方式。優化

一、TOP_N

Top-N 度量,旨在在 Cube 構建的時候預計算好須要的 Top-N;在查詢階段,就能夠迅速的獲取並返回 Top-N 記錄,這樣查詢性能就遠遠高於沒有 Top-N 預計算結果的 Cube。編碼

1.一、Top-N 中 Group By 的該如何選擇?

例如:全國二氧化碳污染物總和的省份排名,結果是省份排名,須要測量的是污染物的總和,所以 Group By 須要設置爲 污染物類型。設計

1.二、Return Type 中的 Top N 是什麼意思?

TOP N 表示最終獲取的前 N 名的排序是比較準確的,例如 TOP 10 表示最終的前 10 名是比較準確的(維度的基數很是大時存在偏差),可是不表明只能取前 10 個(Limit 10),可使用其餘數字,例如 Limit 500,只是返回更多內容時,精準度沒有保證。3d

1.三、TOP-N 的存儲

使用 TOP-N 時,排序度量字段和 Group By 字段會組合在一塊兒,造成一個字段進行存儲,用戶須要 Top 100 的結果,Kylin 對於每種組合條件值,保留 Top 5000 (50倍)的紀錄, 並供之後再次合併。code

TOP-N 內部存儲結構

二、Count_Distinct

Count_Distinct 度量有兩個實現:

  1. 近似實現:基於 HyperLogLog 算法,可選擇接受的錯誤率(從9.75% 到 1.22%),低錯誤率須要更多存儲;
  2. 精確實現:基於 Bitmap(位圖)算法,對於數據型爲 tinyint、smallint 和 int 的數據,將把數據對應的值直接打入位圖;對於數據型爲 long,string 和其餘的數 據,將它們編碼成字符串放入字典,而後再將對應的值打入位圖。返回的度量結果是已經序列化的位圖數據,而不只是計算的值。這確保了不一樣的 segment 中,甚至跨越不一樣的 segment 來上卷,結果也是正確的。

越精確消耗的存儲空間越大,大多數場景下 HyperLogLog 的近似實現便可知足需求。

三、EXTEND_COLUMN

在分析場景中,常常存在對某個 id 進行過濾,但查詢結果要展現爲 name 的狀況,好比user_iduser_name。這類問題一般有三種解決方式:

  1. 將 id 和 name 都設置爲維度,查詢語句相似select name, count(*) from table where id = 1 group by id,name,這種方式的問題是會致使維度增多,致使預計算結果膨脹;
  2. 將 id 和 name 都設置爲維度,而且將二者設置爲聯合維度(Joint Dimensions),這種方式的好處是保持維度組合數不會增長,但限制了維度的其它優化,好比 id 不能再被設置爲強制維度或者層次維度;
  3. 將 id 設置爲維度,name 設置爲特殊的 Measure,類型爲 Extended Column,這種方式既能保證過濾 id 且查詢 name 的需求,同時也不影響 id 維度的進一步優化。

4、Refresh Setting

  • 觸發自動合併的時間閾值(Auto Merge Thresholds):自動合併小的 segments 到中等甚至更大的 segment,若是不想自動合併,刪除默認 2 個選項;
  • Volatile Range: 默認爲 0,‘Auto Merge’ 會自動合併全部可能的 cube segments;設置具體的數值後,‘Auto Merge’ 將不會合並最近 Volatile Range 天的 cube segments;假設 Volatile Range 設置爲 7,則最近 7 天內生成的 cube segments 不會被自動合併;
  • 保留時間閾值(Retention Threshold):對於時間久遠的不須要再被查詢的 Segment,Kylin 經過設置保留時間閾值能夠自動清除這些 Segment,以節省磁盤空間;每當構建新的 Segment 時,Kylin 會自動檢查老的 Segment,當這些 Segment 的結束日期與當前最新 Segment 的結束日期的差值大於保留時間閾值,則會被清除;若是無需自動清理,能夠默認設置保留時間閾值爲 0。
  • 分區起始時間(Partition Start Date):Cube 構建的起始時間,1970-01-01 08:00:00 默認爲分區起始時間。

5、Advanced Setting

高級設置主要用於 Cuboid 的剪枝優化,經過聚合組(Aggregation Group)、必要維度(Mandatory Dimension)、層級維度(Hierarchy Dimension)、聯合維度(Joint Dimension)等方式,可使得 Cuboid 的組合在預期範圍內。

一、聚合組(Aggregation Group)

根據查詢的維度組合,能夠劃分出維度組合大類,這些大類在 Kylin 裏面被稱爲聚合組。例如查詢需求爲:污染物排放量在特定的時間範圍內,各個區域(省、市、區縣三個級別)的排名以及各個流域(1、2、三級流域)的排名。

上述的查詢需求就能夠氛圍兩個聚合組:

  1. 根據區域維度、時間維度查詢污染物排放量;
  2. 根據流域維度、時間維度查詢污染物排放量。

若是隻使用一個聚合組,區域維度和流域維度就很產生不少組合的 Cuboid,然而這些組合對查詢毫無用處,此時就可使用兩個聚合組把區域和流域分開,這樣即可以大大減小無用的組合。

二、必要維度(Mandatory Dimension)

Mandatory 維度指的是那些老是會出現 在Where 條件或 Group By 語句裏的維度

固然必須存在不必定是顯式出如今查詢語句中,例如查詢日期是必要字段,月份、季度、年屬於它的衍生字段,那麼查詢的時候出現月份、季度、年這些衍生字段等效於出現查詢日期這個必要字段。

三、層級維度 (Hierachy Dimension)

Hierarchy 是一組有層級關係的維度,例如:國家->省->市,這裏的「國家」是高級別的維度,「省」「市」依次是低級別的維度;用戶會按高級別維度進行查詢,也會按低級別維度進行查詢,但在查詢低級別維度時,每每都會帶上高級別維度的條件,而不會孤立地審視低級別維度的數據。也就是說,用戶對於這三個維度的查詢能夠歸類爲如下三類:

  1. group by country
  2. group by country, province(等同於group by province)
  3. group by country, province, city(等同於group by country, city 或者group by city)

四、聯合維度(Joint Dimension)

有些維度每每一塊兒出現,或者它們的基數很是接近(有1:1映射關係),例如 「user_id」 和 「email」。把多個維度定義爲組合關係後,全部不符合此關係的 cuboids 會被跳過計算。

Joint Dimension (A, B) 來講,在 group by 時 A, B 最好同時出現,這樣不損失性能。但若是隻出現 A 或者 B,那麼就須要在查詢時從 group by A,B 的結果作進一步聚合運算,會下降查詢的速度。

五、Rowkeys

5.一、編碼

Kylin 以 Key-Value 的方式將 Cube 存儲到 HBase 中,HBase 的 key,也就是 Rowkey,是由各維度的值拼接而成的;爲了更高效地存儲這些值,Kylin 會對它們進行編碼和壓縮;每一個維度都可以選擇合適的編碼(Encoding)方式,默認採用的是字典(Dictionary)編碼技術;字段支持的基本編碼類型以下:

  • dict:適用於大部分字段,默認推薦使用,但在超高基狀況下,可能引發內存不足的問題;
  • boolean:適用於字段值爲true, false, TRUE, FALSE, True, False, t, f, T, F, yes, no, YES, NO, Yes, No, y, n, Y, N, 1, 0
  • integer:適用於字段值爲整數字符,支持的整數區間爲[ -2^(8N-1), 2^(8N-1)]
  • date:適用於字段值爲日期字符,支持的格式包括yyyyMMdd、yyyy-MM-dd、yyyy-MM-dd HH:mm:ss、yyyy-MM-dd HH:mm:ss.SSS,其中若是包含時間戳部分會被截斷;
  • time:適用於字段值爲時間戳字符,支持範圍爲[ 1970-01-01 00:00:00, 2038/01/19 03:14:07],毫秒部分會被忽略,time編碼適用於 time, datetime, timestamp 等類型;
  • fix_length適用於超高基場景,將選取字段的前 N 個字節做爲編碼值,當 N 小於字段長度,會形成字段截斷,當 N 較大時,形成 RowKey 過長,查詢性能降低,只適用於 varchar 或 nvarchar 類型;
  • fixed_length_hex:適用於字段值爲十六進制字符,好比 1A2BFF 或者 FF00FF,每兩個字符須要一個字節,只適用於 varchar 或 nvarchar 類型。

5.二、順序

各維度在 Rowkeys 中的順序,對於查詢的性能會產生較明顯的影響;在這裏用戶能夠根據查詢的模式和習慣,經過拖曳的方式調整各個維度在Rowkeys上的順序。推薦的順序爲:Mandatory 維度、where 過濾條件中出現頻率較多的維度、高基數維度、低基數維度。這樣作的好處是,充分利用過濾條件來縮小在 HBase 中掃描的範圍,從而提升查詢的效率。

5.三、分片

指定 ShardBy 的列,明細數據將按照該列的值分片;沒有指定 ShardBy 的列,則默認將根據全部列中的數據進行分片;選擇適當的 ShardBy 列,可使明細數據較爲均勻的分散在多個數據片上,提升並行性,進而得到更理想的查詢效率;建議選擇基數較大的列做爲 ShardBy 列,以免數據分散不均勻

六、其餘設置

  • Mandatory Cuboids: 維度組合白名單,指定須要構建的 cuboid 的維度的組合;
  • Cube Engine: Cube 構建引擎,有兩種:MapReduce 和 Spark;若是你的 Cube 只有簡單度量(SUM, MIN, MAX),建議使用 Spark;若是 Cube 中有複雜類型度量(COUNT DISTINCT, TOP_N),建議使用 MapReduce;
  • Global Dictionary:用於精確計算 COUNT DISTINCT 的字典, 它會將一個非 integer 的值轉成 integer,以便於 bitmap 進行去重;若是你要計算 COUNT DISTINCT 的列自己已是 integer 類型,那麼不須要定義 Global Dictionary; Global Dictionary 會被全部 segment 共享,所以支持在跨 segments 之間作上捲去重操做。
  • Segment Dictionary:另外一個用於精確計算 COUNT DISTINCT 的字典,與 Global Dictionary 不一樣的是,它是基於一個 segment 的值構建的,所以不支持跨 segments 的彙總計算。若是你的 cube 不是分區的或者能保證你的全部 SQL 按照 partition_column 進行 group by, 那麼你應該使用 「Segment Dictionary」 而不是 「Global Dictionary」,這樣能夠避免單個字典過大的問題。
  • Advanced Snapshot Table: 爲全局 lookup 表而設計,提供不一樣的存儲類型;
  • Advanced ColumnFamily: 若是有超過一個的 COUNT DISTINCT 或 TopN 度量, 你能夠將它們放在更多列簇中,以優化與HBase 的I/O。

6、Configuration Overwrites

Kylin 使用了不少配置參數以提升靈活性,用戶能夠根據具體的環境、場景等配置不一樣的參數進行調優;Kylin 全局的參數值可在 conf/kylin.properties 文件中進行配置;若是 Cube 須要覆蓋全局設置的話,則須要在此頁面中指定,這些配置項將覆蓋項目級別和配置文件中的默認值。

配置重寫覆蓋

7、Overview

你能夠概覽你的 cube 並返回以前的步驟進行修改,點擊 Save 按鈕完成 cube 建立。

概覽與保存

8、Planner

若是你開啓了 Cube Planner,當 Cube 保存後能夠到 Planner 標籤頁查看 Cuboid 的個數以及各個維度的組合狀況,這可以很直觀的幫助你瞭解你的維度組合狀況,若是與預想的有出入能夠隨時對 Cube 進行調整。

經過 Cube Planner 查看 Cuboid


Any Code,Code Any!

掃碼關注『AnyCode』,編程路上,一塊兒前行。

相關文章
相關標籤/搜索