從0到1搭建技術中臺之A / B Testing 平臺實踐

自去年開始,中臺話題的熱度不減,很多公司都投入到中臺的建設中,從戰略制定、組織架構調整、協作方式變動到技術落地實踐,每個環節都可能出現各種各樣的問題。技術中臺最壞的狀況是技術能力太差,不能支撐業務的發展,其次是技術脫離業務,不能服務業務的發展。前者是能力問題,後者是意識問題。在本專題中,伴魚技術團隊分享了從0到1搭建技術中臺的過程及心得。

隨着伴魚業務的快速發展,公司內部越來越多的業務團隊希望通過更加科學的 AB 實驗( 以下簡稱「實驗」)來進行產品方案的決策。起初公司 AB 平臺(以下簡稱「平臺」)的技術方案參考借鑑於 google 論文以及業界分享的實踐案例,詳細設計和實現可參閱:AB 測試平臺的設計與實現。平臺上線後,通過不斷收集用戶的使用反饋,總結試驗週期內各環節存在的問題,我們歸納出平臺下一步需要重點改進的方向,主要包括:

  • 支持客戶端的接入渠道:前期只提供了服務端實驗的接入渠道,客戶端的實驗接入成本高。
  • 統一收斂分流邏輯:定向實驗的流量過濾邏輯散落在接入方的業務代碼中,一方面增加了業務接入的成本,另一方面過濾條件也難以在平臺進行直觀展示。
  • 優化分流及存儲方案:提供多樣化的分流方式,摒棄持久化的存儲方案,解決同層實驗飢餓現象。
  • 打造平臺數據閉環:從業務方提出實驗需求到進行實驗再到結果分析,整個鏈路的數據都能夠在平臺上做到統一流轉,避免一對一的線下溝通,減少人力成本,提升用戶體驗。
  • 優化實驗結果表達:基於統計學原理,對各項實驗結果進行科學的數據分析,並給出相應的量化指標,真實準確地反映實驗效果。
  • 支持事件通知機制:實驗週期內的關鍵節點通知責任人,做到實驗報告生成、實驗關閉等事件的及時感知。
  • 開放 API 能力:支持業務系統快速創建實驗,降低人力成本。

爲此,我們結合業務特點,對現有的框架進行了重構。目前新版平臺已經上線投入使用。

1. 系統設計

1.1. 平臺整體架構

以下是平臺整體架構示意圖:

通過上面這張圖,我們可以將平臺實現分爲以下幾個部分:
1、平臺接入方(即實驗代碼實現的位置),我們提供服務端和客戶端兩種接入渠道。
2、平臺內部實現,分爲「分流」和「管理」兩個部分。分流模塊主要是供在線業務調用,通過分流模型,得出分流結果。管理模塊則是實驗元數據、實驗效果數據等信息的管理後臺,提供可視化的操作界面。
3、周邊數據配套設施,包括實驗分流數據的上報、採集,指標數據的聚合計算。涉及指標庫以及數據處理等系統。

1.2. 接入方案

接入方式主要有 Service 和 SDK 兩種。Service 的方式即每次都通過 Rpc 來獲取實驗分流結果,有一定的網絡開銷,同時平臺將承受較大的壓力,但優點則是具有較低的接入成本以及平臺功能的迭代成本。而 SDK 的方式,是把分流模型直接放在接入方實現,平臺僅僅是下發影響實驗分流結果的元數據,這種方式大大降低了平臺承受的壓力,但接入成本提升了不少,每種類型的接入方都要實現統一的分流模型,進行統一的功能迭代。最終我們選擇採取 Service 的方式來進行方案的落地,接入方 SDK 保持了輕量化的設計。儘管隨着時間的推移,平臺承載的流量會逐漸增加,如何保障服務自身的穩定以及分流效率的穩定或許會成爲平臺未來發展的一大挑戰,不過這些都是後話了。

1.2.1. 服務端接入

服務端接入無需任何成本,採用公司統一的Rpc Client Adapter(由代碼生成服務直接生成) 直接訪問實驗分流接口,返回分流結果。

