Apache Doris 在小米億級使用者行為分析平臺的實踐|最佳實踐
導讀:過去 3 年時間裡,Apache Doris 已經在小米內部得到了廣泛的應用,支援了集團資料看板、廣告投放/廣告 BI、新零售、使用者行為分析、A/B 實驗平臺、天星數科、小米有品、使用者畫像、小米造車等小米內部數十個業務,並且在小米內部形成了一套以 Apache Doris 為核心的資料生態 。本文將為大家分享小米使用者行為分析平臺基於 Apache Doris 向量化版本的改造實踐,包括資料儲存架構和查詢服務架構的演進與改造經驗分享。
作者|小米資料智慧部開發工程師 湯佳樹
小米使用者行為分析統一平臺是基於海量資料的一站式、全場景、多模型、多維度、自助式大資料智慧洞察分析服務平臺,對接各類資料來源,進行加工處理、分析挖掘和視覺化展現,滿足各類使用者在使用者洞察場景下的資料分析應用需求,提供高效極致的分析體驗。
業務需求
平臺可以基於資料進行時間分析,留存分析,分佈分析,漏斗分析等,業務方主要基於事件進行分析,事件是追蹤或記錄的使用者行為或業務過程,可以是單個事件也可以是多個事件組合的虛擬事件。
資料來源於各業務的打點資料,且基於事件模型進行建模,使用者在產品中的各種操作都可以抽象成 Event 實體,並且裡面都會包含五要素:
- Who:即參與這個事件的使用者是誰,例如使用者的唯一 ID
- When:即這個事件發生的實際時間,例如
time
欄位,記錄精確到毫秒的事件發生時間 - Where:即事件發生的地點,例如根據 IP 解析出的省份和城市
- How:即使用者從事這個事件的方式,例如使用者的裝置,使用的瀏覽器,使用的 App 版本等等
- What:描述使用者所做的這件事件的具體內容,例如點選型別的事件,需要記錄的欄位有點選 URL,點選 Title,點選位置等
資料基於 OLAP 引擎 Doris 進行儲存,隨著接入業務不斷增多,且接入的業務量不斷膨脹,Top 級應用可以達到 100 億條/天,查詢壓力和時間相繼增大,使用者對查詢時延的吐槽愈來愈多,我們急切的需要提升查詢效能來提升使用者的體驗。
痛點問題
針對於業務需求,我們總結了以下痛點問題:
- 為了實現複雜的業務需求,OLAP 分析引擎需要留存、漏斗等分析函式支撐。
- 增量資料 100億/天,匯入壓力大,部分業務要求資料匯入不丟不重。
- 業務接入不斷增多,資料量膨脹,需要 PB 級的資料下的互動式分析查詢達到秒級響應。
為了解決以上的痛點問題,我們對比了多款 OLAP 分析引擎,最終選擇了 Apache Doris。Doris 提供了留存、漏斗分析等函式,極大程度的簡化了開發的成本。在資料匯入的過程中,我們嘗試 Doris 剛推出的 Merge On Write Unique Key 匯入模型,可以抗住 100 億/天的增量資料壓力。針對於向量化查詢引擎的改造也是的效能較之前的版本有 3-5 倍的提升。
架構演進
一個優秀的系統離不開持續迭代與演進。為了更好的滿足業務需求,我們在儲存架構與查詢引擎兩個層面上不斷進行嘗試,小米使用者行為分析系統在上線後,目前已完成 3 次改造,以下將為大家介紹改造歷程。
資料儲存結構:資料架構的演進
在小米的使用者行為分析平臺中,原始資料通過小米自研的訊息佇列 Talos,在 Flink 中清洗與建模後,被下游的 Doris 與 Hive 消費。全量的資料會儲存在 Hive 中,進行批量 ETL 或歷史資料召回的查詢。實時增量資料被儲存在 Doris 中,用來做熱資料的查詢操作。基於冷熱資料分離的架構,我們進行了 3 次架構的演進。
第一階段:基於明細寬表的查詢
在最初的階段我們使用了基於明細的寬表查詢模式。為了處理靈活多樣的分析請求,在系統中,我們配合統一埋點平臺處理資料,接入的 OLAP 的資料是直接埋點的全欄位展平。在入庫之前,我們在 Flink 中將資料打平,以寬表的模式儲存在 Doris 明細表中。根據查詢的需求,我們將經常使用的列作為建表的維度列,利用字首索引的特性進行查詢加速。但某些頭部大資料量業務容易查詢多天資料,一個大查詢可能就會將叢集資源佔滿甚至導致叢集不可用,且查詢耗時相當之久。
第二階段:基於聚合模型的查詢加速
在改造的第二階段,我們使用了聚合模型對業務查詢進行加速。 我們對接入行為分析的應用進行統計分析,絕大多數接入行為分析的應用資料量在 1 億/天資料量以內。對於部分使用頻率較高的表,我們採用聚合表完成查詢加速,對單天資料量超 10 億且高頻的頭部應用做聚合表加速。具體流程為根據資料量挑選出頭部應用,對其進行欄位解析,並挑選出常用指標及維度,由 Hive 表資料進行聚合 T-1 產出資料,最後寫入到 Doris 中,進行查詢加速。該階段的改造解決了叢集頭部業務大查詢的問題,此時雖然獨立叢集儲存沒問題,但由於其他業務接入後還會持續增加資料量和* 埋點***欄位 ,這樣會導致元資料最先進入瓶頸**。
第三階段(當前階段):業務適配的建表改造
當前階段,我們對業務需求進行深度解析後重新規劃了建表結構。我們對某些應用的埋點欄位進行分析,發現有些使用者埋點欄位多達 500+,但在行為分析裡實際用到的可能只有 100+,這顯然有所浪費。所以我們與使用者溝通調研需求,配合行為分析平臺側的能力,使用者可在平臺對有用事件和屬性進行篩選,同時設定欄位對映和過濾邏輯,然後再進行建表。
查詢服務架構:查詢引擎的改造與演進
我們基於業務深度改造了查詢的服務架構,構建了新的查詢引擎架構,實現 SQL 的權重、路由、快取和資源排程操作。根據查詢條件,路由引擎會將 SQL 拆分成多條子查詢,在 Doris 或 Hive 中執行後,將子查詢的結果彙總,得到最終的結果。針對查詢引擎,我們也進行了 3 次技術架構的改造。
第一階段:基於叢集粒度的查詢資源管理
我們對叢集粒度進行查詢資源管理,在資源排程中,我們會給每一個 Doris 叢集設定一個總的資源池大小(根據叢集能力和測試進行量化),根據資料量大小和查詢天數對每個 SQL 進行加權,並對資源池的最大最小並行 SQL 數進行限制,如果計算的 SQL 超過限制則進行排隊。其次,還會利用 Redis 對資料進行 SQL 級別快取。
第二階段:基於 SQL 路由的改造
為適配聚合表加速做了路由層,提升快取命中率和利用率,此階段拆分原始提交 SQL,基於指標進行快取,粒度更細,服務端可根據指標進行適當計算更易於快取命中。值得一提的是排隊時間往往會比較長,有些場景下可能會進行重複提交或拆分成同樣的 SQL,為了提高效率會在 SQL 排隊前和排隊後各進行一次快取校驗。
第三階段(當前階段):基於 SQL 權重的改造
整體架構方面,由於採取了篩選埋點欄位而非全量欄位匯入 Doris,針對頭部問題使用者,我們會基於查詢歷史統計指標及維度,根據指定的某些規則進行預設初始化操作,並以此溝通使用者並進行引導升級。此外為了更精細的控制資源排程,本階段對對 SQL 內容進行加權,如含有DISTINCT
,LIKE
,VARIANCE_SAMP
等字樣再加權。對於資源消耗較大的操作,如 DISTINCT,會給予更高的權重,排程引擎在執行時會分配更多的資源。
實踐應用
資料建模
對業務來講,分析查詢需要較高的靈活度,且是對使用者粒度進行分析,所以需要保留較多的維度和指標,我們選用 Doris 作為儲存查詢引擎,且採用明細表建模,這樣可以保證使用者能夠根據分析需求查出資料。另一方面,由於查詢分析是一個延時要求較高的產品,對於資料量大、查詢天數多、語句複雜的情況,查詢延時會很高,所以對於頭部應用,我們根據高頻指標維度進行了聚合表模型建模。
CREATE TABLE `doris_XXX_event` (
`olap_date` bigint(20) NOT NULL COMMENT "",
`event_name` varchar(256) NOT NULL COMMENT "",
`uniq_id` varchar(256) NOT NULL COMMENT "",
`dim1` varchar(256) REPLACE NULL COMMENT "",
`dim2` varchar(256) REPLACE NULL COMMENT "",
...
`cnt` bigint(20) REPLACE NULL COMMENT "",
`index1` double REPLACE NULL COMMENT "",
`index2` double REPLACE NULL COMMENT "",
...
) ENGINE=OLAP
AGGREGATE KEY(`olap_date`, `event_name`, `uniq_id`)
COMMENT "OLAP"
PARTITION BY RANGE(`olap_date`)
資料匯入
明細表部分,我們接入 Json 格式 TalosTopic,動態獲取 Doris 表的 Schema 資訊,通過雙緩衝區迴圈攢批的方式,利用 StreamLoad 向 Doris 中寫資料,如果在匯入 Doris 時有出現失敗的批次,重試 10 次仍然失敗,會將資料按照應用粒度存入 HDFS,並在凌晨定時排程任務重新寫入 T-1 未寫入的資料。聚合表部分,我們由 Talos 落盤的 Iceberg 表,每日進行 T-1 資料的聚合,根據服務端選取的維度和指標,以及聚合型別(count
,count distinct
, sum
,max
,min ),進行聚合存入中間 Hive 表,再由統一匯入 Doris 程式進行匯入。
資料管理
明細資料和應用聚合表分庫儲存,TTL 均為 33 天。資料表會有資料質量監控,如果總行數或者設定指標環比波動太大,會進行告警人工介入確認資料是否有誤,視緊急程度進行回補處理。
資料查詢及應用
絕大多數使用者會錨定事件,進行含指標聚合,去重使用者數(幾乎佔總查詢的 50%)的事件行為分析,同時還會有留存分析,漏斗分析,分佈分析等分析型別。
建表模型的維護
為了適配業務的變更,上游的埋點資訊會週期性的更新。原有的表結構需要進行變更以適配埋點的增加。在過去的 Doris 版本中,Schema Change 是一項相對消耗較大的工作,需要對檔案進行修改。在新版本中開啟 Light Schema Change 功能後 *, *對於增減列的操作不需要修改檔案,只需要修改 FE 中的元資料,從而實現毫秒級的 Schame Change 操作。
應用現狀
小米目前在 300 多個業務線上線了 Doris 叢集,超過 1.5PB 的業務資料。在初期我們選擇了兩個使用較為頻繁的叢集進行向量化升級。
現遷移 Doris 向量化叢集的行為分析業務有 2 個,7 天增量資料的平均值在百億左右,儲存空間佔用 7T/天左右。在升級到向量化的版本後,儲存資源有較大的節省,只需要原有叢集約 2/3 的儲存空間。
效能提升
請求粒度
升級 Doris 向量化版本後,行為分析平臺以請求粒度統計查詢耗時 P80 和均值,P80 耗時下降 43% ,平均耗時下降 27% ;統計口徑:彙總 12.07-12.11 期間,行為分析請求粒度查詢執行時間。
SQL 粒度
升級 Doris 向量化版本後,行為分析平臺以 SQL 粒度來統計查詢耗時 P80 和均值,耗時 P80 下降 70% ,平均耗時下降 54% 。統計口徑:彙總 12.04-12.11 期間,行為分析 SQL 粒度查詢執行時間(未含排隊)
升級 Doris 向量化版本後,行為分析平臺以 SQL 粒度統計查詢耗時 P80 和均值,耗時 P80 下降 56% ,平均耗時下降 44% ;
統計口徑:彙總 12.02-12.11,行為分析 SQL 粒度查詢總時間 (含排隊)
去重優化
在 ID-Mapping 的時候,通常需要針對 ID 進行去重操作。在最初我們使用了COUNT DISTINCT
來完成去重。
SELECT a.`olap_date` AS `time`,
count(distinct a.`distinct_id`) AS distinct_id
FROM analysis.doris_XXX_event a
WHERE `a`.`olap_date` BETWEEN 20221218 AND 20221220 AND
a.`event_name` IN(XXXX, XXX, XXX, XXX) AND
... ...
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10000
在經過優化後,我們使用子查詢+ GROUP BY
來替代COUNT DISTINCT
的功能
SELECT z.`time`,
count(distinct_id) var1
FROM (SELECT a.`olap_date` AS `time`,
a.`distinct_id` AS distinct_id
FROM analysis.doris_XXX_event a
WHERE `a`.`olap_date` BETWEEN 20221218 AND 20221220 AND
a.`event_name` (XXXX, XXX, XXX, XXX) AND
... ...
GROUP BY 1, 2) z
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10000
相較於原有的COUNT DISTINCT
,使用子查詢+ GROUP BY
的模式效能有 1/3 的提升。
未來規劃
在過去的三年時間裡,Apache Doris 已經在小米內部得到了廣泛的應用,支援了集團資料看板、廣告投放/廣告 BI、新零售、使用者行為分析、A/B 實驗平臺、天星數科、小米有品、使用者畫像、小米造車等小米內部數十個業務,並且在小米內部形成了一套以 Apache Doris 為核心的資料生態 。隨著業務的持續增長,未來我們會進一步推動小米的其他業務上線向量化版本。
非常感謝 Apache Doris 社群與 SelectDB 公司的鼎力支援,小米集團作為 Apache Doris 最早期的使用者之一,一直深度參與社群建設,參與 Apache Doris 的穩定性打磨,未來我們也會密切聯絡社群,為社群貢獻更多的力量。
- Apache Doris 在美聯物業的資料倉庫應用實踐,助力傳統行業數字化革新!
- 杭銀消金基於 Apache Doris 的統一資料查詢閘道器改造
- 併發提升 20 倍、單節點數萬 QPS,Apache Doris 高併發特性解讀
- 如何基於 Apache Doris 與 Apache Flink 快速構建極速易用的實時數倉
- 從 Clickhouse 到 Apache Doris,慧策電商 SaaS 高併發資料服務的改造實踐
- 開源新生代的成長之路:從校園到開源,需要邁過哪些挑戰?
- 如何基於 Apache Doris 構建簡易高效的使用者行為分析平臺?
- 查詢效能較 Trino/Presto 3-10 倍提升!Apache Doris 極速資料湖分析深度解讀
- 資源消耗降低 90%,速度提升 50%,解讀 Apache Doris Compaction 最新優化與實現
- 從 ClickHouse 到 Apache Doris,騰訊音樂內容庫資料平臺架構演進實踐
- 一文教你玩轉 Apache Doris 分割槽分桶新功能
- 打破資料孤島,Apache Doris 助力縱騰集團快速構建流批一體數倉架構
- 實時分析全面賦能金融業務,馬上消費基於 Apache Doris 構建實時數倉的實踐
- 更高效能表現、更低資源佔用,高精度計算資料型別 DecimalV3 揭祕
- Java UDF 的設計與使用介紹,相容 Hive UDF 實現資料快速遷移
- 下一個十年,我們需要一款什麼樣的分析型資料庫?
- 更穩定!Apache Doris 1.2.1 Release 版本正式釋出|版本通告
- Apache Doris 在小米億級使用者行為分析平臺的實踐|最佳實踐
- 複雜查詢響應速度提升10 倍,度言軟體基於 Apache Doris 實時數倉建設實踐
- 併發提升 10 倍,運算延時降低 70%,領健從 ClickHouse 和 Kudu 到 Apache Doris 數倉升級實踐