友盟+ 簡(jiǎn)介
友盟+ 以“數(shù)據(jù)智能,驅(qū)動(dòng)業(yè)務(wù)增長(zhǎng)”為使命,為移動(dòng)應(yīng)用開(kāi)發(fā)者和企業(yè)提供包括統(tǒng)計(jì)分析、性能監(jiān)測(cè)、消息推送、智能認(rèn)證等一站式解決方案。截止2023年6月,已累計(jì)為270萬(wàn)移動(dòng)應(yīng)用和980萬(wàn)家網(wǎng)站,提供十余年的專(zhuān)業(yè)數(shù)據(jù)服務(wù)。
作為國(guó)內(nèi)最大的移動(dòng)應(yīng)用統(tǒng)計(jì)服務(wù)商,其統(tǒng)計(jì)分析產(chǎn)品 U-App & U-Mini & U-Web 為開(kāi)發(fā)者提供基礎(chǔ)報(bào)表及自定義用戶(hù)行為分析服務(wù),能夠幫助開(kāi)發(fā)者更好地理解用戶(hù)需求,優(yōu)化產(chǎn)品功能,提升用戶(hù)體驗(yàn),助力業(yè)務(wù)增長(zhǎng)。
為了滿(mǎn)足產(chǎn)品、運(yùn)營(yíng)等多業(yè)務(wù)角色對(duì)數(shù)據(jù)不同視角的分析需求,統(tǒng)計(jì)分析 U-App 提供了包括用戶(hù)分析、頁(yè)面路徑、卸載分析在內(nèi)的多種「開(kāi)箱即用」的預(yù)置報(bào)表,集成 SDK 上報(bào)數(shù)據(jù)后即可查看這些指標(biāo)。除此以外,為了滿(mǎn)足個(gè)性化的分析訴求,業(yè)務(wù)也可以自定義報(bào)表的計(jì)算規(guī)則,提供了事件細(xì)分、漏斗分析、留存分析等用戶(hù)行為分析模型,用戶(hù)可以根據(jù)自己的分析需求靈活地選擇時(shí)間范圍、設(shè)置事件名稱(chēng)、where篩選和Groupby分組等。
如上所述,U-App 服務(wù)了眾多應(yīng)用場(chǎng)景,每天處理接近千億條日志,需要考慮平衡好數(shù)據(jù)新鮮度、查詢(xún)延遲和成本的關(guān)系,同時(shí)保障系統(tǒng)的穩(wěn)定性,這對(duì)數(shù)據(jù)架構(gòu)和技術(shù)選型提出了極高的要求。
針對(duì)報(bào)表類(lèi)型不同的看數(shù)場(chǎng)景和業(yè)務(wù)需求,我們底層技術(shù)架構(gòu)通過(guò)多種產(chǎn)品來(lái)支撐。在數(shù)據(jù)新鮮度方面,分別使用 Flink 和 MaxCompute 提供了T+0 的實(shí)時(shí)計(jì)算 和 T+1的離線批量計(jì)算,主要支持預(yù)置報(bào)表的計(jì)算場(chǎng)景,并將計(jì)算好的結(jié)果導(dǎo)出到類(lèi)Hbase 存儲(chǔ),能夠支持高并發(fā)的報(bào)表查詢(xún)。在分析時(shí)效性方面,使用阿里云的Hologres 實(shí)現(xiàn)自定義報(bào)表支持秒級(jí)的 OLAP分析,當(dāng)處理的數(shù)據(jù)周期跨度大時(shí),可能會(huì)出超過(guò)內(nèi)存算子處理范圍,因此我們轉(zhuǎn)化為離線計(jì)算引擎來(lái)執(zhí)行,同時(shí)也讓交互體驗(yàn)從同步降級(jí)為異步。
在本文中,我們會(huì)分享友盟U-App 背后的技術(shù)實(shí)現(xiàn),以及友盟在行為分析和畫(huà)像分析場(chǎng)景上的最佳實(shí)踐。
友盟+技術(shù)架構(gòu)
如下圖所示,在大數(shù)據(jù)領(lǐng)域這是一個(gè)比較通用的數(shù)據(jù)處理 pipeline,貫穿數(shù)據(jù)的加工&使用過(guò)程包括,數(shù)據(jù)采集&接入、數(shù)據(jù)清洗&傳輸、數(shù)據(jù)建模&存儲(chǔ)、數(shù)據(jù)計(jì)算&分析 以及 查詢(xún)&可視化,其中友盟U-App 數(shù)據(jù)處理的核心架構(gòu)是紅框部分。
U-App 整體架構(gòu)如下圖所示,從上往下大體可以分為四層:數(shù)據(jù)服務(wù)、數(shù)據(jù)計(jì)算、數(shù)據(jù)存儲(chǔ)以及核心組件:
數(shù)據(jù)服務(wù):將查詢(xún)DSL 解析為底層引擎執(zhí)行的DAG,同時(shí)智能采樣、查詢(xún)排隊(duì)等來(lái)盡可能減少系統(tǒng)過(guò)載情況,保證查詢(xún)順滑
數(shù)據(jù)計(jì)算:根據(jù)不同分析場(chǎng)景抽象沉淀了分析模型,包括行為分析和畫(huà)像分析兩大類(lèi)
數(shù)據(jù)存儲(chǔ):使用了以 User-Event 為核心的數(shù)據(jù)模型,提供基于明細(xì)數(shù)據(jù)的行為分析
核心組件:離線批量計(jì)算使用MaxCompute,流式計(jì)算使用Flink,OLAP計(jì)算使用Hologres
在設(shè)計(jì)系統(tǒng)架構(gòu)時(shí),支持多引擎是優(yōu)先要考慮的,主要有以下原因:
鑒于成本、穩(wěn)定性、高可用以及容錯(cuò)性考慮,引擎需要根據(jù)查詢(xún)場(chǎng)景分級(jí)路由,將查詢(xún)性能好的OLAP計(jì)算與健壯可靠但延遲較大的離線計(jì)算相結(jié)合。用戶(hù)可以使用 OLAP 分析進(jìn)行靈活的數(shù)據(jù)探查,當(dāng)數(shù)據(jù)量超過(guò)一定閾值時(shí)自動(dòng)轉(zhuǎn)為離線計(jì)算。另外,對(duì)于添加到看板需要例行查看的報(bào)表也會(huì)通過(guò)離線的方式批量計(jì)算。
鑒于存儲(chǔ)成本考慮,將數(shù)據(jù)進(jìn)行冷熱分離,實(shí)時(shí)數(shù)倉(cāng)只儲(chǔ)最近1個(gè)月熱數(shù)據(jù),超過(guò)查詢(xún)范圍的Query會(huì)自動(dòng)路由到離線計(jì)算。
從系統(tǒng)的可擴(kuò)展性考慮,OLAP領(lǐng)域發(fā)展很快,眾多引擎百花齊放,需要為之后對(duì)接其它引擎預(yù)留出靈活的升級(jí)空間。
同時(shí),我們也設(shè)計(jì)了一套通用的計(jì)算規(guī)則來(lái)支持多引擎架構(gòu),屏蔽底層細(xì)節(jié)。借鑒了Presto系統(tǒng)設(shè)計(jì),選擇Antlr來(lái)定義通用的查詢(xún)規(guī)則,查詢(xún)DSL使用JSON來(lái)描述。Task Builder 在生成任務(wù)DAG時(shí),遍歷AST抽樣語(yǔ)法樹(shù),并結(jié)合物理表存儲(chǔ)等元數(shù)據(jù)信息,生成指定引擎可執(zhí)行的語(yǔ)句。
通過(guò)自定義描述語(yǔ)言,上層業(yè)務(wù)只需要對(duì)接DSL不用關(guān)注底層細(xì)節(jié),既降低了業(yè)務(wù)對(duì)接成本,也增強(qiáng)了平臺(tái)擴(kuò)展性。
基于這套技術(shù)架構(gòu),我們服務(wù)了友盟+U-App 產(chǎn)品中的眾多應(yīng)用場(chǎng)景。其中,基于明細(xì)數(shù)據(jù)的用戶(hù)行為分析和基于全域標(biāo)簽的畫(huà)像分析是非常重要的兩個(gè)功能,其實(shí)現(xiàn)主要使用了阿里云Hologres,下面我們會(huì)詳細(xì)介紹這兩個(gè)場(chǎng)景上的最佳實(shí)踐。
Hologres多維分析使用實(shí)踐
在多維分析場(chǎng)景,尤其是用戶(hù)行為分析和畫(huà)像分析場(chǎng)景上,市面上可選擇的OLAP產(chǎn)品還是較多的。我們對(duì)集團(tuán)多個(gè)引擎進(jìn)行深入調(diào)研和測(cè)試后,最終選擇了阿里云計(jì)算平臺(tái)的Hologres,主要基于以下考慮:
存算分離架構(gòu):計(jì)算資源彈性伸縮,滿(mǎn)足靈活擴(kuò)展性的同時(shí)又兼顧了成本。
生態(tài)豐富:語(yǔ)法與PostgreSQL函數(shù)兼容,我們使用起來(lái)的時(shí)候比較方便。同時(shí)我們也與Hologres團(tuán)隊(duì)共建,支持了一些UDF函數(shù),方便我們業(yè)務(wù)深度開(kāi)展。
與MaxCompute深度集成:可以和MC互相直讀,加速查詢(xún),實(shí)現(xiàn)實(shí)時(shí)離線聯(lián)邦查詢(xún)。同時(shí)也支持冷熱數(shù)據(jù)混合查詢(xún),有利于成本性能平衡。
性能強(qiáng)悍:引擎C/C++編寫(xiě),支持量化全異步執(zhí)行,PB級(jí)數(shù)據(jù)查詢(xún)秒級(jí)響應(yīng)且支持?jǐn)?shù)據(jù)實(shí)時(shí)寫(xiě)入。
用戶(hù)行為分析實(shí)踐
U-App行為洞察提供了事件、漏斗、留存 、行為路徑等模型,可以幫助業(yè)務(wù)從多視角洞察用戶(hù)細(xì)粒度的使用行為,從而進(jìn)一步輔助業(yè)務(wù)精細(xì)化運(yùn)營(yíng)。
U-App 行為洞察提供的是普惠的交互式分析服務(wù),這對(duì)技術(shù)的挑戰(zhàn)主要包括以下幾個(gè)方面:
數(shù)據(jù)量大,每天新增日志條數(shù)接近千億級(jí)別(注:為了保證查詢(xún)靈活性,分析使用的是沒(méi)有信息損失的事件原始數(shù)據(jù),即沒(méi)有使用中間聚合表)
應(yīng)用眾多,不同應(yīng)用數(shù)據(jù)量差距較大
自定義埋點(diǎn)數(shù)據(jù) schema-free ,不同應(yīng)用埋點(diǎn)屬性差異巨大
計(jì)算分析速度要快并發(fā)要高
為了應(yīng)對(duì)以上諸多挑戰(zhàn),我們從存儲(chǔ)層、引擎執(zhí)行層以及查詢(xún)層制定了系統(tǒng)性化的解決方案,下面依次進(jìn)行介紹。
數(shù)據(jù)存儲(chǔ)層設(shè)置合理的索引
根據(jù)業(yè)務(wù)查詢(xún)特點(diǎn),在Hologres中合理的建立索引,盡可能減少Scan的數(shù)據(jù)量:
根據(jù)查詢(xún)特點(diǎn)(每個(gè)查詢(xún)只涉及一個(gè)應(yīng)用的有限幾個(gè)事件),按照appkey,event_name建立聚簇索引(Clustering Key)
根據(jù)用戶(hù)行為分析的特點(diǎn),按設(shè)備id分片(Distribution Key),數(shù)據(jù)在woker節(jié)點(diǎn)正交分布,減少跨節(jié)點(diǎn)數(shù)據(jù) shuffle
設(shè)置合理shard數(shù)量,平衡數(shù)據(jù)寫(xiě)入和查詢(xún)性能
對(duì)常用篩選列建立Bitmap索引,提升數(shù)據(jù)過(guò)濾效率
在埋點(diǎn)場(chǎng)景上,開(kāi)發(fā)者可設(shè)置自定義事件和屬性,自定義屬性使用 JSON 字符串表示。JSON 優(yōu)點(diǎn)是天然支持 Schema Evoluation,開(kāi)發(fā)者根據(jù)業(yè)務(wù)需求,靈活進(jìn)行埋點(diǎn)。缺點(diǎn)是較列式存儲(chǔ),由于無(wú)法利用列存對(duì)數(shù)據(jù)進(jìn)行壓縮,占用存儲(chǔ)空間大,而且查詢(xún) JSON 時(shí)要將整個(gè)字符串完整解析一遍,中間涉及大量IO和CPU操作,對(duì)性能影響極大。
為解決這個(gè)問(wèn)題,業(yè)界較通用的方案是在預(yù)處理階段,動(dòng)態(tài)地將JSON展開(kāi)成獨(dú)立列,通過(guò)外部的元數(shù)據(jù)表來(lái)維護(hù) schema。另外,為了減少 schema 變動(dòng),也可以提前創(chuàng)建預(yù)留列,然后將新抽取的列映射到預(yù)設(shè)列上。但友盟+服務(wù)了眾多開(kāi)發(fā)者 ,不可能將所有的屬性都展開(kāi)成獨(dú)立列---即使可以做到,使用和維護(hù)成本也相當(dāng)高。
借助 Hologres v1.3版本的JSONB列式存儲(chǔ)特效,支持在導(dǎo)入JSON 數(shù)據(jù)時(shí),引擎自動(dòng)抽取JSON數(shù)據(jù)結(jié)構(gòu),包括字段個(gè)數(shù),字段類(lèi)型等,然后在存儲(chǔ)層將JSON數(shù)據(jù)轉(zhuǎn)化成強(qiáng) Schema格式的列式存儲(chǔ)格式的文件,以此來(lái)達(dá)到加速查詢(xún)的效果。通過(guò)測(cè)試,使用 JSONB 后,數(shù)據(jù)存儲(chǔ)會(huì)節(jié)省 25~50%,查詢(xún)效率提升 5~10 倍。
引擎執(zhí)行層使用行為分析函數(shù)
為了提升查詢(xún)性能,我們與Hologres合作共建了自定義的分析函數(shù)函數(shù),它主要解決兩個(gè)問(wèn)題:
漏斗、留存這類(lèi)分析模型,使用普通JOIN計(jì)算性能較差,尤其是漏斗分析,隨著計(jì)算事件數(shù)的增加,時(shí)間復(fù)雜度會(huì)指數(shù)級(jí)放大。
原生SQL表達(dá)能力差,無(wú)法描述計(jì)算邏輯復(fù)雜的模型。為了解決以上問(wèn)題,需要開(kāi)發(fā)自定義的分析函數(shù) 。
具體實(shí)現(xiàn)是基于Hologres的引擎,兼容PostgreSQL語(yǔ)法,使用C語(yǔ)言定制開(kāi)發(fā)了漏斗和留存算子,集成在Hologres的版本中(最開(kāi)始的發(fā)布的版本是0.8版本)。目前在Hologres高版本中默認(rèn)已經(jīng)集成了計(jì)算漏斗和留存的流量函數(shù)(windowFunnel,retention等),以及成為系統(tǒng)的標(biāo)配,使用起來(lái)更加方便,性能也更好。
例如下面是一個(gè)漏斗分析的示例,計(jì)算在 20231220 這一天,在 1 小時(shí)內(nèi) 依次發(fā)生從啟動(dòng)(session_start)-> 加購(gòu)物車(chē)(add_cart)-> 支付訂單(order_pay)3 個(gè)事件的轉(zhuǎn)化漏斗,我們對(duì)比了傳統(tǒng)JOIN方案和漏斗函數(shù)的方案的性能性能。
第一個(gè)是純SQL的方式,第二個(gè)是用 Hologres windowFunne 聚合函數(shù)。使用第一個(gè)JOIN SQL會(huì)有性能問(wèn)題,因?yàn)榇嬖诙嗖絁OIN操作,隨著計(jì)算事件量的增加,時(shí)間復(fù)雜度會(huì)指數(shù)級(jí)放大。而第二個(gè)使用漏斗函數(shù)的SQL則變得簡(jiǎn)單許多。
下面是使用普通JOIN與漏斗函數(shù)的性能測(cè)試對(duì)比情況:在事件量較小的情況下,二者性能差距不大,但隨著事件量的增加,普通JOIN查詢(xún)性能迅速衰減,而使用漏斗函數(shù)的耗時(shí)較平緩。與普通的JOIN 查詢(xún)相比,使用漏斗函數(shù)的查詢(xún)速度提升了 5~10 倍,內(nèi)存使用量下降 10%~25%。
數(shù)據(jù)查詢(xún)層使用智能采樣、查詢(xún)排隊(duì)
智能采樣:由于OLAP是完全基于內(nèi)存的計(jì)算,為了避免較大查詢(xún)引發(fā)系統(tǒng)OOM,保障查詢(xún)吞吐和系統(tǒng)穩(wěn)定性,對(duì)于數(shù)據(jù)量較大的 Query 會(huì)主動(dòng)采樣。通過(guò)分析查詢(xún)條件,結(jié)合預(yù)先統(tǒng)計(jì)的信息可以預(yù)估出Scan的數(shù)據(jù)量,然后再結(jié)合提前設(shè)置好的閾值確定采樣率。平臺(tái)上線初期,智能采樣發(fā)揮了很大的作用。
查詢(xún)排隊(duì):為了解決瞬時(shí)高并發(fā)查詢(xún)引發(fā)的系統(tǒng)過(guò)載的問(wèn)題,基于Redis實(shí)現(xiàn)了查詢(xún)排隊(duì)功能。如下圖所示,它包含Waiting Queue和Active Queue兩部分,所有請(qǐng)求先進(jìn)入等待隊(duì)列排隊(duì),并控制進(jìn)入執(zhí)行隊(duì)列的數(shù)量,從而避免系統(tǒng)過(guò)載,大幅提升了查詢(xún)的順滑性。
標(biāo)簽人群計(jì)算實(shí)踐
友盟+基于采集的設(shè)備信息產(chǎn)出了豐富維度的標(biāo)簽數(shù)據(jù)。依托這些數(shù)據(jù),U-App提供的全景畫(huà)像功能可以對(duì)數(shù)據(jù)進(jìn)行詳細(xì)刻畫(huà)。
為了實(shí)現(xiàn)畫(huà)像的高性能多維分析,我們使用了Hologres的Roaring Bitmap功能。在具體數(shù)據(jù)存儲(chǔ)上,為了充分發(fā)揮 Hologres 多 shard 的并發(fā)優(yōu)勢(shì),數(shù)據(jù)的分布鍵(Distribution Key)按桶號(hào)和 bitmap 高16位打散到Hologres各個(gè)計(jì)算節(jié)點(diǎn)。在進(jìn)行交并差集計(jì)算過(guò)程中,由于各個(gè)節(jié)點(diǎn)之間數(shù)據(jù)完全獨(dú)立,每個(gè)節(jié)點(diǎn)可以單獨(dú)計(jì)算,然后在Master節(jié)點(diǎn)進(jìn)行匯總。
計(jì)算過(guò)程如下圖所示,整個(gè)過(guò)程可以分為兩個(gè)階段:在Worker節(jié)點(diǎn)會(huì)進(jìn)行第一次聚合,由于Worker間數(shù)據(jù)完全正交,數(shù)據(jù)沒(méi)有shuffle過(guò)程,不需要跨幾點(diǎn)轉(zhuǎn)移數(shù)據(jù),效率會(huì)非常高;在Master節(jié)點(diǎn)進(jìn)行最終聚合通過(guò)簡(jiǎn)單匯總得到最終結(jié)果。
基于以上 Hologres 的Roaring Bitmap設(shè)計(jì),一個(gè)完整的標(biāo)簽場(chǎng)景從數(shù)據(jù)導(dǎo)入和查詢(xún)示例如下:
通過(guò)使用 Hologres 提供的 Roaring Bitmap 功能,使用的存儲(chǔ)大大減少,相較之前大概有 5~10 倍的節(jié)省。查詢(xún)性能方面,與普通的 JOIN 相比,兩個(gè)億級(jí)別ID的標(biāo)簽復(fù)合運(yùn)算的可以有數(shù)量級(jí)的性能提升,90%的 Query 能夠在1秒內(nèi)穩(wěn)定完成,滿(mǎn)足了業(yè)務(wù)上對(duì)高吞吐和即時(shí)分析的需求。
總結(jié)與展望
目前,Hologres 在友盟+統(tǒng)計(jì)分析、營(yíng)銷(xiāo)等多個(gè)產(chǎn)品線使用,很好地滿(mǎn)足了用戶(hù)行為分析、人群圈選與洞察場(chǎng)景的多維度分析、靈活下鉆、快速人群預(yù)估和圈選等分析需求,提供客戶(hù)更流暢的數(shù)據(jù)查詢(xún)和分析體驗(yàn)。
未來(lái),隨著互聯(lián)網(wǎng)流量紅利消失,拉新和留存成本升高,精細(xì)化數(shù)據(jù)運(yùn)營(yíng)越來(lái)越被重視,對(duì)于數(shù)據(jù)分析的時(shí)效性和靈活性的要求變得越來(lái)越高,實(shí)時(shí)OLAP數(shù)據(jù)分析會(huì)成為一種基本需求,這對(duì)技術(shù)的挑戰(zhàn)也越來(lái)越大。技術(shù)上,后續(xù)會(huì)結(jié)合Hologres物化視圖、冷熱數(shù)據(jù)分離等新特性,同時(shí)探索基于Apache Paimon 的 Streaming LakeHouse 存儲(chǔ)技術(shù),不斷優(yōu)化精簡(jiǎn)架構(gòu),在平衡好性能、成本和穩(wěn)定性基礎(chǔ)上,提升計(jì)算平臺(tái)實(shí)時(shí)計(jì)算能力,為開(kāi)發(fā)者提供更好用的普惠的數(shù)據(jù)分析服務(wù)。