1.2.2. 客戶端接入

早期我們並沒有直接提供客戶端的接入渠道,客戶端上的實驗需要經由服務端配合纔可以完成,成本非常的高。考慮到客戶端的流量成本以及對分流結果的時效性要求高,平臺提供了批量獲取特定類型APP(我們的業務存在多種類型的APP,如伴魚繪本,自然拼讀等)上全部進行中的實驗分流結果。端在啓動的時候會批量拉取各實驗的分流結果,並在本地進行存儲,頁面上的各實驗通過 ABE SDK 直接從本地加載結果,並在固定的時間間隔後,再次拉取刷新數據。採用這種方式,分流結果的及時性得不到保障。但從實驗的整個生命週期來看,實驗效果的產出需要較長的時間週期(我們設定最短的實驗週期至少需要持續兩週,低於這個時間,實驗效果是不顯著的),這點時間的延遲是可以忽略的。

1.3. 實驗分流

一條實驗流量從進入系統到最終分配方案需要經歷三個階段:流量過濾、同層實驗分配、實驗內部方案分配。這些階段應當在平臺內部分流模塊中閉環實現。

1.3.1. 流量過濾

定向實驗指對特定的實驗流量開展實驗,這就涉及到對不滿足實驗條件的流量進行過濾。

平臺支持實驗條件可配置。條件可以由四元組構成,包括:「Key」、「Value」、「Operator」和「Type」。Key、Value 分別對應實驗的條件字段和期望值,Operator 表示比較算子,Type 表示條件類型,Operator 和 Type 是綁定的。由於 Operator 表達的語義有限(以 “大於” 比較算子來說,兩個字符串 A: “1.10.0” 和 B: “1.5.0” ,從普通字符串的語義理解,B > A ,但從版本號的語義理解,則 A > B ),因此增加了 Type 的概念。每種條件類型對應一系列比較算子。絕大部分場景「通用Type」即滿足我們的需求。目前通用Type提供了以下幾種算子,包括:

  • “=” 算子:等於比較符
  • “!=” 算子:不等於比較符
  • “>” 算子:大於比較符
  • “<” 算子:小於比較符
  • “in” 算子:包含比較符
  • “not in” 算子:不包含比較符

考慮到流量標識 client_id 含義的不確定性以及多樣性,平臺暫不支持通過 client_id 來定位實驗條件字段的條件值(即平臺內部打通各類型數據字典系統,如用戶畫像等)。獲取實驗分流結果時,實驗條件可以抽象成一個 Map ,接入方自行定義,傳入即可。

平臺對過濾條件逐一判斷,不滿足條件的流量直接返回兜底方案( fallback )。

1.3.2. 同層實驗分配

早期爲了追求分流結果的絕對穩定,採用了持久化的方案將結果存儲到了 DB 。這種方案實踐起來存在多種問題:

存儲不可估計,當前絕大部分的實驗是針對用戶的,client_id 一般爲 uid ,存儲規模相對可控。但如果實驗是基於事件的,client_id 爲事件 ID ,則存儲規模將劇增。
白名單方案調整受限,數據一經落盤,調整不再受控制。當然也可以針對白名單的分流結果不進行存儲,不過終究又是多了一個堆砌的 if 條件。

同層實驗分配產生飢餓現象。早期同層實驗分配採用「無權重無分桶」的方案,即將同層中進行的每一個實驗看做一個桶,對 key ( layer_id + client_id ) 進行 Hash 取模,命中哪個桶就分配至哪個實驗,無需擔心實驗增減導致分配不穩定,一個相同的 key ,只有一次分配機會,結果持久化後,下次分流直接返回結果了。通過這種方式,同層中前期進行的實驗可能“霸佔”了總體流量中的絕大部分流量。後期實驗只能“撿漏”,導致飢餓現象產生。

