天天看點

Apache Kylin優化之—Cube的進階設定

随着次元數目的增加,cuboid 的數量會爆炸式地增長。為了緩解 cube 的建構壓力,apache kylin 引入了一系列的進階設定,幫助使用者篩選出真正需要的 cuboid。這些進階設定包括聚合組(aggregation group)、聯合次元(joint dimension)、層級次元(hierachy dimension)和必要次元(mandatory dimension)等。”

衆所周知,apache kylin 的主要工作就是為源資料建構 n 個次元的 cube,實作聚合的預計算。理論上而言,建構 n 個次元的 cube 會生成 2n 個 cuboid, 如圖 1 所示,建構一個 4 個次元(a,b,c, d)的 cube,需要生成 16 個cuboid。

Apache Kylin優化之—Cube的進階設定

(圖1)

随着次元數目的增加 cuboid 的數量會爆炸式地增長,不僅占用大量的存儲空間還會延長 cube 的建構時間。為了緩解 cube 的建構壓力,減少生成的 cuboid 數目,apache kylin 引入了一系列的進階設定,幫助使用者篩選出真正需要的 cuboid。這些進階設定包括聚合組(aggregation group)、聯合次元(joint dimension)、層級次元(hierachy dimension)和必要次元(mandatory dimension)等,本系列将深入講解這些進階設定的含義及其适用的場景。

聚合組(aggregation group)

使用者根據自己關注的次元組合,可以劃分出自己關注的組合大類,這些大類在 apache kylin 裡面被稱為聚合組。例如圖 1 中展示的 cube,如果使用者僅僅關注次元 ab 組合和次元 cd 組合,那麼該 cube 則可以被分化成兩個聚合組,分别是聚合組 ab 和聚合組 cd。如圖 2 所示,生成的 cuboid 數目從 16 個縮減成了 8 個。

Apache Kylin優化之—Cube的進階設定

(圖2)

使用者關心的聚合組之間可能包含相同的次元,例如聚合組 abc 和聚合組 bcd 都包含次元 b 和次元 c。這些聚合組之間會衍生出相同的 cuboid,例如聚合組 abc 會産生 cuboid bc,聚合組 bcd 也會産生 cuboid bc。這些 cuboid不會被重複生成,一份 cuboid 為這些聚合組所共有,如圖 3 所示。

Apache Kylin優化之—Cube的進階設定

(圖3)

有了聚合組使用者就可以粗粒度地對 cuboid 進行篩選,擷取自己想要的次元組合。

聚合組應用執行個體

假設建立一個交易資料的 cube,它包含了以下一些次元:顧客 id buyer_id 交易日期 cal_dt、付款的方式 pay_type 和買家所在的城市 city。有時候,分析師需要通過分組聚合 city、cal_dt 和 pay_type 來獲知不同消費方式在不同城市的應用情況;有時候,分析師需要通過聚合 city 、cal_dt 和 buyer_id,來檢視顧客在不同城市的消費行為。在上述的執行個體中,推薦建立兩個聚合組,包含的次元和方式如圖 4 :

Apache Kylin優化之—Cube的進階設定

(圖4)

聚合組 1: [cal_dt, city, pay_type]

聚合組 2: [cal_dt, city, buyer_id]

在不考慮其他幹擾因素的情況下,這樣的聚合組将節省不必要的 3 個 cuboid: [pay_type, buyer_id]、[city, pay_type, buyer_id] 和 [cal_dt, pay_type, buyer_id] 等,節省了存儲資源和建構的執行時間。

case 1:

select cal_dt, city, pay_type, count(*) from table group by cal_dt, city, pay_type 則将從 cuboid [cal_dt, city, pay_type] 中擷取資料。

case2:

select cal_dt, city, buy_id, count(*) from table group by cal_dt, city, buyer_id 則将從 cuboid [cal_dt, city, pay_type] 中擷取資料。

case3 如果有一條不常用的查詢:

select pay_type, buyer_id, count(*) from table group by pay_type, buyer_id 則沒有現成的完全比對的 cuboid。

此時,apache kylin 會通過線上計算的方式,從現有的 cuboid 中計算出最終結果。

聯合次元(joint dimension)

使用者有時并不關心次元之間各種細節的組合方式,例如使用者的查詢語句中僅僅會出現 group by a, b, c,而不會出現 group by a, b 或者 group by c 等等這些細化的次元組合。這一類問題就是聯合次元所解決的問題。例如将次元 a、b 和 c 定義為聯合次元,apache kylin 就僅僅會建構 cuboid abc,而 cuboid ab、bc、a 等等cuboid 都不會被生成。最終的 cube 結果如圖5所示,cuboid 數目從 16 減少到 4。

Apache Kylin優化之—Cube的進階設定

(圖5)

聯合次元應用執行個體

