employee實事表纔會參與真正運算,dept維表不參與
model模型分以下2種:
① 當所有維表都直接連接到“ 事實表”上時,整個圖解就像星星一樣,故將該模型稱爲星形模型
星狀模型是直接關聯;
② 當有一個或多個維表沒有直接連接到事實表上,而是通過其他維表連接到事實表上時,其圖解就像多個雪花連接在一起,故稱雪花模型。
雪花模型是主從間接關聯;
創建分區表:
create table emp_partition(empno int, ename string, job string, mgr int, sal double, comm double, deptno int) partitioned by(hire_date string) row format delimited fields terminated by '\t'; 動態分區應該手動開啓: set hive.exec.dynamic.partition.mode=nonstrict;
動態插入數據 insert into table emp_partition partition(hire_date) select empno, ename, job, mgr, sal, comm, deptno, hiredate from emp;
1. 創建module項目名稱
project_partition
主表--FactTable: default.emp_partition
從表--Add Lookup Table:emp_partition inner join dept
維度--Select dimension columns:EMP_PARTITION-->job,mgr,hire_date ; DEPT-->dname
度量--Select measure columns: EMP_PARTITION--->sal
2. 構建Data Model
Data Model 主要是構建整體的數據模型,無論你的數據是星型模型或者是雪花模型,需要在這個地方建立數據表之間的關係。
2.1. 選擇事實表與維度表
建立數據模型的第一步是選擇事實表,選擇完成後點擊 “Add Lookup Table” 按鈕設置事實表與維度表之間的關係。
2.2. 建立數據關係
對 “Add Lookup Table” 頁面的幾點說明:
- 數據關係不僅僅是事實表與維度表之間(星型模型),維度表和維度表之間(雪花模型)也可以建立聯繫;
- 表與表之間的連接添加有三種:“Left Join”、“Inner Join”、“Right Join”;
Skip snapshot for this lookup table
選項指的是是否跳過生成 snapshotTable,由於某些 Lookup 表特別大(大於 300M),如果某一個維度的基數比較大 ,可能會導致內存出現 OOM,所以在創建 snapshotTable 的時候會限制原始表的大小不能超過配置的一個上限值(kylin.snapshot.max-mb
,默認值300);- 跳過構建 snapshot 的 lookup 表將不能搜索,同時不支持設置爲衍生維度(Derived);
- 大部分情況下都是使用 “Left Join”,其他兩種 Join 方式不是很常用。
每一個 Snapshot 是和一個 Hive 維度表對應的,生成的過程是:
- 從原始的hive維度表中順序得讀取每一行每一列的值;
- 使用 TrieDictionary 方式對這些所有的值進行編碼(一個值對應一個 Id);
- 再次讀取原始表中每一行的值,將每一列的值使用編碼之後的 Id 進行替換,得到了一個只有 Id 的新表;
- 同時保存這個新表和 Dictionary 對象(Id 和值的映射關係)就能夠保存整個維度表;
- Kylin 將這個數據存儲到元數據庫中。
2.3. 完成表關係構建
通過上述的操作即可將事實表以及維度表聯繫起來,構成一個數據模型。
點擊了Skip snapshot就會進行limit限制; 否則就是 Table kind --> Normal
2.4. Dimensions
在 Dimensions 頁面選擇可能參與計算的維度,這裏被選擇的只是在 Cube 構建的時候擁有被選擇資格的維度,並不是最後參與 Cube 構建的維度,推薦將維度表中的字段都選擇上。
一般而言,日期、商品種類、區域等會作爲維度。
2.5. Measures
在 Measures 頁面選擇可能用於計算的度量。
一般而言,銷售額、流量、溫溼度等會作爲度量。
2.6. Settings
在 Settings 頁面可以設置分區以及過濾條件,其中分區是爲了系統可以進行增量構建而設計的,目前 Kylin 支持基於日期的分區,在 “Partition Date Column” 後面選擇事實表或者維度表中的日期字段,然後選擇
日期格式即可;過濾條件設置後,Kylin 在構建的時候會選擇符合過濾條件的數據進行構建。
需要注意的幾點:
- 時間分區列可以支持日期或更細粒度的時間分區;
- 時間分區列支持的數據類型有
time/date/datetime/integer
等; - 過濾條件不需要寫
WHERE
; - 過濾條件不能包含日期維度。
與動量cute做呼應,分區必須是日期;選分區表:summary_time
2.7. Save
最後保存即可完成 Model 的創建,可以打開 Model 中的 Visualization 標籤頁查詢模型的表連接情況。
3. 構建cube
3.1. Dimensions
Dimensions是維度選擇界面,從數據模型的維度中選擇一些列作爲 Cube 的維度,這裏的設置會影響到生成的 Cuboid 數量,進而影響 Cube 的數據量大小。
在選擇維度時,每一個維度列可以作爲普通維度(Normal),也可以作爲衍生維度(Derived)。相對於普通維度來說,衍生維度並不參與維度的 Cuboid,衍生維度對應的外鍵(FK)參與維度 Cuboid,從而
降低 Cuboid 數。在查詢時,對衍生維度的查詢會首先轉換爲對外鍵所在維度的查詢,因此會犧牲少量性能(大部分情況可以接受)。
維度的選擇
- 作爲 Cube 的維度需要滿足下面的條件:可能存在於 where 條件中或者 groupBy 中的維度;
- 事實表(Fact Table)只選擇參與查詢的字段,不參與查詢的一定不要勾選(即便是外鍵);
- 維度表(Lookup Table)中的主鍵與事實表的外鍵一一對應,推薦勾選事實表的外鍵,維度表的主鍵勾選後選擇爲衍生(Derived)維度;
- 對於星型模型而言,維度表的字段往往可以全部爲衍生字段;
- 對於雪花模型而言,如果維度表存在子表,則維度表對於子表的外鍵推薦作爲普通(Normal)維度。
特別注意項
- 表連接的字段並非一定要參與 Cuboid 計算;
- 表連接的字段如果沒有被勾選,且其外鍵表中沒有任何字段作爲衍生維度,則該表連接字段是不會參與 Cuboid 的;
- 一旦被設置爲 Normal 類型,則一定會參與 Cuboid 計算;
- 如果維度表存在層級(例如省市縣、日月年等),則推薦分層級的相關字段選擇爲普通(Normal)維度。
3.2. Measures
維度選擇完成後,需要選擇度量聚合的方式,比較常規的聚合方式有:COUNT、SUM、MIN、MAX、PERCENTILE,下面將詳細介紹其他幾種聚合方式。
①TOP_N
Top-N 度量,旨在在 Cube 構建的時候預計算好需要的 Top-N;在查詢階段,就可以迅速的獲取並返回 Top-N 記錄,這樣查詢性能就遠遠高於沒有 Top-N 預計算結果的 Cube。
Top-N 中 Group By 的該如何選擇?
例如:全國二氧化碳污染物總和的省份排名,結果是省份排名,需要測量的是污染物的總和,因此 Group By 需要設置爲 污染物類型。
Return Type 中的 Top N 是什麼意思?
TOP N 表示最終獲取的前 N 名的排序是比較準確的,例如 TOP 10 表示最終的前 10 名是比較準確的(維度的基數非常大時存在誤差),但是不代表只能取前 10 個(Limit 10),可以使用其他數字,例如 Limit 500,只是返回更多內容時,精準度沒有保證。
TOP-N 的存儲
使用 TOP-N 時,排序度量字段和 Group By 字段會組合在一起,形成一個字段進行存儲,用戶需要 Top 100 的結果,Kylin 對於每種組合條件值,保留 Top 5000 (50倍)的紀錄, 並供以後再次合併。
② Count_Distinct
Count_Distinct 度量有兩個實現:
- 近似實現:基於 HyperLogLog 算法,可選擇接受的錯誤率(從9.75% 到 1.22%),低錯誤率需要更多存儲;
- 精確實現:基於 Bitmap(位圖)算法,對於數據型爲 tinyint、smallint 和 int 的數據,將把數據對應的值直接打入位圖;對於數據型爲 long,string 和其他的數 據,將它們編碼成字符串放入字典,然後再將對應的值打入位圖。返回的度量結果是已經序列化的位圖數據,而不僅是計算的值。這確保了不同的 segment 中,甚至跨越不同的 segment 來上卷,結果也是正確的。
越精確消耗的存儲空間越大,大多數場景下 HyperLogLog 的近似實現即可滿足需求。
④ EXTEND_COLUMN
在分析場景中,經常存在對某個 id 進行過濾,但查詢結果要展示爲 name 的情況,比如user_id
和user_name
。這類問題通常有三種解決方式:
- 將 id 和 name 都設置爲維度,查詢語句類似
select name, count(*) from table where id = 1 group by id,name
,這種方式的問題是會導致維度增多,導致預計算結果膨脹; - 將 id 和 name 都設置爲維度,並且將兩者設置爲聯合維度(Joint Dimensions),這種方式的好處是保持維度組合數不會增加,但限制了維度的其它優化,比如 id 不能再被設置爲強制維度或者層次維度;
- 將 id 設置爲維度,name 設置爲特殊的 Measure,類型爲 Extended Column,這種方式既能保證過濾 id 且查詢 name 的需求,同時也不影響 id 維度的進一步優化。
3.3 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
默認爲分區起始時間。
3.4 Advanced Setting
高級設置主要用於 Cuboid 的剪枝優化,通過聚合組(Aggregation Group)、必要維度(Mandatory Dimension)、層級維度(Hierarchy Dimension)、聯合維度(Joint Dimension)等方式,可以使得 Cuboid
的組合在預期範圍內。
① 聚合組(Aggregation Group)
根據查詢的維度組合,可以劃分出維度組合大類,這些大類在 Kylin 裏面被稱爲聚合組。例如查詢需求爲:污染物排放量在特定的時間範圍內,各個區域(省、市、區縣三個級別)的排名以及各個流域(一、二、三級流域)的排名。
上述的查詢需求就可以氛圍兩個聚合組:
- 根據區域維度、時間維度查詢污染物排放量;
- 根據流域維度、時間維度查詢污染物排放量。
如果只使用一個聚合組,區域維度和流域維度就很產生很多組合的 Cuboid,然而這些組合對查詢毫無用處,此時就可以使用兩個聚合組把區域和流域分開,這樣便可以大大減少無用的組合。
② 必要維度(Mandatory Dimension)
Mandatory 維度指的是那些總是會出現 在Where 條件或 Group By 語句裏的維度。
當然必須存在不一定是顯式出現在查詢語句中,例如查詢日期是必要字段,月份、季度、年屬於它的衍生字段,那麼查詢的時候出現月份、季度、年這些衍生字段等效於出現查詢日期這個必要字段。
③ 層級維度 (Hierachy Dimension)
Hierarchy 是一組有層級關係的維度,例如:國家->省->市,這裏的“國家”是高級別的維度,“省”“市”依次是低級別的維度;用戶會按高級別維度進行查詢,也會按低級別維度進行查詢,但在查詢低級別維度時,
往往都會帶上高級別維度的條件,而不會孤立地審視低級別維度的數據。也就是說,用戶對於這三個維度的查詢可以歸類爲以下三類:
- group by country
- group by country, province(等同於group by province)
- 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
的結果做進一步聚合運算,會降低查詢的速度。
3.5 Rowkeys
編碼
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 類型。
順序
各維度在 Rowkeys 中的順序,對於查詢的性能會產生較明顯的影響;在這裏用戶可以根據查詢的模式和習慣,通過拖曳的方式調整各個維度在Rowkeys上的順序。推薦的順序爲:Mandatory 維度、where 過濾
條件中出現頻率較多的維度、高基數維度、低基數維度。這樣做的好處是,充分利用過濾條件來縮小在 HBase 中掃描的範圍,從而提高查詢的效率。
分片
指定 ShardBy 的列,明細數據將按照該列的值分片;沒有指定 ShardBy 的列,則默認將根據所有列中的數據進行分片;選擇適當的 ShardBy 列,可以使明細數據較爲均勻的分散在多個數據片上,提高並行性,
進而獲得更理想的查詢效率;建議選擇基數較大的列作爲 ShardBy 列,以避免數據分散不均勻。
3.6、其他設置
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。
3.7 Configuration Overwrites
Kylin 使用了很多配置參數以提高靈活性,用戶可以根據具體的環境、場景等配置不同的參數進行調優;Kylin 全局的參數值可在 conf/kylin.properties
文件中進行配置;如果 Cube 需要覆蓋全局設置的話,則
需要在此頁面中指定,這些配置項將覆蓋項目級別和配置文件中的默認值。
3.8 Overview
你可以概覽你的 cube 並返回之前的步驟進行修改,點擊 Save
按鈕完成 cube 創建。
3.9 Planner
如果你開啓了 Cube Planner,當 Cube 保存後可以到 Planner 標籤頁查看 Cuboid 的個數以及各個維度的組合情況,這能夠很直觀的幫助你瞭解你的維度組合情況,如果與預想的有出入可以隨時對 Cube 進行調整。
4. Build Cube
Cube已經創建好了,就可以Build了。
Action下拉框選項顯示Cube操作有:
(1)Drop
刪除此Cube。
(2)Edit
如果發現Cube設計有問題,可以選擇Edit進行修改。
(3)Build
執行構建Cube操作,如果是增量Cube,則需要指定開始和結束時間,這兩個時間區間標識本次構建的segment的數據源只選擇這個時間範圍內的數據。對於Build操作而言,startTime是不需要的,因爲它總是會選擇最後一個segment的結束時間作爲當前segment的起始時間。
由於Kylin基於預計算的方式提供數據查詢,構建操作是指將原始數據(存儲在Hadoop中,通過Hive獲取)轉換成目標數據(存儲在HBase中)的過程。
(4)Refresh
對某個已經構建過的Cube Segment,重新從數據源抽取數據並構建,從而獲得更新。
(5)Merge
對於增量Cube,即設置分區字段,這樣的Cube就可以進行多次Build,每一次的Build會生成一個segment,每一個segment對應着一個時間區間的Cube,這些segment的時間區間是連續並且不重合的,對於擁有多個segment的cube可以執行merge,相當於將一段時間區間內部的segment合併成一個,可以減少Segment的數量,同時減少Cube的存儲空間。
(6)Enable
使Cube生效。如果Cube處於disabled狀態時改變Cube Schema,那麼Cube的所有segments將因爲Data和Schema不匹配而被丟棄。
(7)Disabled
使Cube失效,此時無法再通過SQL查詢Cube數據。如果再執行Enable的話,就可以繼續查詢了。
(8)Purge
將Cube的所有Cube Segment刪除。
(9)Clone
如果我們想保留原先已經創建好的Cube,但是又想創建一個類似的Cube,那麼此時就可以使用Clone功能重新克隆一個一模一樣的Cube,然後對這個Cube進行修改等操作。
對於Cube不同的狀態,能夠執行的Action也是不同的,比如Cube處於Ready狀態時可以執行的Action
如果Cube的狀態變成“Ready”意味着已經準備好對外SQL查詢服務。
下面我們切換到Monitor界面,查看剛纔提交的Job。
等作業執行完成後,Monitor中的Job狀態顯示爲FINISHED,並且Progress顯示爲100%。
Job的幾種狀態:
- NEW:新任務,剛剛創建。
- PENDING:等待被調度執行的任務。
- RUNNING:正在運行的任務。
- FINISHED:正常完成的任務(終態)。
- ERROR:執行出錯的任務。
- DISCARDED:丟棄的任務(終態)。
Build Cube完成後,我們可以從Cube的詳細信息中看到HBase的信息了(Build Cube之前沒有任何信息)。
此Cube數據存儲在HBase的表KYLIN_C37CNMSYXA中,2個Region,小於1MB,並且包含開始和結束時間。我們登錄到HBase環境中查看:
hbase(main):001:0> list TABLE KYLIN_AMLAK436TI KYLIN_C37CNMSYXA kylin_metadata 3 row(s) in 0.3120 seconds
=> ["KYLIN_AMLAK436TI", "KYLIN_C37CNMSYXA", "kylin_metadata"] hbase(main):002:0>
可以看到表KYLIN_C37CNMSYXA是存在的。
5. Kylin查詢
在New Query中輸入查詢語句並Submit
數據圖表展示及可以導出