因此,分流結果持久化的方案需要廢棄。結果數據進行日誌埋點,最終收集起來,作爲實驗效果數據的數據源。同時不必擔心分流結果不穩定,分流算法可以保證。而對於實驗方案調整(增減方案或調整方案流量)等現象,我們增加了「實驗版本」的概念,一經調整,實驗版本將發生變更,實驗進入一個新的階段(類似於一次新的功能發佈上線),實驗效果重新計算。

既然廢棄了持久化的方案,同層實驗分配採用「無權重無分桶」的方案就站不住腳了(依賴持久化,否則隨着同層實驗的增減,分配結果就不穩定了)。同層實驗的分配方案應當是一個可選的集合。隨着業務的發展和平臺的迭代,將衍生出更多貼近業務的優秀方案。「分桶」的方式是最本質的一種實現方案,設定層的桶的總量(比如1000),實驗在設計階段,指定佔用流量的區間大小(平臺予以提示,防止一個實驗佔用過多流量,其他實驗無流量區間可以進行試驗的情況)。同時過期實驗佔用的桶,將採用「惰性驅逐」的方式進行清除,即每次新實驗在平臺創建時,如果準備選擇某一層進行試驗,在獲取該層可用的流量區間時,會進行驅逐操作。「城市分桶」的方案,則是對「分桶」方案進行了更貼近業務的一層抽象,把每個城市看成一個桶,試驗可以選擇在固定的一些城市進行。

1.3.3. 實驗內方案分配

實驗內部的方案分配應當同樣也是一個可選的集合。目前我們採用的是業界最常用的方式:隨機分組( Hash 取模分桶)的方式,對 client_id 加鹽後進行哈希取模,結果值進入不同的桶,每個桶歸屬於一個分組。這種分組方式是否均勻,有待結合後續更多的實驗進一步探究。業內也有提出其他類型的分組算法,相信隨着時間的推移,更多的算法將被我們在實踐中運用起來。

1.4. 數據閉環

實驗報告關注的數據(通常指業務指標數據)以及實驗報告的數據展現應當統一收斂在平臺內部,以達到更好的用戶體驗。試想,每次做實驗,都需要直接和數據同學人肉對接,無論是從成本還是體驗方面都很糟糕。而要到達數據閉環,得從以下兩個方面着手:

  • 指標服務構建:提供一套公司級的指標服務系統,維護每一個指標元數據信息(包括:統計口徑、數據源等)。指標數據可以源於業務中的日誌埋點或者是 Mysql 中的 binlog ,經過數據收集、清洗、計算得到。平臺通過打通指標系統,獲取實驗可以訂閱的指標。
  • 數據關聯:實驗數據和訂閱的指標數據關聯之後,纔可以得到我們的實驗指標數據。事實上,實驗數據自身就是一種指標數據,在每次拿到實驗分流結果時,都進行分流結果的日誌埋點,通過對這些日誌的收集處理便可得到實驗數據。值得一提的是,指標數據和實驗數據如何進行關聯?關聯的Key應該是什麼?我們以一個簡單例子來說明這種情況。產品設計了一個試驗(包括方案 A 和 B ),想要關注兩種方案下客戶訂單數的指標。這種場景下,我們可以將數據以 json 形式進行簡單地表述:
    1. 實驗分流明細數據
{
    "client_id":"123456789", 
    "experiment_key":"TEST",
    "experiment_variant":"A",
    ...
}
  1. 訂單寬表明細數據
{
    "order_id":"202006301111",
    "uid":"123456789",
    "phone":"18712344321",
    "price":"100.00",
    "discount":"0.95",
    ...
}

要得到每種方案訂單數,無疑需要進行 Join 操作。實驗分流數據肯定是要以 client_id 作爲關聯 key 的,其他字段從語義上不具備關聯的條件 ,但是由於 client_id 的具體語義系統沒有概念(例子中 client_id 其實表示的是 uid,但只有實驗 Owner 清楚),因此係統不知道該和訂單寬表明細數據中的哪個字段進行關聯。這裏我們採用的方法是:給每一個指標都增加一個表示主體的字段(其實就是通過這個字段,給指標信息中增加了一層和 client_id 對應的語義),那麼以 uid 爲主體和以 phone 爲主體的用戶訂單數就是兩個不同的指標,儘管二者的其他信息都是一樣的。這樣一來,實驗 Owner 在訂閱指標的時候,就應該選擇與 client_id 語義一致的指標了。

