B站埋點數據標準化實踐
一、埋點標準化背景
1、埋點的定義
(1)什么是埋點
先舉一個實際的例子,比如用戶在某一時刻點擊了某個APP里面某個頁面上的推薦按鈕,這一信息將被記錄下來,會以一條日志的方式去做上報,存儲到服務器當中,這樣的日志信息可以定義為一個埋點。
埋點的結構可以抽象為who、when、where、what、how這五個關鍵詞,記錄用戶在APP、網頁或小程序里面一系列的行為。實際上不管是用戶在客戶端的行為,還是在接口日志的變更記錄,都是埋點的一種類型,這就是常見的客戶端埋點以及服務端埋點。
(2)埋點的作用
日常工作中,非常常見的一類數據是,統計APP的日活、每一天的新增用戶、新增用戶路徑流轉等,這些數據是偏分析用的。另一類是推薦算法的調優等。這些都是常見的埋點的應用場景,需要應用到埋點處理后的數據。
如上圖中可以看到,用戶點擊推薦按鈕,就會有JSON格式的日志上報,這份日志整體可以劃分為兩個部分,是典型的上報埋點日志格式,包括用于定位用戶ID、操作的時間戳、操作的類型,以及業務所需要的一些參數,比如點進去的位置,這個頁面的名稱等等。
2、埋點數據鏈路
埋點的應用過程會有一個比較長的鏈路。這里以B站的埋點應用鏈路為例,做一個簡單的拆解。
圖中從左到右是埋點數據從生產到消費使用的整個過程,底層的埋點測試與埋點元數據管理是做數據應用支撐管理的一部分。
從生產環節來看,業內都會將埋點采集抽象為可復用的埋點數據模型并集成到SDK內,避免每次業務開發都要重新定義采集的格式規范。這個SDK通常會劃分為iOS、安卓、Web、服務端等等,還有以backload的方式批量導入的離線數據,這是數據的生產側。
在數據流轉側,通過抽取轉換加載(ETL)的方式進入到傳輸流,這里有兩條鏈路,一部分業務需要消費數據實時流,另一部分業務是消費離線數據。實時流的消費可能會用于算法推薦,或者實時的數據分析,實時的監控看板。離線的數據,就是關于數倉的ODS到DWD,再到ADS的這個部分。在離線存儲的部分,數據的存儲會采用不同的介質,比如常見的HDFS、Parquet等等。查詢引擎包含了ClickHouse、Presto、Hive等行業內主流引擎,B站也提供了一個可視化的Web,給產品經理、分析師、運營等同學去操作分析。
B站的同學通過點選的操作去查看埋點常見的PV、UV數據,前端把操作拼接的參數傳給查詢引擎,作為查詢SQL的拼寫。業內關于查詢引擎的采納,根據每個公司的數據量會有多種不同的方案。常見的情況是:如果數據量比較小,那就直接用Hive查詢,如果數據量多一些,那可能會用Presto。目前對于B站的日增千億的數據量級,采用的是ClickHouse作為查詢引擎。
為支撐整個數據鏈路,還會采用埋點測試去保障埋點數據質量。再往下是埋點元數據管理,這也是本次分享的重點內容。
3、常見業務問題
在業務服務、業務支持過程中,面對非常多的業務痛點,主要可以歸納為兩大方面:生產設計和消費使用。
- 生產設計方面
首先,最常見的問題就是屬性命名,不同的業務和開發團隊有著不同的命名偏好,有的人喜歡駝峰命名,有的人喜歡用下劃線做分割,有的人喜歡用中劃線去做分割,這會導致埋點非常混亂,需要統一命名的規范。
第二個問題是在埋點上報的時候,有記錄業務屬性的參數,在業務實際的管理過程中,可能會出現參數枚舉的映射值找不到了,比如原本是小寫的abc,另一個業務用的是大寫ABC,業務值的映射方向混亂會導致埋點管理的混亂。
第三個問題是在埋點生產的過程中,會涉及到數據產品、開發人員、測試人員以及線上的應用方,參與方越多,各方的埋點信息越可能對不齊。
最后一個問題是,用Excel或文檔來管理埋點,數據量少的時候是可以操作的,但是數據量多、交接的人員多的情況下,信息失真就會比較嚴重。
- 消費使用方面
第一個問題是,運營常常會向產品發起拷問,頁面上對應的埋點是哪個ID?在數據里面找不到。
第二個問題,查詢埋點數據的時候,應該查詢哪一張表,過濾哪一個埋點的參數,私有參數是什么。
第三個問題,數倉治理時,存儲的壓力非常大,并非所有的業務埋點都是一定會使用的。其中有一部分比如曝光的埋點,它的性價比會比較低,那么可以考慮做分級的存儲。
第四個問題是關于權限,運營需要查詢某一個埋點的數據,是否要全部開放還是只開放一部分,需要精細化管理。
二、標準化實踐策略
針對上述問題,B站提出了從埋點生產到消費下線全生命周期的管理。其重點就是在埋點元數據管理這一環節。
1、B站埋點數據的現狀和歷史迭代
目前,B站線上有1萬+的客戶端埋點在應用中,整個埋點的元數據量非常大。另外,各類網頁Web端有10萬+埋點。日增量數據上報,達到了千億級別,一周就會達到萬億級別,數據量非常龐大。
在歷史上,埋點的迭代經歷了三個半階段。
- 第一個階段是按業務需求定制化管理,比如采集播放詳情頁的瀏覽,一個埋點設計一個字段,存成一張Hive表或日志表。這種做法很明顯的弊端就是管理會非常混亂,數據只能一次性使用,沒有辦法做一個收斂。
- 第二個階段,在意識到埋點應該做抽象化跟模型的設計后,就開始引用事件模型,但引入了事件模型以后,沒有做產品化工具化的支持,還是由業務去做管理。
- 第三個階段,在事件模型的基礎上,抽象出了b站業務埋點的特征。統一定義了公共字段,不管這個業務私有的屬性要不要上報,公共字段要求統一上報。在SDK里面減小業務重復開發成本,再加上業務自定制事件,已經具備了抽象的雛形。
- 從19年開始,進入到一個新的階段,開始逐步規范SPMID的埋點模型,加上沉淀出來的產品化管理,輔助以工具跟模型產品,去進行規范的定義。
2、埋點設計
在埋點標準化設計的過程當中,有4個重要的部分:埋點命名規范,埋點屬性管理,工具化支持,以及流程與規范。
(1)埋點命名規范
首先來看一下埋點的命名,很多業務會各自命名埋點的eventID,需要一個低門檻的工具管理埋點的eventID,不需要思考怎么樣命名,也不要去做隨機的編碼,而是要有一個高業務可讀性的ID信息。另外,幾個版本需要有可延續性,不要過幾個版本就混亂了。要求可交接或者可讀性,在版本之間的遷移度是較高的。最后,還需要有一個工具保證不同維護人之間可以順暢交接。
B站在標準化實踐中引入了spmid(super-model)模型。在埋點的eventID中包含業務的實際信息,將各業務含義抽象在埋點ID當中,然后將這個ID進行維表化的管理。整體分成五個部分,包括業務ID、頁面ID、模塊、位置和埋點類型。通過規范的命名可以提升整個業務的可讀性,在做埋點數據治理時,可以合理的定位問題,降低埋點的成本。相同的命名,不同的埋點類型可以做到復用。
上圖中展示了一個實際的例子,在埋點的首頁,推薦按鈕應該如何命名?這個埋點可以命名為bili.homepage.top-tabbar.0.click,這樣一個命名中包含了很多業務使用的含義。拆解來看,這個埋點實際上包含四個業務粒度及埋點類型的元信息。業務的粒度從粗到細,覆蓋了business_id、page_id、model_id、position_id。
對于使用者來說,拿到這個eventID以后能快速地定位到這個埋點所處的頁面模塊、位置模塊,以及在哪一個頁面homepage,所屬的業務線是哪一條,能夠精確地定位它所處的業務線對應的信息。
這個業務埋點ID,對于做一個定位或者類型的劃分,能夠做到業務的可讀性非常高,分攤業務埋點的成本,并且復用性非常高。點擊的埋點命名為click,那同樣一個模塊,曝光的埋點,命名為show就可以了。
在做埋點的時候,上報的時候會劃分為客戶端SDK上報以及服務端上報。客戶端通過埋點的類型劃分,包括啟動、瀏覽、曝光、點擊、播放、系統以及其它事件。服務端包括這個API的請求記錄,以及業務端業務表的日志變更信息。
上述就是B站關于埋點的命名的一些經驗。
(2)埋點屬性管理
在埋點上報的時候,有一個很重要的部分是記錄埋點的屬性參數。埋點屬性在業務含義當中是對用戶有一些定制采集的信息。會做三個層級的劃分:
首先是全局公共字段,包括埋點事件ID、APP信息、觸發的時間戳、觸發時間的網絡、運營商、操作系統的版本等等。
第二個是針對不同的埋點類型,包括頁面瀏覽PV、播放,或者業務特色的業務內容埋點,抽象出這個類型通用字段去做一個具體的預填充。
這兩個部分都是預設在SDK當中,業務開發無需二次處理。
第三個部分就是業務定制化的私有參數,比如做海報輪播的時候,需要這個海報輪播的bannerID,或者這個海報對應跳轉up主的mid等參數,就是業務它自定義去使用的參數信息。
在業內有另外兩種主流的方案,一種是采集參數,平鋪預留10-20個param的私有參數,另外一種就是只區分公共屬性跟私有字段的屬性。這兩類方案的問題是擴展性會有一些欠缺,雖然在早期的時候可以快速地去輔助業務的數據采集,但是后期的治理成本比較高。經過長期的實踐發現,采用公共字段+類型通用字段+私有字段這種方式,是一個比較通用,而且擴展性比較強的埋點屬性規范方式,保證了靈活性和擴展性。
關于埋點屬性規范,在數倉中,比如一張Hive表,會有表字段級別的數據標準。在埋點數據當中,把埋點抽象為業務表,埋點的屬性實際上映射為表當中的字段,所以引申出來,它也有屬性標準。
一個管理的規范會劃分為三大類,一類是基礎的描述信息,第二類是屬性的質量,第三類輔助去做屬性管理所使用的信息。
第一類基礎屬性,常見的有命名規范是否符合下劃線連接、點號連接,中劃線連接。數據的類型,到底是字符串還是數值,還是枚舉類型。
第二個部分是它的數據質量,包括埋點是否為空值、枚舉值,默認值應該填充為Null,還是一個中劃線,這些是后面做埋點測試的時候使用,測試規則都是基于這部分埋點的屬性標準。
第三類是元數據集管理,包括埋點的版本,屬性的優先級、安全等級等等。以B站為例,安全等級會劃分為S級、A級、B級、C級、D級幾個不同的等級,其中S級是最重要的一個安全等級。
(3)工具化支持
我們希望應用工具去做SPMID的模型支持,而避免讓業務同學人工選擇。B站內部沉淀了一款叫做北極星的埋點管理工具。
上圖中可以看到,這是一個埋點事件創建模塊,將埋點的業務、頁面、模塊、位置、類型都抽象為了維表化的選擇。創建埋點的運營和產品只需要去做下拉點擊的篩選,而不需要去從頭去做一個埋點設計。如果有歷史的埋點,做一個快速地復制,修改一些參數信息即可。
第一部分是埋點的命名。第二部分是去做埋點屬性的標準化,包括屬性ID、屬性顯示名,屬性的枚舉類型等等。第三個部分是業務比較關注的上報時機,埋點是否需要做抽樣上報,以及配置遠程是否停止采集。
上述的幾個部分都做了維表化抽象,每個環節、每個模塊都有一個對應的管理列表,結構化存儲在業務表中,方便下游的使用。
以圖中模塊列表為例,對應的埋點模塊已經做了一個標準化的命名,它的英文ID跟中文含義相互映射。
在使用過程當中,只需要做一個查詢,就可以知道對應模塊是使用在哪一款產品,以及哪一個業務線當中的,做到了層層遞進,維表化的復用。
(4)流程與規范
B站把整個埋點流程及規范,劃分為了六個環節以及四個重要的參與方。
四個重要的參與方分別如下,業務同學提出了需求以后,給到數據產品同學,數據產品把業務需求抽象為埋點需求文檔,稱為DRD,然后跟開發進行可行性方案的評審,根據優先級、成本去進行評估,最后落地為開發排期進行需求上線,需求開發完成通過測試,再給到數據同學進行分析。
六個環節除了包含上述四個參與方的環節,還包含數據采集和驗證。開發根據這個需求文檔進行埋點開發,對服務端或者客戶端的行為去做接口日志的采集存儲,最后交由數據產品或者測試同學進行埋點測試。測試會借助到埋點管理工具當中的一個測試模塊。最后測試完成,進行上線使用。上線的場景包括指標分析、算法推薦,輸出數倉的中間表、數倉ADS層的應用,以及數據看板等等。
3、基于埋點標準化元數據的提效應用
B站在關于數據標準化的實踐上,還提出了應用提效,存儲、規范的埋點元數據,這并不是為了管理規范而規范,而是有實際應用場景,發揮埋點的價值。可歸納為三個應用場景,第一個是數據報得更準確,第二個是存儲成本變得更低,第三個是查詢變得更方便。
(1)上報更準確
為了讓上報變得更準確,有一個很重要的工具,埋點測試的時候能夠快速精準、半自動甚至是全自動能夠發現業務上報的問題點在什么地方。在埋點設計的時候,根據業務的需求抽象為DRD,這部分會錄入到結構化的埋點管理工具當中,埋點管理工具去生成測試校驗或者DQC校驗的一些規則,比如枚舉空值、默認值以及值范圍等等。
同時在埋點進行抽樣,配置元數據信息下發到客戶端SDK。通過這個環節,測試機可以在測試后臺進行掃碼,通過SDK上報埋點參數,服務端進行埋點的接收,對埋點日志進行解析,包括實時的Kafka或者JSON格式的數據,解析到測試鏈路當中。
測試鏈路分成兩個部分,一個是匯總展示的日志報告,另外一個就是明細測試數據的解析,在測試機上觸發哪些埋點的規則,命中了模塊中哪些校驗規則,哪些是達標的,哪些不達標?不達標的原因是什么?通過整個從生產到測試傳輸鏈路流程的支持,提升埋點上報校驗的質量和效率。
從實際效果來看,可以通過手機客戶端的APP掃碼連接埋點測試模塊,測試模塊能夠實時地接收到上報端使用到的埋點數據,并且能夠映射到之前在源數據中已經錄入的中文名、埋點的屬性、DQC等規則,進行實時的校驗判斷,匯總并生成可視化的測試報告。基于埋點標準化的元數據,B站能夠做到近實時的效果檢驗,覆蓋了APP、web端以及服務端的埋點測試。
如果測試環境中的埋點數據出現缺失,通過這個鏈路能夠迅速回填到埋點管理的環節當中,做到埋點數據標準、快速的回補。從而保證上報得更準確,而且讓測試工作變得更簡單、更直觀。
(2)存儲成本變得更低
數據存儲的壓力,實際上在埋點部分會更突出、更嚴重。如果埋點的數據不做存儲的降本增效,那么成本是非常高的,因為有很多的業務會出現這種情況,不管有沒有用,先上報上來,這意味著埋點數據有泛濫的傾向。
所以我們在埋點源數據下游的管理方向上,按照業務進行分庫分表,這樣存儲管理就變得更容易,中間表按照業務類型進行劃分,按照業務的businessID,也就是埋點的首位ID,做業務的分表,在數倉DWD層或者DWS層,按照這個分層是一個很好的依據。
除了業務的分區分表,同時也可以降低存儲周期。有了eventID的元數據,將埋點的等級劃分為S級、A級、B級、C級,不同的等級對應到不同存儲的周期,不同的存儲粒度。同時針對不同的埋點類型,不管是點擊曝光頁面瀏覽,針對性地去做埋點的抽樣上報。
對于曝光類的埋點,很多時候業務價值是比較低的,重點只是想看一下模塊曝光PV跟UV。但是對于點擊類的埋點,它的業務價值會高一些,會詳細地區分用戶主動觸發的這一類埋點,比如點擊、啟動。不同埋點類型,對應不同的性價比,根據不同的性價比可以做埋點的抽樣,比如抽10%、20%或1%,或者埋點已經下線了,遠程進行下線開關的配置。
(3)查詢變得更方便
在做埋點分析的時候,希望盡量去代碼化,以工具和前端交互UI頁面提供給分析師和產品經理,這樣的方式會更友好、更直觀。
已經準備好了埋點的元數據,提供一個前端查詢的頁面,通過獲取用戶前端的操作,跟埋點管理的元數據模塊相互結合,以及DB層面上存儲好的埋點的元數據,發起查詢的SQL,返回查詢結果的結果集,進行一個可視化的BI展示,支持折線圖、柱狀圖的等多種可視化圖形。
在這一過程中可以看到,查詢的SQL或者查詢的字段,會依賴前置的分區去做查詢的加速,并降低成本,提升整體的效率。
B站內部已有服務于業務團隊的產品,圖中上方是做埋點分析的模塊,通過讀取埋點的元數據,做可視化展示,包括前置已經抽象出來的埋點私有屬性,這里能夠做兩個部分的分析,一個是去做快速篩選過濾,另一個是做分組展示。這里實現的分析的提效,都是依賴埋點數據標準化的存儲和管理。
三、后續展望
關于未來的展望,最近B站在做的探索是基于已經標準化的埋點元數據做自動化分流。業內經常所做的數據架構鏈路是分成兩個部分,一個是消費數據的實時流,經常使用的是Kafka;另外一個是消費離線的Hive表,去做ODS、DWD、DWS數倉分層的建設。如果已經接入了埋點的元數據,是否可以做流批一體的統一化管理,或者統一化的消費使用,做到一次的分流配置,它的實時跟離線均能夠生效,而且兩邊的口徑是對齊的。
對于下一步業務的分流使用,可以預設業務的中間表,有業務想要定制消費某幾個埋點,或者是某一些業務數據,通過埋點ID的劃分去做一個中間表,或者叫視圖級別的消費,減少下游讀取全表的查詢成本。
最后通過流批一體的鏈路做到線上實時高優消費埋點數據流,用于業務端的推薦算法等等。
四、Q&A
Q1:關于埋點的標準化管理,上線以后如何保障新舊數據兼容?
A1:假設在web端的埋點,有一套埋點管理的標準,在APP的埋點也有好幾套不同的埋點標準,在上報的埋點中,公共參數、私有參數埋點的命名規范不太一樣。有兩種處理的方案,第一種是在離線的數倉層面,做一個中間層的整合,通過離線數倉backload的方式,把歷史重要的埋點寫入到埋點數倉當中,增加埋點的eventID字段,做一個埋點兼容的處理。第二個方案是比如業務的埋點命名,相對還可以再搶救一下,它的埋點雖然有不規范,但是不規范程度并不是那么嚴重,還可以修改。對于增量的這一類需求,面向業務宣講,命名應該按照SPMID的模塊標準化進行,歷史可以用批量導入的方式做兼容。總體來講,就是按照存量跟增量以及業務不規范的嚴重程度,做兩類劃分處理。
Q2:B站埋點標準化的實踐,會展開ToB的產品化服務嗎?是否會做一個ToB的商業化?
A2:目前B站還是在內部去做ToB的服務,短期暫時內應該不會對外部做SaaS服務,但是可以和大家做一個交流。
Q3:如何理解曝光數據的抽樣上報?如果是曝光抽樣點擊全量上報的話,點擊率計算是否有問題?
A3:元數據記錄這個抽樣比例,下發給客戶端SDK。比如抽樣10%,一共觸發有10條數據,那SDK會上報1條。分析的時候要做一次轉化,比如PV上報的是1萬條,那實際上抽樣10%,那實際的PV那應該是1萬/抽樣率10%,也就是PV是乘以10倍,按這樣的方式進行轉換計算。
Q4:埋點需求如何滿足上線的時效性?如何做到跟業務的需求同步上線?
A4:其實就是文章中提到的協同環節過程,如何協同各方在合適的時間節點做埋點的上報,或者規范統一。比如運營提的需求已經提前先上線了,但是埋點需求還沒有補,實際上是流程中不太規范。
在B站這邊,實際在進行業務方案評審的時候,業務的需求文檔一定會包含埋點需求文檔,業務評審是包含數據采集的。業務模塊上線,那埋點采集也就同步上線了,同時錄入管理是一個通過流程協作規范的方式,評審環節就已經解決掉這些問題了。
還有一個同步上線的問題,可能存在歷史的模塊,它的埋點沒有采集,需要統一提某個版本的需求,做一個集中補充采集。
Q5:SPMID的規范設計工作會不會很繁瑣?
A5:如果純人工的方式去做埋點,SPMID的設計確實是非常繁瑣的,但是B站上線了這些功能:快速復制、一鍵復制、一鍵導入,用戶在做埋點設計的時候,是不需要從頭進行設計的。點擊復制,然后修改對應的模塊參數就可以了。SDK目前能夠下發到對應的埋點參數信息,部分公共參數是全部做到自動化采集。網頁端可以做到自動上報,APP端還需要做相互的check。