假設建立一個交易資料的cube,它具有很多普通的次元,像是交易日期 cal_dt,交易的城市 city,顧客性别 sex_id 和支付類型 pay_type 等。分析師常用的分析方法為通過按照交易時間、交易地點和顧客性别來聚合,擷取不同城市男女顧客間不同的消費偏好,例如同時聚合交易日期 cal_dt、交易的城市 city 和顧客性别 sex_id來分組。在上述的執行個體中,推薦在已有的聚合組中建立一組聯合次元,包含的次元群組合方式如圖6:

Apache Kylin優化之—Cube的進階設定

(圖6)

聚合組:[cal_dt, city, sex_id,pay_type]

聯合次元: [cal_dt, city, sex_id]

case 1:

select cal_dt, city, sex_id, count(*) from table group by cal_dt, city, sex_id 則它将從cuboid [cal_dt, city, sex_id]中擷取資料

case2如果有一條不常用的查詢:

select cal_dt, city, count(*) from table group by cal_dt, city 則沒有現成的完全比對的 cuboid,apache kylin 會通過線上計算的方式,從現有的 cuboid 中計算出最終結果。

層級次元(hierarchy dimension)

使用者選擇的次元中常常會出現具有層級關系的次元。例如對于國家(country)、省份(province)和城市(city)這三個次元,從上而下來說國家/省份/城市之間分别是一對多的關系。也就是說,使用者對于這三個次元的查詢可以歸類為以下三類:

group by country

group by country, province(等同于group by province)

group by country, province, city(等同于 group by country, city 或者group by city)

以圖7所示的 cube 為例,假設次元 a 代表國家,次元 b 代表省份,次元 c 代表城市,那麼abc 三個次元可以被設定為層級次元,生成的cube 如圖7所示。

Apache Kylin優化之—Cube的進階設定

(圖7)

例如,cuboid [a,c,d]=cuboid[a, b, c, d],cuboid[b, d]=cuboid[a, b, d],因而 cuboid[a, c, d] 和 cuboid[b, d] 就不必重複存儲。

圖8展示了 kylin 按照前文的方法将備援的cuboid 剪枝進而形成圖 2 的 cube 結構,cuboid 數目從 16 減小到 8。

Apache Kylin優化之—Cube的進階設定

(圖8)

層級次元應用執行個體

假設一個交易資料的 cube,它具有很多普通的次元,像是交易的城市 city,交易的省 province,交易的國家 country, 和支付類型 pay_type等。分析師可以通過按照交易城市、交易省份、交易國家和支付類型來聚合,擷取不同層級的地理位置消費者的支付偏好。在上述的執行個體中,建議在已有的聚合組中建立一組層級次元(國家country/省province/城市city),包含的次元群組合方式如圖9:

Apache Kylin優化之—Cube的進階設定

(圖9)

聚合組:[country, province, city,pay_type]

層級次元: [country, province, city]

case 1 當分析師想從城市次元擷取消費偏好時:

select city, pay_type, count(*) from table group by city, pay_type 則它将從 cuboid [country, province, city, pay_type] 中擷取資料。

case 2 當分析師想從省級次元擷取消費偏好時:

select province, pay_type, count(*) from table group by province, pay_type 則它将從cuboid [country, province, pay_type] 中擷取資料。

case 3 當分析師想從國家次元擷取消費偏好時:

select country, pay_type, count(*) from table group by country, pay_type 則它将從cuboid [country, pay_type] 中擷取資料。

case 4 如果分析師想擷取不同粒度地理次元的聚合結果時:

無一例外都可以由圖 3 中的 cuboid 提供資料 。

例如,select country, city, count(*) from table group by country, city 則它将從 cuboid [country, province, city] 中擷取資料。

必要次元 (mandatory dimension)

使用者有時會對某一個或幾個次元特别感興趣,所有的查詢請求中都存在group by這個次元,那麼這個次元就被稱為必要次元,隻有包含此次元的cuboid會被生成(如圖10)。

Apache Kylin優化之—Cube的進階設定

(圖10)

以圖 1中的cube為例,假設次元a是必要次元,那麼生成的cube則如圖11所示,次元數目從16變為9。

Apache Kylin優化之—Cube的進階設定

(圖11)

必要次元應用執行個體

假設一個交易資料的cube,它具有很多普通的次元,像是交易時間order_dt,交易的地點location,交易的商品product和支付類型pay_type等。其中,交易時間就是一個被高頻作為分組條件(group by)的次元。 如果将交易時間order_dt設定為必要次元,包含的次元群組合方式如圖12:

Apache Kylin優化之—Cube的進階設定

(圖12)

系列總結

根據本系列的原理介紹,在kylin的進階設定中,使用者可以根據查詢需求對cube建構預計算的結果進行優化(剪枝),進而減少占用的存儲空間。 而優化得當的cube可以在占用盡量少的存儲空間的同時提供極強的查詢性能。

本文作者:佚名

來源:51cto