數據分析與結論

通常使用統計學中假設檢驗的理論來分析實驗指標數據。實驗組的效果是相對於對照組而言的,因此在查看實驗報告時,首先需要選擇對照組。

  • 顯著性水平( p-value ):就是當原假設(對照組和實驗組實驗效果沒有差異)爲真時所得到的樣本觀察結果或更極端結果出現的概率。如果 P 值很小,說明原假設情況的發生的概率很小,而如果出現了,根據小概率原理,我們就有理由拒絕原假設,P 值越小,我們拒絕原假設的理由越充分。p-value 表示的是實驗組相較於對照組統計的顯著性(即二者是否存在差異),它並不能告訴我們實驗組比對照組有多少提升。

  • 置信區間:實驗組相對於對照組的變化,可以使用 $$ \frac{(Value_實-Value_對)*100%}{(Value_對)} $$ 表示,這個是點估計,它是有誤差的。針對統計顯著的實驗組,我們需要區間估計的方法來得到一個概率範圍,以準確地描述實驗效果。通常使用 95% 的置信水平來進行區間估計。

實驗效果的科學系分析是一個很大的話題,目前我們採用以上兩種常用的方式,對實驗指標數據給予定性結論。當然結論的可靠性還受實驗樣本數、實驗樣本隨機性等因素的影響。通常,爲了進一步驗證實驗結論的可靠性還可以採取「AA測試」等方法進行前置驗證。此外,一個實驗往往可能會訂閱多項指標,指標數據並非表現出一致效果,需要整體的權衡和考慮。

1.6.事件通知

實驗的生命週期我們總結爲以下幾個階段:

  • 實驗設計階段:從平臺創建實驗開始,至業務代碼接入併發布上線。實驗 Owner(可以是產品或者業務研發同學)需要明確實驗的目的,仔細設計實驗方案及流量配比,綜合考量同其他實驗的相互影響以及訂閱實驗需要觀測的指標。
  • 流量接入階段:從線上分流請求進入平臺開始,至一定的實驗效果觀測週期爲止。此階段,實驗元數據(實驗方案、方案流量配比等)應保持穩定,一經調整效果數據將進入新的階段,觀測週期重新開始。
  • 效果產出階段:經過觀測週期後,實驗結論便產生了,可好可壞,需要實驗 Owner 決策實驗的下一步計劃。
  • 實驗關閉階段:實驗關閉後,需要業務研發同學及時清理實驗,避免不斷堆積的廢棄代碼。實驗關閉階段,實驗分流結果將默認爲兜底方案,不再支持灰度放量,以提升業務研發同學對關閉實驗後的代碼進行處理的意識。

在以上每個實驗階段的初始節點,通過發送事件,提醒實驗 Owner 執行相關的操作。

1.7. 開放API

爲了滿足業務多樣化的需求,降低試驗創建的人工成本。提供開放API的能力,可以支持業務通過腳本、代碼(內嵌於上層業務系統)等方式直接創建或修改實驗。

2.未來工作

隨着平臺在公司內部的繼續推廣,問題的暴露勢必會越來越多。目前可預見的需要加強完善的幾個方向:

  • 服務穩定性保障、優化分流效率
  • 更多樣化的分流算法,提升實驗科學性
  • 更健全、更科學的實驗分析手段
  • 內部指標體系深化建設

相關文章推薦:

《從 0 到 1 搭建技術中臺之推送平臺實踐:高吞吐、低延遲、多業務隔離的設計與實現》

《從 0 到 1 搭建技術中臺之技術文化篇》

《從 0 到 1 搭建技術中臺之協作方式篇》

《從 0 到 1 搭建技術中臺之報警平臺實踐:匹配器演進》

《從 0 到 1 搭建技術中臺之發佈系統實踐:集泳道、灰度、四端和多區域於一體的設計與權衡》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章