官方教程請參考:http://kylin.apache.org/cn/
參考文章:https://www.cnblogs.com/honey01/p/8351145.html
總結:
kylin是一個olap引擎
(1)首先kylin從先建立一個model(包括維度,度量,及join的方式,時間列的選擇用於根據時間段查詢)
時間列的格式有規定
(2)然後創建cube,創建cube的流程如下:
(3)cobe包括多個cobeid,每個cobeid爲一組維度的組合
(4)他只是從數據源抽取數據,然後根據 事先設置好的維度進行維度組合(默認爲全維度,可以根據維度規則進行剪枝優化防止維度爆炸),然後根據統計(sum,count,max等)的度量算好在每一個維度的值,存入hbase,把維度組合作爲rowkey,統計類型+字段名作爲列族或者列,把統計值作爲value來進行存儲。使用select查詢時,就只能使用預先構建好的cube中存在的統計方法及字段進行查詢,這樣查詢的數據就是hbase中的數據,所有的cube都存在hbase,查詢時會把 sql語言轉換爲hbase查詢語言,注意這裏的sql 不是完全和mysql或者oracle的sql完全相同,具體的sql中的方法請參考官方教程http://kylin.apache.org/cn/docs/tutorial/sql_reference.html
(5)select的字段只能是cube中存在的維度,或者sum(a),max(a)等,不能是單個度量字段如:select a from xx,注意a表示度量字段
(6)關於 group by,order by,where 條件或者分組語句後面跟的字段必須是cube中設置好的維度,或者 select max(a) as a_max中的a_max。不能是單個度量字段如 where a>10,會報錯,hbase中沒有這個關係或者字段,所以預先設置cube的時候必須要針對某個特定場景進行設置,不能要求通用多個場景
(7)關於維度爆炸,如果有3個維度,默認的全維度爲2的3次方=8種組合,若不進行維度則會產生維度爆炸
(8)關於超基數維,若一個維度有100萬種以上不相同的數據,則稱爲超基數維度,超基數維度會導致hbase的rowkey成倍增長
(9)關於實際中遇到的問題,查詢select count(*) from table1,結果爲1000條,但是查詢select * from table1只有5條?原因如下:
kylin默認有一個度量count,所以查詢count的時候定位到某個列族-列,此列的值就是數據源的總的記錄數(預先計算好的)
而select * from table1則是查詢的group by 所有的維度。
(10)如何同時作爲維度,又是度量?
在cube的創建度量的時候,選擇 also show dimensions就會顯示所有度量
(11)最後生成的維度,可通過以下方式查看,可以看到生成了三個維度,鼠標放上去可以看到當前維度的組成
關於維度在hbase中的存儲及各種維度的構建,以及優化防止維度爆炸的方法請參考以下:
維度優化
爲什麼需要維度優化
因爲如果不進行任何維度優化,直接將所有的維度放在一個聚集組裏,Kylin就會計算所有的維度組合(cuboid)。
比如,有12個維度,Kylin就會計算2的12次方即4096個cuboid,實際上查詢可能用到的cuboid不到1000個,甚至更少。 如果對維度不進行優化,會造成集羣計算和存儲資源的浪費,也會影響cube的build時間和查詢性能,所以我們需要進行cube的維度優化。
當你在保存cube時遇到下面的異常信息時,意味1個聚集組的維度組合數已經大於 4096 ,你就必須進行維度優化了。
如何計算1個聚集組的維度組合數
當有層次維度時,公式如下:
(hierarchy.size() + 1) * hierarchyDimsList.size() * (1 << jointDimsList.size()) * (1 << normalDims.size())
當沒有層次維度時,公式如下:
1 << jointDimsList.size()) * (1 << normalDims.size()
hierarchyDimsList.size(): 層次維度的個數。
hierarchy.size(): 每個層次維度包含的維度個數。
jointDimsList.size(): 聯合維度的個數。
normalDims.size(): 正常維度的個數,即不是強制維度,層次維度,聯合維度的維度數目。
如何進行維度優化
首先請確認你設置的cube維度都是你查詢時會使用到的。
目前Kylin可以使用的維度優化手段有以下幾種:
- 聚集組
- 衍生緯度
- 強制維度
- 層次維度
- 聯合維度
- Extended Column
下文會詳細介紹以上維度優化手段的基本概念,以及何時使用這些優化手段。
聚集組
聚集組:用來控制哪些cuboid需要計算。
適用場景:不是只需要計算base cuboid的情況下,都需要聚集組。
注意事項:一個維度可以出現在多個聚集組中,但是build期間只會計算一次。
如果不設置聚集組,默認情況下只會計算 base cuboid。
聚集組不宜太多。
衍生維度
衍生維度:維表中可以由主鍵推導出值的列可以作爲衍⽣維度。
使用場景:以星型模型接入時。例如用戶維表可以從userid推導出用戶的姓名,年齡,性別。
優化效果:維度表的N個維度組合成的cuboid個數會從2的N次方降爲2。
圖示:
強制維度
強制維度:所有cuboid必須包含的維度,不會計算不包含強制維度的cuboid。
適用場景:可以將確定在查詢時一定會使用的維度設爲強制維度。例如,時間維度。
優化效果:將一個維度設爲強制維度,則cuboid個數直接減半。
圖示:
層次維度
層次維度:具有一定層次關係的維度。
使用場景:像年,月,日;國家,省份,城市這類具有層次關係的維度。
優化效果:將N個維度設置爲層次維度,則這N個維度組合成的cuboid個數會從2的N次方減少到N+1。
圖示:
聯合維度
聯合維度:將幾個維度視爲一個維度。
適用場景: 1 可以將確定在查詢時一定會同時使用的幾個維度設爲一個聯合維度。
2 可以將基數很小的幾個維度設爲一個聯合維度。
3 可以將查詢時很少使用的幾個維度設爲一個聯合維度。
優化效果:將N個維度設置爲聯合維度,則這N個維度組合成的cuboid個數會從2的N次方減少到1。
Extended Column
在OLAP分析場景中,經常存在對某個id進行過濾,但查詢結果要展示爲name的情況,比如user_id和user_name。這類問題通常有三種解決方式:
a. 將ID和Name都設置爲維度,查詢語句類似
select name, count(*) from table where id = 1 group by id,name
。這種方式的問題是會導致維度增多,導致預計算結果膨脹;b. 將id和name都設置爲維度,並且將兩者設置爲聯合。這種方式的好處是保持維度組合數不會增加,但限制了維度的其它優化,比如ID不能再被設置爲強制維度或者層次維度;
c. 將ID設置爲維度,Name設置爲特殊的Measure,類型爲Extended Column。這種方式既能保證過濾id且查詢name的需求,同時也不影響id維度的進一步優化。
所以此類需求我們推薦使用 Extended Column。
HBase Rowkey順序
簡單的講,查詢頻率越高的維度在Rowkey中的順序需要越靠前。
cube在hbase中的存儲
全維度構建
假設一張表有3個字段name,age,sex,那麼當通過kylin構建這張表的cube時,hbase的表結構如下所示。注意本示例沒有度量字段,value表示記錄條數累計,代表count(*),度量如果存在那麼也是存儲在value的位置,可以手動配置cf。
通過圖1很明顯的可以看到,kylin將每個維度的所有基數都枚舉了出來,並通過組合的方式構建出hbase的rowkey,另外將組合對應的記錄數做預統計保存在value中,對應hbase表中的一個cf:c。
當維度基數很大的時候,那麼構建cube會稱爲災難,所以kylin提供了cube的組合模式來減少cube的總維度組合。這裏相關概念可以參考《kylin介紹》,下面直接對不同的模式進行案例分析。
aggregate group
意思是多少幾個維度可以任一組合
假設圖1中的cube配置aggregate group爲2,那麼構建出的cube相比全維度組合構建剪去了3個維度組合的部分,參數圖2
mandatory
假設圖1中的維度name是必要維度,那麼構建出的hbase結構參考圖3
joint
假設圖1中name和sex維度是joint關係,那麼構建出的hbase結構如圖4
Hierarchy
繼承關係比較好理解,這裏就不展示了: )