作為大數(shù)據(jù)團隊,需要給公司的各條業(yè)務線提供數(shù)據(jù)服務。為了更好地洞察用戶行為,支撐各大事業(yè)群的產(chǎn)品和運營同學給用戶提供更好、更深層次的服務,我們自研了流量分析平臺 APPDATA,代替了分散在各個事業(yè)群和業(yè)務線的商業(yè)化流量分析工具,完成了流量分析的全集團統(tǒng)一。本文介紹 APPDATA 的演進過程,主要包括:1)滿幫流量分析的業(yè)務背景,以及 APPDATA 的產(chǎn)品定位;2)立項之初的技術(shù)架構(gòu)和實現(xiàn)及遭遇到的問題;3)將 Kylin 作為 APPDATA 的核心多維分析引擎所帶來的巨大改變;4)對 Kylin 的一些調(diào)優(yōu)操作,以及為了更好的滿足業(yè)務需求,對 Kylin 做出的一點改造。
APPDATA 是什么?
滿幫流量分析的場景特點
第一個特點,滿幫流量數(shù)據(jù)規(guī)模盤大。滿幫集團作為全國最大的車貨匹配信息平臺,連接著上千萬的司機和貨主用戶,這些用戶每天都會訪問平臺各種各樣的產(chǎn)品來進行發(fā)貨、找貨,以及使用一些如加油、ETC充值、借貸等服務,從而每天會產(chǎn)生近十億的流量數(shù)據(jù),近半年的數(shù)據(jù)累計達千億級。
第二,業(yè)務重度依賴流量分析。海量的流量數(shù)據(jù)記錄著非常豐富的用戶行為。無論哪條業(yè)務線,無論是管理者、數(shù)據(jù)分析師、產(chǎn)品經(jīng)理,還是運營人員,都非常希望深入分析流量數(shù)據(jù),以此來洞察用戶,為各項業(yè)務的展開提供決策支持。業(yè)務線對流量分析的訴求十分強烈,數(shù)據(jù)團隊每周會收到幾十個流量數(shù)據(jù)相關(guān)的需求。
第三,人工提數(shù)方式處理需求。在數(shù)據(jù)團隊成立的初期,我們以人工提數(shù)的方式處理需求。業(yè)務人員每周會把需求提交給數(shù)據(jù)分析師,數(shù)據(jù)分析師進行排期、寫 SQL 提數(shù),最后把數(shù)據(jù)反饋給需求方。這種方式非常的原始低效,一方面,業(yè)務人員要等較長的時間才能拿到結(jié)果;另一方面,人工處理需求的成本非常高,當時我們有兩個數(shù)據(jù)分析師全人力投入支持。
APPDATA 產(chǎn)品定位
針對上述流量分析場景的特點,我們希望能有一款自助流量分析的數(shù)據(jù)產(chǎn)品,提供給業(yè)務人員,快速高效的響應流量分析的需求。同時,也可以將那兩個 all in 在 流量數(shù)據(jù)提取工作上的數(shù)據(jù)分析師解救出來,讓他們能專注到更需要「人智」的數(shù)據(jù)處理工作上。這款自助流量分析產(chǎn)品就是 APPDATA。我們盤點了之前收到所有流量分析相關(guān)的提數(shù)需求,梳理出了 APPDATA 的 Feature List:
多維查詢:提供在不同維度組合下,頁面/自定義事件的PV、UV、停留時長等指標查詢;
自定義漏斗分析:支持用戶自定義漏斗轉(zhuǎn)化路徑,由系統(tǒng)計算出漏斗每步驟的人數(shù)、轉(zhuǎn)化率;
留存分析:提供留存分析,幫助產(chǎn)品做黏性分析;
用戶畫像:實現(xiàn)流量數(shù)據(jù)和用戶畫像標簽數(shù)據(jù)的聯(lián)動,提供用戶畫像信息查詢;
我們希望通過這四個功能覆蓋 80% 的流量分析需求,通過產(chǎn)品滿足數(shù)據(jù)分析,讓大數(shù)據(jù)在驅(qū)動業(yè)務中工具化,自動化。
早期方案和挑戰(zhàn)
明確產(chǎn)品規(guī)劃之后,我們開始推進產(chǎn)品落地。
早期方案
立項之初,出于效率優(yōu)先的考慮,采用的方案如下圖所示:

用戶訪問客戶端產(chǎn)生埋點數(shù)據(jù),上報到數(shù)據(jù)團隊的集群,落到 Hive 中,數(shù)據(jù)分析師根據(jù)業(yè)務人員的查詢需求,提前編寫相應的 SQL 邏輯,在 Hive 中進行計算,通過流程引擎每天將數(shù)據(jù)結(jié)果導入到 MySQL 中,前臺再根據(jù)相應的篩選條件,進行數(shù)據(jù)查詢以及結(jié)果呈現(xiàn)。早期方案能實現(xiàn)以下功能:
- T+1 的單維度下,頁面/自定義事件的PV、UV、停留時長指標查詢;
- 自定義漏斗分析,但漏斗模型配置后第二天才會生效輸出數(shù)據(jù);
- 有限的留存數(shù)據(jù)查詢,僅支持每個埋點的次日留存人數(shù);
可以看到早期方案實現(xiàn)的效果遠未達到最初產(chǎn)品規(guī)劃的效果,僅能覆蓋最基礎(chǔ)的流量數(shù)據(jù)查詢需求。然而,隨著業(yè)務的發(fā)展和業(yè)務人員數(shù)據(jù)意識的增強,對流量數(shù)據(jù)的查詢越來越精細化,用戶希望得到更豐富的維度、更及時的數(shù)據(jù)。
早期方案面臨的挑戰(zhàn)
早期方案存在怎樣的問題,導致 APPDATA 無法滿足精細化的流量數(shù)據(jù)查詢?總結(jié)有以下四個原因:
- 僅支持單維度條件查詢,UV 無法實現(xiàn)二次聚合。UV 的計算不是單純的相加,需要依據(jù) UID 做去重計算。早期方案需要數(shù)據(jù)分析師根據(jù)用戶的查詢需求,提前編寫 SQL 計算邏輯,而多維度下的 UV 查詢需要根據(jù)用戶的查詢條件實時做去重計算,很顯然早期方案無法做到。
- 用戶自定義的數(shù)據(jù),如漏斗分析,配置需要 T+1 才能生效。用戶在系統(tǒng)上新建漏斗,需要第二天才能看到結(jié)果。這個延遲是非常影響業(yè)務,因為新加的漏斗,往往會包含新上線的埋點,那么新上線的埋點需要 T+1 出數(shù)據(jù),漏斗配置又需要 T+1 才有數(shù)據(jù),無法在最好的時機支持運營策略和產(chǎn)品設(shè)計上的調(diào)整。
- 人工編寫 SQL 計算邏輯,維護起來很困難,開發(fā)周期長。APPDATA 上流量指標的計算較為復雜,由數(shù)據(jù)分析師編寫 SQL 邏輯,維護起來很麻煩,當有調(diào)整時,需要一定的開發(fā)周期,無法快速響應業(yè)務上的訴求。
- 埋點數(shù)據(jù)量龐大,導致 MySQL 查效率低。系統(tǒng)時常出現(xiàn)查不出來數(shù)據(jù)的情況,使得用戶對系統(tǒng)的可靠性產(chǎn)生懷疑。
基于 Kylin 的解決方案
針對上述存在的諸多問題,研發(fā)團隊提出引入 Kylin 作為系統(tǒng)的核心計算引擎加以解決。
為什么選擇 Kylin?
回答這個問題,主要還是從實際面臨的問題出發(fā)思考。下圖的左邊是上文提到的早期方案存在的四個問題,右邊是 Kylin 的一些特性,可以看到 kylin 特性能較好的解決問題。

Kylin 是一個 OLAP 引擎,可以非??焖俚捻憫A繑?shù)據(jù)的多維查詢場景。對于 UV 二次聚合,可以將 UV 存儲成 Bitmap,這樣就可以實現(xiàn)根據(jù)用戶查詢條件的二次聚合;
Kylin 有靈活的框架,支持函數(shù)功能擴展,可以利用它提供的交集函數(shù)解決自定義數(shù)據(jù) T+1 生效的問題;
Kylin提供了一個可視化管理界面,只需在前期對數(shù)據(jù)做簡單的處理和轉(zhuǎn)化,后續(xù)的數(shù)據(jù)處理工作都可以在界面上完成,包括定義 Cube 模型、處理數(shù)據(jù)、到最后的查詢,不用寫一行代碼,可以大大的提高效率;
-
Kylin 使用 Hbase 來存儲數(shù)據(jù),不會有 MySQL 那樣存太多導致查詢效率低的問題。
除此之外,還有兩個原因:
一個是成本問題,Kylin 支持標準 SQL,可用使用 JDBC 連接,早期方案也使用 JDBC 連接,新舊方案切換成本比較可控;
Kylin 支持 T+0 Cube構(gòu)建,可以讓 APPDATA 提供 T+0 流量數(shù)據(jù)查詢,我們認為實時數(shù)據(jù)的查詢也是非常有必要的。
基于上述的這些原因,我們選擇引入 Kylin 作為 APPDATA 的核心計算引擎。
Kylin 和 APPDATA 結(jié)合的技術(shù)架構(gòu)
APPDATA 和 Kylin 結(jié)合的技術(shù)架構(gòu)圖如下所示:

從左往右,客戶端產(chǎn)生埋點數(shù)據(jù),上報到大數(shù)據(jù),這些數(shù)據(jù)首先通過 Kafka 接進來,對于 T+1 的數(shù)據(jù),數(shù)據(jù)寫入 Hive,每天的凌晨根據(jù)事先寫好的 SQL 邏輯對數(shù)據(jù)做簡單的處理和轉(zhuǎn)化,最終形成一張寬表, 然后根據(jù)配置好的 Cube 模型,每天構(gòu)建一次,然后將結(jié)果數(shù)據(jù)導入到 Hbase。對于 T+0 的數(shù)據(jù)處理,數(shù)據(jù)進來后會落到 kafka,在兩個 kafka 之間我們用程序做了數(shù)據(jù)轉(zhuǎn)化的工作,最終的效果也是形成一張寬表,這里和離線數(shù)據(jù)不同的是,Cube 構(gòu)建是每十分鐘構(gòu)建一次,同樣的,結(jié)果數(shù)據(jù)也會導入到 Hbase。數(shù)據(jù)都準備好之后,剩下的就是響應用戶的查詢了。
新方案能做到哪些早期方案做不到的功能:
- 多維查詢:系統(tǒng)有十多個維度可以相互交叉,并且和任意日期關(guān)聯(lián)。在新的方案中,對于這種多維的查詢,不再需要像以前一樣,提前梳理用戶可能查詢的指標,對數(shù)據(jù)建模,然后再進行復雜的數(shù)據(jù)處理,只需要對數(shù)據(jù)進行簡單的處理和轉(zhuǎn)化,配置好 Cube 的模型,然后構(gòu)建 Cube,APPDATA 根據(jù)查詢條件生成相應 SQL 請求 Kylin,就可以得到結(jié)果,整個過程非常的優(yōu)雅;
- 虛擬埋點:虛擬埋點就是若干個埋點組合成的埋點,在很多場景下,只查詢單個埋點的數(shù)據(jù)是不夠的,需要拉通全域流量數(shù)據(jù)來看。而虛擬埋點涉及到 UV 聚合去重,早期方案是做不到的,而在新的方案中,只要用戶把這個虛擬埋點具體包含哪些埋點告訴系統(tǒng),系統(tǒng)生成 SQL 去查詢 Kylin 就可以;
- 自定義漏斗2.0:在新方案中,我們利用 Kylin 提供的交集函數(shù),實現(xiàn)了漏斗配置后即刻返回結(jié)果數(shù)據(jù)的效果;
- T+0 流量數(shù)據(jù):新的方案實現(xiàn)了 T+0 的流量數(shù)據(jù)查詢,端到端的延遲大概是15分鐘左右。
顯然,新的實現(xiàn)方式能夠更近一步支持精細化的流量分析,提供豐富的維度、T+0 的數(shù)據(jù)、即時靈活的自定義數(shù)據(jù),讓系統(tǒng)的功能得到了非常強大擴展。
數(shù)據(jù)情況和運行效率
硬件配置
Kylin 集群總共有三臺服務器,一臺用于構(gòu)建 Cube,兩臺用于查詢;HBase 服務器一共八臺,每臺機器內(nèi)存 256GB,CPU24 核,硬盤 8TB;計算集群服務器 60 臺,內(nèi)存 192GB,CPU 24 核,硬盤 144TB。
數(shù)據(jù)量
目前 APPDADA 生產(chǎn)線上有 5 個 Cube,每天有八九億的數(shù)據(jù)增量,提供近半年數(shù)據(jù)查詢,共累計了 10+T 的數(shù)據(jù)。接入了 8 個客戶端,覆蓋公司所有業(yè)務線的流量數(shù)據(jù)。
并發(fā)量
APPDATA 以 Web 服務和 API 兩種形式服務于公司內(nèi)部業(yè)務人員和業(yè)務系統(tǒng),業(yè)務人員的數(shù)量在 150 個人左右,對接廣告系統(tǒng)、活動運營平臺兩個業(yè)務系統(tǒng)。
查詢效率
查詢的效率依賴于查詢條件的復雜程度,經(jīng)過簡單的測試,目前我們 85% 的查詢是小于 800 毫秒,95% 的查詢小于 3 秒,99% 的查詢小于 7 秒。
調(diào)優(yōu)和改造
在文章的最后,介紹在使用 Kylin 的過程中,做的一些調(diào)優(yōu)操作,以及為了實現(xiàn)業(yè)務上的需求,對 Kylin 做的一點改進。
性能調(diào)優(yōu)
首先,我們對維度做了優(yōu)化。Kylin 核心的工作就是構(gòu)建 N 個維度的 Cube,實現(xiàn)聚合的預計算。理論上,構(gòu)建 N 個維度的 Cube 會生成 2 的 N 次方個 Cuboid。隨著維度的增加,Cuboid 的數(shù)量會爆炸式地增長,給 Cube 的構(gòu)建帶來巨大的壓力。而在實際數(shù)據(jù)查詢中一些維度之間的組合是不必要的。這樣就可以通過修剪無查詢需求的 Cuboid,來緩解 Cube 構(gòu)建的壓力。
第二個是 Rowkey 的順序優(yōu)化。一般而言,Kylin 以 HBase 作為存儲引擎,而 HBase 是以 Rowkey 順序存儲行的,設(shè)計良好的 Rowkey 將更有效地完成數(shù)據(jù)的查詢過濾和定位,減少 IO 次數(shù),提高查詢速度。這意味著我們可以把查詢中被用作過濾條件的維度放在非過濾條件維度的前面,基數(shù)較高的維度,放在基數(shù)較低維度的前面,這樣就可以跳過一些不必要的掃描,快速的定位到查詢場景。通過種方式,可以將絕大部分的查詢效率穩(wěn)定在亞秒級。
上述的這兩個調(diào)優(yōu)操作都能在 Kylin 提供的可視化界面的「高級配置」設(shè)置完成。
在應用層面的一點改進
為了幫助提升產(chǎn)品關(guān)鍵路徑的轉(zhuǎn)化,我們支持產(chǎn)品同學到 APPDATA 上構(gòu)建漏斗,上文中提到我們用 Kylin 提供的交集函數(shù)來計算漏斗數(shù)據(jù)。假設(shè)一個兩步的漏斗,計算時,先分別獨立計算訪問過兩個步驟的用戶數(shù),得到的第一步的用戶數(shù)作為第一步的人數(shù),然后求兩群人的交集,得到的人數(shù)作為第二步的人數(shù)。這里的求交集就是用到交集函數(shù)。
為了滿足業(yè)務上的需要,在配置漏斗時,每一個步驟可以是單個的埋點,也可以是由多個埋點組合成的虛擬埋點。而單個埋點和虛擬埋點是有差異的,前者是物理上的概念,后者是邏輯上的。Kylin 原本提供的交集函數(shù)只能支持物理概念上的單個埋點,而不支持多個埋點組合成虛擬埋點,也就是說,不可以先對單個埋點求并集,然后再求交集。在這里,我們所做的改造就是擴展交集函數(shù)支持邏輯上的虛擬埋點??梢钥吹綌U展后,我們可以先讓單個埋點做或者運算,再求交集。

我們用擴展后的交集函數(shù)計算漏斗和留存數(shù)據(jù)。對于漏斗,用戶先創(chuàng)建虛擬埋點,綁定若干個埋點,再創(chuàng)建漏斗,后臺調(diào)用交集函數(shù),給出結(jié)果。對于留存數(shù)據(jù),用戶也是先創(chuàng)建虛擬埋點,系統(tǒng)調(diào)用交集函數(shù),計算每個虛擬埋點的日留存、周留存、月留存數(shù)據(jù)。
寫在最后
本文最早發(fā)布在 apachekylin 公眾號,以及infoQ,如需轉(zhuǎn)載請注明出處和作者名字。