kylin-增量構建Cube

1、全量和增量的區別

對於全量構建來說,每當需要更新Cube數據的時候,它不會區分歷史數據和新加入的數據,也就是說,在構建的時候會導入並處理所有的原始數據。
我們將Cube劃分爲多個Segment,每個Segment用起始時間和結束時間來標誌。Segment代表一段時間內源數據的預計算結果。增量構建只會導入新Segment指定的時間區間內的原始數據,並只對這部分原始數據進行預計算。
在這裏插入圖片描述
最後,我們可以得到這樣的結論:對於小數據量的Cube,或者經常需要全表更新的Cube,使用全量構建需要更少的運維精力,以少量的重複計算降低生產環境中的維護複雜度。而對於大數據量的Cube,例如,對於一個包含兩年曆史數據的Cube,如果需要每天更新,那麼每天爲了新數據而去重複計算過去兩年的數據就會變得非常浪費,在這種情況下需要考慮使用增量構建。

2、增量構建的前提

並非所有的Cube都適用於增量構建,Cube的定義必須包含一個時間維度,用來分割不同的Segment,我們將這樣的維度稱爲分割時間列(Partition Date Column)。

· Model層面的設置:
在Model Designer的最後一步Settings會添加分割時間列,如圖:
在這裏插入圖片描述
補充:Has aseparate”time of the day“column選項的作用:
在一些用戶場景中,年月日和時分秒並不體現在同一個列上,例如在用戶的事實表上有兩個列,分別是“日期”和“時間”,分別保存記錄發生的日期(年月日)和時間(時分秒),對於這樣的場景,允許用戶指定一個額外的分割時間列來指定除了年月日之外的時分秒信息。爲了區分,我們將之前的分割時間列稱爲常規分割時間列,將這個額外的列稱爲補充分割時間列。在勾選了“Has aseparate”time of the day“column?”選項之後,用戶可以選擇一個符合時分秒時間格式的列作爲補充的分割時間列。

· Cube層面的設置
在Cube Designer的“Refresh Settings”中。包含“Auto Merge Thresholds”、“Retention Threshold”和“Partition StartDate”。
在這裏插入圖片描述
“Partition Start Date”是指Cube默認的第一個Segment的起始時間。同一個Model下不同的Cube可以指定不同的起始時間
“Auto Merge Thresholds”用於指定Segment自動合併的閾值,
“Retention Threshold”則用於指定將過期的Segment自動拋棄

3、增量構建的觸發

在Web GUI的Model頁面中,選中想要增量構建的Cube,單擊Action→Build。
不同於全量構建,增量構建的Cube會在此時彈出對話框讓用戶選擇“End Date”,目前Kylin要求增量Segment的起始時間等於Cube中最後一個Segment的結束時間,因此當我們爲一個已經有Segment的Cube觸發增量構建時,“Start Date”的值已經被確定,且不能修改。如果在觸發增量構建的時候Cube中不存在任何的Segment,那麼“StartDate”的值會被系統設置爲“Partition Start Date”的值。
在這裏插入圖片描述

在這裏插入圖片描述
在進行增量構建時,將增量部分的起始時間和結束時間作爲增量構建請求的一部分提交給Kylin的任務引擎,任務引擎會根據起始時間和結束時間從Hive中抽取相應時間的數據,並對這部分數據做預計算處理,然後將預計算的結果封裝成爲一個新的Segment,並將相應的信息保存到元數據和存儲引擎中。
在JOB step1″Create Intermediate Flat Hive Table”可以看到:

Create and distribute table, cmd: 
hive -e "USE default;

