黃亦男 上海大學
隨著互聯(lián)網(wǎng)的高速發(fā)展,用戶的很多消費逐漸從線下轉(zhuǎn)移至線上,比如購物、網(wǎng)課、生活繳費等等,在大量的用戶數(shù)據(jù)中,包含著很多運營商感興趣的內(nèi)容。從運營的角度看,對于一個app 或者網(wǎng)站,一般都需要統(tǒng)計和匯報每天的登陸量,點擊量,消費情況,用戶身份,以及每個產(chǎn)品的用戶分布情況等,這些數(shù)據(jù)有些可以通過業(yè)務子系統(tǒng)輕易的獲取,但更多的需要結(jié)合用戶行為記錄分析才能知道,比如活躍用戶變化趨勢等。從產(chǎn)品的角度,則會關心用戶對某個產(chǎn)品的粘度,大概多少用戶登陸后會產(chǎn)生實質(zhì)的商業(yè)行為,體驗是否良好,新功能使用情況是否符合預期等。從戰(zhàn)略決策角度,數(shù)據(jù)能夠給決策者提供很多參考,哪個地區(qū)的潛在用戶量最高,則有必要在這個地區(qū)開辟業(yè)務,哪個渠道轉(zhuǎn)化的新用戶數(shù)最客觀,則應該增加這個渠道的廣告投放,比如頭條、微信等。數(shù)據(jù)越準確,越不會造成決策的失誤,可以有效的把成本轉(zhuǎn)化為利潤。
那這些數(shù)據(jù)是如何獲取的呢?想象在一家互聯(lián)網(wǎng)公司,產(chǎn)品經(jīng)理需要知道昨天成功注冊后購買某產(chǎn)品并且留下評論的人數(shù)、男女比例以便決定下一步的放量計劃,首先他需要聯(lián)系用戶系統(tǒng)的負責人獲得相關的用戶ID,然后通過用戶ID 在訂單表獲取產(chǎn)品ID,最后使用這2 個ID 在社區(qū)系統(tǒng)搜索評論。一次普通的查詢由于要橫跨3 個業(yè)務子系統(tǒng),關聯(lián)的id 還需要查詢?nèi)罩静拍塬@取,使得查詢成本非常高。而產(chǎn)品經(jīng)理由于職業(yè)特殊性,不可避免地會有經(jīng)常查詢這些用戶行為的需求,這些工作需要各子系統(tǒng)開發(fā)人員的配合才能完成,無形中增加了企業(yè)內(nèi)部大量運營成本。
為了提高數(shù)據(jù)獲取效率,目前互聯(lián)網(wǎng)公司通過自研大數(shù)據(jù)實時分析平臺來滿足各種數(shù)據(jù)查詢的需求,平臺通常滿足數(shù)據(jù)統(tǒng)一上傳管理,友好的服務界面以及提供了高效的查詢接口,平臺可以實時提供數(shù)據(jù)查詢,產(chǎn)品經(jīng)理可以迅速調(diào)整策略,比如根據(jù)實時運營情況,是否增發(fā)紅包,或者使用其他營銷方式。
數(shù)據(jù)處理一般分為數(shù)據(jù)采集,數(shù)據(jù)傳輸,數(shù)據(jù)建模/存儲,數(shù)據(jù)查詢和可視化處理5 個步驟。
1.1.1 數(shù)據(jù)采集
前端數(shù)據(jù)采集一般通過埋點的方式,將基本信息比如手機型號、ip、位置等和業(yè)務信息打包后,通過特定的端口向服務器發(fā)包,通常這類埋點會在app 初始安裝時獲得用戶的允許,基本信息的埋點稱為全埋點,覆蓋在前端框架中,業(yè)務埋點又稱為代碼埋點,與業(yè)務會有耦合。后端數(shù)據(jù)采集可以直接從日志中獲取信息,前提是把需要上報的數(shù)據(jù)提前打好標簽,這類采集傳輸可靠,信息更加完整。
1.1.2 數(shù)據(jù)傳輸
數(shù)據(jù)傳輸一般是各公司自研的部分,后端需要處理客戶端打點請求,由于網(wǎng)絡傳輸過程會增加額外的數(shù)據(jù)開銷,將數(shù)據(jù)反序列化后需要對數(shù)據(jù)做清洗,過濾以及去重,只留下有分析價值的內(nèi)容,并且還要考慮整體系統(tǒng)的可靠性和可用性,所以一般自研系統(tǒng)會優(yōu)先定義框架,再設計加工邏輯。
1.1.3 數(shù)據(jù)建模/存儲
區(qū)別于傳統(tǒng)的關系型數(shù)據(jù)庫存儲,大數(shù)據(jù)的存儲按照時間軸分布,采用多維讀的列示存儲,比如按用戶id,瀏覽過的頁面,點擊過的按鈕等結(jié)構(gòu)存儲。本文使用Kudu/Parquet 作為存儲引擎,類似于Hbase,MongoDB 等nosql 數(shù)據(jù)庫,可以實現(xiàn)一次導入,多次查詢,這樣設計的原因是大數(shù)據(jù)平臺主要為了查詢統(tǒng)計歷史數(shù)據(jù),沒有修改場景,同時這些加工后存儲的數(shù)據(jù)與正常的業(yè)務數(shù)據(jù)隔絕,即不會影響正常業(yè)務的運行。
1.1.4 數(shù)據(jù)查詢和可視化處理
數(shù)據(jù)查詢的輸入,一般仍然采取通用的SQL 查詢方式,將SQL語句翻譯為查詢引擎可以識別的查詢語言,比如Hive 使用Antrl 實現(xiàn)了對SQL 詞法和語法的解析,將SQL 轉(zhuǎn)化為MapReduce 任務。查詢輸出可以根據(jù)公司產(chǎn)品需求,設計為圖表、趨勢圖、油表等表現(xiàn)形式。輸入和輸出都需要企業(yè)做圖形界面做可視化支持。
本文針對數(shù)據(jù)傳輸,存儲和查詢,為大數(shù)據(jù)實時分析平臺做了以下的后端架構(gòu)設計。
1.2.1 數(shù)據(jù)接入子系統(tǒng)
Nginx 作為可靠的反向代理服務器,可以用來接收客戶端的打點請求,通過http 的方式,根據(jù)聲明不同的RestAPI 調(diào)用后方的Extractor。
Extractor 監(jiān)聽Nginx 轉(zhuǎn)發(fā)的請求,提供對請求處理的主邏輯,并作為kafka 生產(chǎn)者插入消息隊列,數(shù)據(jù)收集器根據(jù)訂閱的消息topic 來處理對應的請求消息。
1.2.2 ETL 子系統(tǒng)
ETL 子系統(tǒng)一般會和業(yè)務強關聯(lián),沒有開源軟件可用,這一層需要對數(shù)據(jù)做基本的清洗,過濾以及去重,比如系統(tǒng)間互相調(diào)用后留下的中間id 和http 頭部多余的報文,路由留下的內(nèi)網(wǎng)ip,保留的信息除了業(yè)務數(shù)據(jù)外,還有很多用戶相關聯(lián)的信息,比如UserAgent 中保存的端末信息,app 版本號,地域信息等。
1.2.3 存儲子引擎
Kudu 是cloudera 開源的運行在hadoop 平臺上的列式存儲系統(tǒng),擁有Hadoop 生態(tài)系統(tǒng)應用的常見技術特性,與imapla 集成或spark 集成后(dataframe)可通過標準的sql 操作,使用起來很方便。KUDU 同時兼?zhèn)銱DFS 批處理以及HBASE 的實時寫入更新的能力,底層使用類似parquet 的列示存儲結(jié)構(gòu),Tablet 是負責Table表的一部分的讀寫工作,Tablet 是有多個或一個Rowset 組成的,其中一個Rowset 處于內(nèi)存中,叫做MemRowSet,MemRowSet 主要是負責處理新的數(shù)據(jù)寫入請求。DiskRowSet 是MemRowSet 達到1G 刷新一次或者是時間超過2 分鐘后刷新到磁盤后生成的,實際底層存儲是是有Base Data(一個CFile 文件)、多個Delta file(Undo data、Redo data 組成)的和Delta MemStore,其中位于磁盤中的Base data、Undo data、Redo data 是不可修改的,Delta Memstore 達到一定程度后會刷新到磁盤中的生成Redo data,其中kudu后臺有一個類似HBase 的compaction 線程策略進行合并處理。本文將Kudu 保存當前實時的數(shù)據(jù),即1 小時內(nèi)所有的用戶請求數(shù)據(jù),Parquet 保存所有的歷史數(shù)據(jù),定時的數(shù)據(jù)轉(zhuǎn)儲shell 程序每小時運行一次。
1.2.4 查詢引擎
Impala 是Cloudera 公司推出提供對HDFS、Hbase 數(shù)據(jù)的高性能、低延遲的交互式SQL 查詢,Impala 對內(nèi)存的要求很高,和Hive 類似都基于MPP 查詢引擎,使用純內(nèi)存計算,效率高容錯性低,一般Impala會和hdfs同機部署,利用內(nèi)存計算的特性,避免網(wǎng)絡消耗。同時,為了盡量使用內(nèi)存計算的特性,避免產(chǎn)生不必要的IO,Impala會在源表存儲部分冗余數(shù)據(jù)避開表間的連接。Query Engine 是一個翻譯者中間件,將查詢的SQL 語句或command 翻譯為查詢引擎所能識別的查詢語言,類似Hive。
實驗數(shù)據(jù)采用某電商企業(yè)過去2 年的運營數(shù)據(jù),其中包括客戶端操作、日志、訂單數(shù)據(jù)、注冊數(shù)據(jù)、以及其他業(yè)務數(shù)據(jù)。
本文使用自研的ETL 系統(tǒng)來清洗數(shù)據(jù),目的是能夠快速通過時間維度和用戶維度來獲取用戶相關的信息,并分別保存在用戶行為表和用戶表中。盡可能使用少量的表,可以最大化利用Impala 內(nèi)存計算的特性,減少表連接。用戶行為表中會存放用戶在什么時間什么地方用什么渠道處理了什么業(yè)務,用戶表則用來保存用戶本身的屬性。
節(jié)點:阿里云ECS 三個節(jié)點
配置:CPU 8 核、內(nèi)存: 32 GB
操作系統(tǒng):CentOS 6.9 64 位
版本:Kudu 1.7.0
通過tpcds-gen 在hdfs上生成parquet 數(shù)據(jù),在控制臺運行--bash start.sh generate x
利用impala 將tpcds 數(shù)據(jù)從hdfs上導入至kudu,在控制臺運行--bash start.sh load x
表 行數(shù) 時間(秒)Kudu 數(shù)據(jù)導入 用戶行為表1,439,980,416 10.89 Kudu 數(shù)據(jù)導入 用戶表 12,367,428 15.67時間(秒)Kudu 數(shù)據(jù)查詢 平均人均月消費 7.26 Kudu 數(shù)據(jù)查詢 平均月增長用戶數(shù) 7.89
行數(shù)超過千萬量級數(shù)據(jù)表時,Kudu 的導入性能具有巨大的優(yōu)勢,針對 用戶行為表導入時間僅為10 秒,而針對較大規(guī)模的數(shù)據(jù),Kudu 的查詢性能同樣有較大的優(yōu)勢,對指定用戶特定業(yè)務行為查詢時間僅為7 秒。
本文使用Kudu 在3 個節(jié)點部署,10 秒內(nèi)完成了10 億條行為數(shù)據(jù)的錄入及分組聚合,證實了通過合理的數(shù)據(jù)接入方式(Http),合理的存儲模型(Kudu/Impala),可以有效簡化數(shù)據(jù)處理,針對特定場景的查詢優(yōu)化有顯著的效果,但對硬件的要求非常高,尤其是對內(nèi)存的要求。