增量構建應用場景
Kylin在每次Cube的構建都會從Hive中批量讀取數據,而對於大多數業務場景來說,Hive中的數據處於不斷增長的狀態。爲了支持Cube中的數據能夠不斷地得到更新,且無需重複地爲已經處理過的歷史數據構建Cube,因此對於 Cube引入了增量構建的功能
理解Cube、Cuboid與Segment的關係
Kylin將Cube劃分爲多個Segment(對應就是HBase中的一個表),每個Segment用起始時間和結束時間來標誌。Segment代表一段時間內源數據的預計算結果。一個Segment的起始時間等於它之前那個Segment的結束時間,同理,它的結束時間等於它後面那個Segment的起始時間。同一個Cube下不同的Segment除了背後的源數據不同之外,其他如結構定義、構建過程、優化方法、存儲方式等都完全相同。
一個Cube,可以包含多個Cuboid,而Segment是指定時間範圍的Cube,可以理解爲Cube的分區。對應就是HBase中的一張表。該表中包含了所有的Cuboid。
例如:以下爲針對某個Cube的Segment
Segment名稱 |
分區時間 |
HBase表名 |
201910110000000-201910120000000 |
20191011 |
KYLIN_41Z8123 |
201910120000000-201910130000000 |
20191012 |
KYLIN_5AB2141 |
201910130000000-201910140000000 |
20191013 |
KYLIN_7C1151 |
201910140000000-201910150000000 |
20191014 |
KYLIN_811680 |
201910150000000-201910160000000 |
20191015 |
KYLIN_A11AD1 |
全量構建與增量構建
全量構建
在全量構建中,Cube中只存在唯一的一個Segment,該Segment沒有分割時間的概念,也就沒有起始時間和結束時間。全量構建和增量構建各有其適用的場景,用戶可以根據自己的業務場景靈活地進行切換。對於全量構建來說,每當需要更新Cube數據的時候,它不會區分歷史數據和新加入的數據,也就是說,在構建的時候會導入並處理所有的原始數據。
增量構建
增量構建只會導入新Segment指定的時間區間內的原始數據,並只對這部分原始數據進行預計算。
全量構建和增量構建的對比
全量構建 |
增量構建 |
每次更新時都需要更新整個數據集 |
每次只對需要更新的時間範圍進行更新,因此離線計算量相對較小 |
查詢時不需要合併不同Segment的結果 |
查詢時需要合併不同Segment的結果,因此查詢性能會受影響 |
不需要後續的Segment合併 |
累計一定量的Segment之後,需要進行合併 |
適合小數據量或全表更新的Cube |
適合大數據量的Cube |
全量構建與增量構建的Cube查詢方式對比:
- 全量構建Cube
- 查詢引擎只需向存儲引擎訪問單個Segment所對應的數據,無需進行Segment之間的聚合
- 爲了加強性能,單個Segment的數據也有可能被分片存儲到引擎的多個分區上,查詢引擎可能仍然需要對單個Segment不同分區的數據做進一步的聚合
- 增量構建Cube
- 由於不同時間的數據分佈在不同的Segment之中,查詢引擎需要向存儲引擎請求讀取各個Segment的數據
- 增量構建的Cube上的查詢會比全量構建的做更多的運行時聚合,通常來說增量構建的Cube上的查詢會比全量構建的Cube上的查詢要慢一些。
對於小數據量的Cube,或者經常需要全表更新的Cube,使用全量構建需要更少的運維精力,以少量的重複計算降低生產環境中的維護複雜度。而對於大數據量的Cube,例如,對於一個包含兩年曆史數據的Cube,如果需要每天更新,那麼每天爲了新數據而去重複計算過去兩年的數據就會變得非常浪費,在這種情況下需要考慮使用增量構建
增量構建Cube過程
1、指定分割時間列
增量構建Cube的定義必須包含一個時間維度,用來分割不同的Segment,這樣的維度稱爲分割時間列(Partition Date Column)。
2、增量構建過程
- 在進行增量構建時,將增量部分的起始時間和結束時間作爲增量構建請求的一部分提交給Kylin的任務引擎
- 任務引擎會根據起始時間和結束時間從Hive中抽取相應時間的數據,並對這部分數據做預計算處理
- 將預計算的結果封裝成爲一個新的Segment,並將相應的信息保存到元數據和存儲引擎中。一般來說,增量部分的起始時間等於Cube中最後一個Segment的結束時間。
增量Cube的創建
創建增量Cube的過程和創建普通Cube的過程基本類似,只是增量Cube會有一些額外的配置要求
1、配置Model
增量構建的Cube需要指定分割時間列。例如:將日期分區字段添加到維度列中
在設置中,配置分區列,並指定日期格式
注意事項
- 注意構建Cube時,選擇的分區時間爲,起始時間(包含)、結束時間(不保存),對應了從Hive從獲取數據源的條件
INSERT OVERWRITE TABLE `kylin_intermediate_cube_order_1582ee64_45f9_cf22_bef2_e0b455efc284` SELECT
`FACT_ORDER`.`DT` as `FACT_ORDER_DT`
,`FACT_ORDER`.`USER_ID` as `FACT_ORDER_USER_ID`
,`FACT_ORDER`.`PRICE` as `FACT_ORDER_PRICE`
FROM `ITCAST_KYLIN_DW`.`FACT_ORDER` as `FACT_ORDER`
INNER JOIN `ITCAST_KYLIN_DW`.`DIM_USER` as `DIM_USER`
ON `FACT_ORDER`.`USER_ID` = `DIM_USER`.`ID`
WHERE 1=1 AND (`FACT_ORDER`.`DT` >= '20191011' AND `FACT_ORDER`.`DT` < '20191012');
2、參看Segment
3、構建 20191012、20191013的Cube數據
INSERT OVERWRITE TABLE `kylin_intermediate_cube_order_16b6b739_cf24_fa63_c9bb_f8932b8c5d15` SELECT
`FACT_ORDER`.`DT` as `FACT_ORDER_DT`
,`FACT_ORDER`.`USER_ID` as `FACT_ORDER_USER_ID`
,`FACT_ORDER`.`PRICE` as `FACT_ORDER_PRICE`
FROM `ITCAST_KYLIN_DW`.`FACT_ORDER` as `FACT_ORDER`
INNER JOIN `ITCAST_KYLIN_DW`.`DIM_USER` as `DIM_USER`
ON `FACT_ORDER`.`USER_ID` = `DIM_USER`.`ID`
WHERE 1=1 AND (`FACT_ORDER`.`DT` >= '20191012' AND `FACT_ORDER`.`DT` < '20191013');
4、查看增量構建Cube對應的Segment
REST API觸發增量構建
在Web GUI上進行的所有操作,其背後調用的都是同一套Rest API。將來可以SHELL腳本調度REST API觸發構建。
屬性 |
值 |
URL |
http://node1:7070/kylin/api/cubes/{Cube名稱}/rebuild |
請求方式 |
PUT |
RequestBody(JSON字符串) |
{"startTime":時間戳, "endTime": "時間戳", "buildType": "BUILD/MERGE/REFRESH"} |
注意:
- Kylin中Cube構建的時間採用CST(北京時間),而REST提交的時間採用的是UTC(世界標準時間)
- CST = UTC + 8
- startTime、endTime提交到Kylin,應該 +8 個小時
參考JSON:
{
"startTime": "1570838400000",
"endTime": "1570924800000",
"buildType": "BUILD"
}
時間戳轉換工具:
http://tool.chinaz.com/Tools/unixtime.aspx
Cube碎片管理
增量構建的問題
日積月累,增量構建的Cube中的Segment越來越多,該Cube的查詢性能也會越來越慢,因爲需要在單點的查詢引擎中完成越來越多的運行時聚合。爲了保持查詢性能:
- 需要定期地將某些Segment合併在一起
- 或者讓Cube根據Segment保留策略自動地淘汰那些不會再被查詢到的陳舊Segment
管理Cube碎片
上述案例,每天都會生成一個Segment,對應就是HBase中的一張表。增量構建的Cube每天都可能會有新的增量。這樣的Cube中最終可能包含上百個Segment,這將會導致Kylin性能受到嚴重的影響。
- 從執行引擎的角度來說,運行時的查詢引擎需要聚合多個Segment的結果才能返回正確的查詢結果
- 從存儲引擎的角度來說,大量的Segment會帶來大量的文件,給存儲空間的多個模塊帶來巨大的壓力,例如Zookeeper、HDFS Namenode等
因此,有必要採取措施控制Cube中Segment的數量。
手動觸發合併Segment
Kylin提供了一種簡單的機制用於控制Cube中Segment的數量:合併Segments。在Web GUI中選中需要進行Segments合併的Cube,
操作步驟:
1、單擊Action→Merge
2、選中需要合併的Segment,可以同時合併多個Segment,但是這些Segment必須是連續的
單擊提交後系統會提交一個類型爲“MERGE”的構建任務,它以選中的Segment中的數據作爲輸入,將這些Segment的數據合併封裝成爲一個新的Segment。新的Segment的起始時間爲選中的最早的Segment的起始時間,它的結束時間爲選中的最晚的Segment的結束時間。
注意事項
- 在MERGE類型的構建完成之前,系統將不允許提交這個Cube上任何類型的其他構建任務
- 在MERGE構建結束之前,所有選中用來合併的Segment仍然處於可用的狀態
- 當MERGE構建結束的時候,系統將選中合併的Segment替換爲新的Segment,而被替換下的Segment等待將被垃圾回收和清理,以節省系統資源
自動合併
手動維護Segment很繁瑣,人工成本很高,Kylin中是可以支持自動合併Segment。
在Cube Designer的“Refresh Settings”的頁面中有:
- Auto Merge Thresholds
- Retention Threshold
兩個設置項可以用來幫助管理Segment碎片。這兩項設置搭配使用這兩項設置可以大大減少對Segment進行管理的麻煩。
1、Auto Merge Thresholds
- 允許用戶設置幾個層級的時間閾值,層級越靠後,時間閾值就越大
- 每當Cube中有新的Segment狀態變爲 READY的時候,會自動觸發一次系統自動合併
- 合併策略
達到了閾值就跳過,沒有達到閾值就合併到這個閾值,沒滿足不合並。
-
- 嘗試最大一級的時間閾值,例如:針對(7天、28天)層級的日誌,先檢查能否將連續的若干個Segment合併成爲一個超過28天的大Segment
- 如果有個別的Segment的時間長度本身已經超過28天,系統會跳過Segment
- 如果滿足條件的連續Segment還不能夠累積超過28天,那麼系統會使用下一個層級的時間閾值重複尋找
- 嘗試最大一級的時間閾值,例如:針對(7天、28天)層級的日誌,先檢查能否將連續的若干個Segment合併成爲一個超過28天的大Segment
示例1 - 理解Kylin自動合併策略
- 假設自動合併閾值設置爲7天、28天
- 如果現在有A-H8個連續的Segment,它們的時間長度爲28天(A)、7天(B)、1天(C)、1天(D)、1天(E)、1天(F)、1天(G)、1天(H)
- 此時,第9個Segment I加入,時間長度爲1天。
自動合併策略爲:
1、Kylin判斷時候能將連續的Segment合併到28天這個閾值,由於Segment A已經超過28天,會被排除
2、剩下的連續Segment,所有時間加一起 B + C + D + E + F + G + H + I (7 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 14) < 28天,無法滿足28天閾值,開始嘗試7天閾值
3、跳過A(28)、B(7)均超過7天,排除
4、剩下的連續Segment,所有時間加一起 C + D + E + F + G + H + I(1 + 1 + 1 + 1 + 1 + 1 + 1 = 7)達到7天閾值,觸發合併,提交Merge任務。並構建一個Segment X(7天)
5、合併後,Segment爲:A(28天)、B(7天)、X(7天)
6、繼續觸發檢查,A(28天)跳過,B + X(7 + 7 = 14)< 28天,不滿足第一閾值,重新使用第二閾值觸發
7、跳過B、X,嘗試終止
2、示例:配置自動合併4天的Segment
操作步驟:
1、配置自動合併閾值爲(4、28)
2、分別按照天構建分區Cube
3、自動觸發合併Segment構建
自動刪除Segment
自動合併是將多個Segment合併爲一個Segment,以達到清理碎片的目的。自動刪除Segment則是及時清理不再使用的Segment。
在很多場景中,只會對過去一段時間內的數據進行查詢,例如:
- 對於某個只顯示過去1年數據的報表
- 支撐它的Cube其實只需要保留過去一年類的Segment即可
- 由於數據在Hive中已經存在備份,則無需在Kylin中備份超過一年的歷史數據
可以將Retention Threshold設置爲365。每當有新的Segment狀態變爲READY的時候,系統會檢查每一個Segment。如果它的結束時間距離最晚的一個Segment的結束時間已經大於等於“Retention Threshold”,那麼這個Segment將被視爲無需保留。系統會自動地從Cube中刪除這個Segment。
需求:
- 配置保留Segment爲2天,分別構建增量Segment,測試Segment保留情況
操作步驟:
1、在Cube中設置Retension Threshold爲2
2、重新構建Cube
3、測試超過指定保留時間的Segment,是否被自動移除