DROP TABLE IF EXISTS kylin_intermediate_cube_incr_3_8ff2496d_8d5d_09c3_a9a7_aa84f52c1276;
CREATE EXTERNAL TABLE IF NOT EXISTS kylin_intermediate_cube_incr_3_8ff2496d_8d5d_09c3_a9a7_aa84f52c1276
(
\`KYLIN_SALES_PART_DT\` date
,\`KYLIN_SALES_SELLER_ID\` bigint
,\`KYLIN_SALES_OPS_REGION\` string
)
STORED AS SEQUENCEFILE
LOCATION 'hdfs://gd2:8020/kylin/kylin_metadata/kylin-5b2b9f02-786f-26dd-ee5c-4b22e371409e/kylin_intermediate_cube_incr_3_8ff2496d_8d5d_09c3_a9a7_aa84f52c1276';
ALTER TABLE kylin_intermediate_cube_incr_3_8ff2496d_8d5d_09c3_a9a7_aa84f52c1276 SET TBLPROPERTIES('auto.purge'='true');
INSERT OVERWRITE TABLE \`kylin_intermediate_cube_incr_3_8ff2496d_8d5d_09c3_a9a7_aa84f52c1276\` SELECT
\`KYLIN_SALES\`.\`PART_DT\` as \`KYLIN_SALES_PART_DT\`
,\`KYLIN_SALES\`.\`SELLER_ID\` as \`KYLIN_SALES_SELLER_ID\`
,\`KYLIN_SALES\`.\`OPS_REGION\` as \`KYLIN_SALES_OPS_REGION\`
 FROM \`DEFAULT\`.\`KYLIN_SALES\` as \`KYLIN_SALES\`
LEFT JOIN \`DEFAULT\`.\`KYLIN_ACCOUNT\` as \`KYLIN_ACCOUNT\`
ON \`KYLIN_SALES\`.\`SELLER_ID\` = \`KYLIN_ACCOUNT\`.\`ACCOUNT_ID\`
WHERE 1=1 AND (\`KYLIN_SALES\`.\`PART_DT\` >= '2012-01-14' AND \`KYLIN_SALES\`.\`PART_DT\` < '2012-01-21')
;

" --hiveconf hive.merge.mapredfiles=false --hiveconf hive.auto.convert.join=true --hiveconf dfs.replication=2 --hiveconf hive.exec.compress.output=true --hiveconf hive.auto.convert.join.noconditionaltask=true --hiveconf mapreduce.job.split.metainfo.maxsize=-1 --hiveconf hive.merge.mapfiles=false --hiveconf hive.auto.convert.join.noconditionaltask.size=100000000 --hiveconf hive.stats.autogather=true
ls: cannot access /opt/cloudera/parcels/SPARK2-2.3.0.cloudera2-1.cdh5.13.3.p0.316101/lib/spark2/lib/spark-assembly-*.jar: No such file or directory
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512M; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512M; support was removed in 8.0

Logging initialized using configuration in jar:file:/opt/cloudera/parcels/CDH-5.16.2-1.cdh5.16.2.p0.8/jars/hive-common-1.1.0-cdh5.16.2.jar!/hive-log4j.properties
OK
Time taken: 1.906 seconds
OK
Time taken: 0.046 seconds
OK
Time taken: 0.849 seconds
OK
Time taken: 0.89 seconds
Query ID = root_20200611164444_54919364-439f-4988-83a6-d8363bdb4afb
Total jobs = 1
Execution log at: /tmp/root/root_20200611164444_54919364-439f-4988-83a6-d8363bdb4afb.log
2020-06-11 04:44:08	Starting to launch local task to process map join;	maximum memory = 19089326082020-06-11 04:44:09	Dump the side-table for tag: 1 with group count: 10000 into file: file:/tmp/root/23d176a0-45d0-4506-b6fc-3778158420ee/hive_2020-06-11_16-44-06_441_1460799768032424703-1/-local-10002/HashTable-Stage-4/MapJoin-mapfile01--.hashtable
2020-06-11 04:44:09	End of local task; Time Taken: 0.505 sec.
Execution completed successfully
MapredLocal task succeeded
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
Starting Job = job_1591773281588_0053, Tracking URL = http://gd1:8088/proxy/application_1591773281588_0053/
Kill Command = /opt/cloudera/parcels/CDH-5.16.2-1.cdh5.16.2.p0.8/bin/../lib/hadoop/bin/hadoop job  -kill job_1591773281588_0053
Hadoop job information for Stage-4: number of mappers: 1; number of reducers: 0
2020-06-11 16:44:15,985 Stage-4 map = 0%,  reduce = 0%
2020-06-11 16:44:21,186 Stage-4 map = 100%,  reduce = 0%, Cumulative CPU 2.61 sec
MapReduce Total cumulative CPU time: 2 seconds 610 msec
Ended Job = job_1591773281588_0053
Loading data to table default.kylin_intermediate_cube_incr_3_8ff2496d_8d5d_09c3_a9a7_aa84f52c1276
Table default.kylin_intermediate_cube_incr_3_8ff2496d_8d5d_09c3_a9a7_aa84f52c1276 stats: [numFiles=1, numRows=105, totalSize=780, rawDataSize=2909]
MapReduce Jobs Launched: 
Stage-Stage-4: Map: 1   Cumulative CPU: 2.61 sec   HDFS Read: 807467 HDFS Write: 916 SUCCESS
Total MapReduce CPU Time Spent: 2 seconds 610 msec
OK
Time taken: 16.674 seconds

4、合併

4.1 合併的好處

增量構建的Cube,由於不同時間的數據分佈在不同的Segment之中,因此爲了獲得完整的數據,查詢引擎需要向存儲引擎請求讀取各個Segment的數據。當然,查詢引擎會根據查詢中的條件自動跳過不感興趣的Segment。
對於全量構建的Cube,查詢引擎只需要向存儲引擎訪問單個Segment所對應的數據,從存儲層返回的數據無需進行Segment之間的聚合,但是這也並非意味着查詢全量構建的Cube不需要查詢引擎做任何額外的聚合,爲了加強性能,單個Segment的數據也有可能被分片存儲到引擎的多個分區上,從而導致查詢引擎可能仍然需要對單個Segment不同分區的數據做進一步的聚合。
當然,整體來說,增量構建的Cube上的查詢會比全量構建的做更多的運行時聚合,而這些運行時聚合都發生在單點的查詢引擎之上,因此通常來說增量構建的Cube上的查詢會比全量構建的Cube上的查詢要慢一些。
可以看到,日積月累,增量構建的Cube中的Segment越來越多,根據上一段的分析可以猜測到該Cube的查詢性能也會越來越慢,因爲需要在單點的查詢引擎中完成越來越多的運行時聚合。爲了保持查詢性能,Cube的管理員需要定期地將某些Segment合併在一起,或者讓Cube根據Segment保留策略自動地淘汰那些不會再被查詢到的陳舊Segment。
不僅如此,從存儲角度來說,大量的Segment會帶來大量的文件,這些文件會充斥所提供的命名空間,給存儲空間的多個模塊帶來巨大的壓力,例如Zookeeper、HDFS Namenode等。因此,有必要採取措施控制Cube中Segment的數量。

4.2 合併的方式

手動合併
單擊Action→Merge,然後在對話框中選中需要合併的Segment,可以同時合併多個Segment。注意這些Segment必須是連續的。
單擊提交後系統會提交一個類型爲“MERGE”的構建任務,它以選中的Segment中的數據作爲輸入,將這些Segment的數據合併封裝成爲一個新的Segment。這個新的Segment的起始時間爲選中的最早的Segment的起始時間,它的結束時間爲選中的最晚的Segment的結束時間。
自動合併
創建Cube的時候說過,在Cube Designer的“Refresh Settings”的頁面中有“Auto Merge Thresholds”和“Retention Threshold”兩個設置項可以用來幫助管理Segment碎片。
在這裏插入圖片描述
1、“Auto Merge Thresholds”
允許用戶設置幾個層級的時間閾值,層級越靠後,時間閾值就越大。舉例來說,用戶可以爲一個Cube指定(7天、28天)這樣的層級。每當Cube中有新的Segment狀態變爲READY的時候,就會觸發一次系統試圖自動合併的嘗試。系統首先會嘗試最大一級的時間閾值,結合上面的(7天、28天)層級的例子,首先查看是否能將連續的若干個Segment合併成爲一個超過28天的大Segment,在挑選連續Segment的過程中,如果遇到已經有個別Segment的時間長度本身已經超過了28天,那麼系統會跳過該Segment,從它之後的所有Segment中挑選連續的累積超過28天的Segment。如果滿足條件的連續Segment還不能夠累積超過28天,那麼系統會使用下一個層級的時間閾值重複尋找的過程。每當找到了能夠滿足條件的連續Segment,系統就會觸發一次自動合併Segment的構建任務,在構建任務完成之後,新的Segment被設置爲READY狀態,自動合併的整套嘗試又需要重新再來一遍。
舉例來說,如果現在有A~H 8個連續的Segment,它們的時間長度分別爲28天(A)、7天(B)、1天(C)、1天(D)、1天(E)、1天(F)、1天(G)、1天(H)。此時第9個Segment I加入,它的時間長度爲1天,那麼現在Cube中總共存在9個Segment。系統首先嚐試能否將連續的Segment合併到28天這個閾值上,由於Segment A已經超過28天,它會被排除。接下來的B到H加起來也不足28天,因此第一級的時間閾值無法滿足,退一步系統嘗試第二級的時間閾值,也就是7天。系統重新掃描所有的Segment,發現A和B已經超過7天,因此跳過它們,接下來發現將Segment C到I合併起來可以達到7天的閾值,因此係統會提交一個合併Segment的構建請求,將Segment C到I合併爲一個新的Segment X。X的構建完成之後,Cube中只剩下三個Segment,分別是原來的A(28天),B(7天)和新的X(7天)。由於X的加入,觸發了系統重新開始整個合併嘗試,但是發現已經沒有滿足自動合併的條件,既沒有連續的、滿足條件的、累積超過28天的Segment,也沒有連續的、滿足條件的、累積超過7天的Segment,嘗試終止。

2、 “Retention Threshold”
從碎片管理的角度來說,自動合併是將多個Segment合併爲一個Segment,以達到清理碎片的目的。保留Segment則是從另外一個角度幫助實現碎片管理,那就是及時清理不再使用的Segment。
在很多業務場景中,只會對過去一段時間內的數據進行查詢,例如對於某個只顯示過去1年數據的報表,支撐它的Cube事實上只需要保留過去一年內的Segment即可。由於數據在Hive中往往已經存在備份,因此無需再在Kylin中備份超過一年的歷史數據。
在這種情況下,我們可以將“Retention Threshold”設置爲365。每當有新的Segment狀態變爲READY的時候,系統會檢查每一個Segment:如果它的結束時間距離最晚的一個Segment的結束時間已經大於“RetentionThreshold”,那麼這個Segment將被視爲無需保留。系統會自動地從Cube中刪除這個Segment。

如果啓用了“Auto Merge Thresholds”,那麼在使用“Retention Threshold”的時候需要注意,不能將“Auto Merge Thresholds”的最大層級設置得太高。假設我們將“Auto Merge Thresholds”的最大一級設置爲1000天,而將“Retention Threshold”設置爲365天,那麼受到自動合併的影響,新加入的Segment會不斷地被自動合併到一個越來越大的Segment之中,糟糕的是,這會不斷地更新這個大Segment的結束時間,從而導致這個大Segment永遠不會得到釋放。因此,推薦自動合併的最大一級的時間不要超過1年。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章