干货 | 携程是如何做AB实验分流的
作者簡介
Will Wang,攜程技術專家,負責AB實驗分流和其他數據智能項目的開發。關注大數據和分布式方面,會做一些深入的開發部署和結合業務數據的基準調試工作。
一、背景???
攜程是業界比較早進行AB實驗的公司。AB實驗可以簡單認為是傳入一個實驗號和用戶分流ID到AB實驗分流器,分流器吐出分流版本A、B、C、D等,通過截取應用流量落地一段時間的分流數據,就可以分析具體版本的優劣,決定啟用新版本或者沿用老版本。???
攜程的AB分流器沿用至今,在業務發展上發揮了很大作用,但也存在一些問題。
1)攜程內部,除了攜程App,還有小程序、Online頁面等都在用AB實驗分流器,這些分流器是不同部門維護的不同接口,導致AB實驗人員在開發的時候,有時候會用錯,或者經過幾輪溝通才能找到適合的分流器接口;
2)AB實驗分流器在公司越來越多的AB實驗應用接入的時候,響應效率不盡人意,沒有開始的時候那么好。還有實驗新配置的分流規則,在一個訪問量大的頁面如攜程App酒店主頁上很難即時生效,有時候要等到凌晨訪問量較少時才生效;
3)AB實驗方法論也需要改進,從而更精確地指導AB實驗結論。但AB實驗分流器前端接口里直接引用了AB實驗配置表的全量字段信息,導致AB實驗配置表隨著AB實驗方法論改進更新的時候,AB實驗分流器也需要更新換代,這對公司的各個實驗應用方來說是不可接受的。
基于此,我們開始著手攜程AB實驗分流器的改進。AB實驗分流器的效率改進是重中之重,收口公司眾多的分流器接口,遷移舊接口流量到新接口和推進公司AB實驗應用采用新分流接口,這樣才可以適應AB新方法論上的AB實驗配置的更新迭代。
?
二、改進結果
截至到目前,除少量在2020年年底計劃下線的.net應用外,其他的應用都通過公司的slbportal工具把分流流量遷移到改進過的新AB實驗分流器接口,或者直接采用了新AB實驗分流器。下面貼上新舊AB實驗分流器的改進效果,供大家參考。
從以上的流量統計圖可以看出,新AB實驗分流器在QPS相應更大的情況下(200.7->290.2),P99.9線反而表現的更好(363.1ms->5.2ms)??梢娦翧B分流器的響應更快,對舊AB實驗分流器接口的效率改進還是比較顯著的。
??
三、改進方案
本文將從AB實驗分流器整體設計,收口,SDK設計和分流器后臺選型設計方面進行分享,主要說明如何提升AB分流器的分流效率,希望給AB實驗特別是AB實驗分流器的開發人員帶來一定的啟發和幫助。
3.1 AB分流器整體設計???
AB分流器整體設計是用SDK還是service方式,是一開始就要制定的,因為如果方向搞錯,后面都要重新來。
采用service有改動和運維方便等優點,但考慮到全公司都在使用AB分流器,如果用service方式,除了網絡訪問service影響分流效率外,攜程用戶的每臺手機,每個pc和小程序頁面等都可能調用到這個service,對service的沖擊還是很大的。
一個訪問量很大的AB實驗頁面,也會影響到其他訪問量相對小的AB實驗頁面,這也是不公平的。所以用駐留SDK的方式,把AB實驗分流器分發到各個部門的各個AB實驗應用中,讓各個部門自行根據AB實驗流量調配資源,分流效率也可以最大化。
3.2 AB實驗分流器收口
文章開頭提到攜程AB實驗幾乎在用戶能用到的攜程產品上無處不在,攜程App、小程序等,這些AB實驗調用的是不同部門開發的不同的AB分流器。
AB實驗最重要的是兩個口子,一個入口是AB實驗分流器,一個出口是AB實驗分析報表,入口要進的簡單,出口要出的明白。收口這些眾多的分流器接口到一兩個簡單接口,對AB實驗開發人員和AB分流器的開發維護都是有利的。???
下圖概括了AB實驗分流主要接口的收口工作(左邊是舊分流器接口,右邊是新分流器接口):
3.3 AB實驗分流器SDK設計
分流器收口的效果是顯而易見的,原來需要跨部門多個接口溝通解決的事情,現在一個部門一個接口就可以了,開發測試也方便。
新分流器SDK完全兼容舊分流器接口的業務功能,并做了一個主要的技術改進,從“胖”SDK變成“瘦”SDK。? ?
舊SDK中,當一個實驗分流請求過來后,會關聯查詢緩存里實驗的各種AB實驗表信息,如實驗域、實驗層、分流規則(分流桶)和指定版本等信息,然后計算一個分流版本信息返回。
新SDK緩存里只有一個類似AB實驗寬表的信息存在,這個寬表是影響實驗分流的各個字段信息的最小集,去除了舊SKD中的對分流結果無影響的分流頻道等字段信息。最小集定義好后,基本就固定不變了,舊SDK里的關聯查詢動作在新SDK里推到分流器后臺去做。? ?
上述最小集寬表的存在,讓AB實驗系統在改進AB實驗方法論后進行的不斷迭代開發過程中,不用頻繁替換AB實驗應用的分流器。因為、新AB分流器后臺會提前關聯查詢,組織好寬表數據提供給前端的分流器SDK使用就可以了。? ?
上述的減肥操作讓分流器SDK的效率提高一大截。另外舊分流器SDK的實驗緩存沒有讀寫分離的概念,當AB實驗頁面,如攜程App酒店主頁有大量并發請求過來的時候,有可能會導致AB實驗新配置的分流規則或者指定版本等很長時間不生效,新AB分流器SDK緩存引入了CopyOnWrite的設計,讓影響到分流的AB實驗改動能夠快速生效。
3.4 AB實驗分流器后臺選型設計
AB實驗業務特點是讀多寫少的,寫有單個數據的寫入,也有批量數據的寫入,采用CopyOnWrite設計可以很好地支撐這種場景,后面講到的分流器后臺分布式緩存系統也采用了類似的設計。??
舊AB實驗分流器后臺通過SOA服務直接讀取DB里的AB實驗分流配置信息,會讓DB成為AB實驗分流的瓶頸。SOA服務可以根據分流器請求的流量自動擴容縮容,但DB不是。DBA看到復雜的sql查詢,還有這么多的訪問量的時候,也是不允許的。
所以新AB實驗分流器后臺需要在DB前面多加一層前置的數據緩存系統來提高分流效率,這個緩存系統是采用公司成熟的qconfig還是redis,或者結合AB實驗特點自己部署一個分布式緩存系統呢?
AB實驗通用的業務操作是對一個實驗進行用戶分流,也有對同一類型的實驗進行分流,如攜程App對這個App版本下的所有App頁面端實驗進行分流,這也是為分流效率考慮的。???
qconfig可以進行簡單配置數據的實時推送,對于AB實驗這樣稍顯復雜并且是大批量的關系型數據是不太適合的。舉例來說,一個攜程App上的AB實驗分流器需要拿到所有手機頁面進行的實驗,是在qconfig上一個配置文件中配這些所有實驗,還是每個實驗一個配置文件?
單一一個配置文件會讓攜程App訪問公司qconfig服務器成為一個很大的IO操作,多個配置文件會讓攜程App收到這些改動的實驗配置信息后,還要進行聚合操作。qconfig中會存在一個“長連接”來進行實時配置信息推送,每個AB實驗應用的多個設備上都會建立一個和AB實驗分流后臺qconfig服務器上的這樣的連接?!伴L連接”是很難適時根據流量進行擴容和重連的,公司的災備演練過程中出現的apollo和qconfig配置系統負載過高就說明了這一點。因此新AB實驗分流器后臺的設計中首先排除了qconfig這一方案。
redis在公司和業界用的比較成熟,采用redis如出現數據問題,可以給到公司的redis框架部門解決。但任何設計都是為業務服務的,如果一個流行的方案不適合現在的業務,那就要考慮改進或者自行設計了。
還以攜程App頁面端實驗分流為例,可以把app頁面端單個實驗的名稱作為redis的key,value里存影響實驗分流的關聯字段信息。當更新一個或者多個app頁面端實驗,或刪除一個或者多個過期的app頁面端實驗的時候,批量讀取app頁面端實驗就會產生不一致的現象。
如果把這些批量的app頁面端實驗分流信息組合放在一個key對應的value里,這個key的讀取效率就會很差,會影響到其他類型單個實驗信息的讀取。AB實驗分流的字段信息比較多,就一個AB實驗指定版本varchar字段已經定義為20000還不能滿足某些部門的需求,可以想象多個實驗分流放在一個value里, size會有可能很大。
AB實驗分流的一致性設計要求是要高于時效性的,可以晚一點拿到最新的分流規則,但同一時間讀取到的實驗分流應該是一致的,這對于AB實驗報表分析也是有利的。
綜上所述,redis不大適合AB實驗分流,其分布一致性hash也未必能滿足特定的AB實驗業務數據擴展的需求,在其上改動的成本也大。所以我們在apache ignite的基礎上開發了一套分布式緩存系統,滿足實時性、一致性、高并發、高性能、高可用的需求。
這套分布式緩存系統可以走公司paas發布系統發布,系統節點可以納入公司的監控告警系統,可以水平擴展,可以以key-value的形式寫入annotation標記過的java object,以符合ANSI-99語法的sql語句讀出,一個個分布式緩存節點發布的時候不影響緩存一致性的讀取。AB實驗分流器后臺部署圖如下:
上端是SOA service供AB分流器調用,中間是分布式緩存系統,下端就是AB實驗配置數據庫。
AB實驗分流系統后臺取數據的概要設計如下:
上圖的分布式緩存系統部署有一個snapshot service,這個service負責每5分鐘關聯生成分流信息寬表,把可寫cache清空,然后把分流信息寬表的全量數據寫入。寫入完成后會把可寫cache標成可讀cache,可讀cache標成可寫cache,每次soa訪問分布式緩存系統的時候,會先從snapshot service里檢查哪個cache是可寫的,然后從可寫cache中讀數據,可讀和可寫cache的數據有效期都設置成一天。
Snapshot service這種設計可以避免前面redis方案中提到的批量數據一致性的問題,效率上也是好的,相當于讀寫分離。可以認為snapshot service是分布式緩存系統的數據自治中心,在分布式系統重啟的時候,還能自動從DB中再拉取組織數據。這種設計還有別于通用的緩存設計cache aside, read/write through和write behind三種設計。
AB實驗分流系統后臺實時更新數據的概要設計如下:
?
上圖設計可以讓分流實驗數據改動后實時在分流器中生效,而不是在分布式緩存系統5分鐘后更新全量分流寬表信息后才生效。注意在設計中沒有采用用消息包里放改動的實驗分流信息,讓SOA service收到消息后立即改動對應實驗,而是SOA service收到消息后,再重新以拉的方式讀一遍數據。通過一種方式更改數據比通過多種方式更改數據更安全,檢查問題也方便,同時也能聚合并發的消息再拉取。
四、后序
攜程AB實驗分流器的改進和設計大致情況如上所述。目前改進的新AB實驗分流器和分流器后臺在公司的幾次災備演練中表現的很穩定。分布式系統在開發的時候遇到過分布式唯一標示控制和讀取的問題,在部署分布式系統時遇到過snapshot service重復部署的問題等,這些都一一解決了。
在公司災備演練切換集群網絡的過程中,出現過后臺的分布式緩存系統無法從單點系統恢復成多點系統的問題,這可能是分布式系統的共病。因為掉線的節點數據的一致性校驗是很繁瑣的,這時候需要手工重啟下掉線的分布節點。
AB分流器設計還有很多需要完善的地方,譬如實時緩存監控和告警等,路還沒走完,要眼望前方,同時要時不時回頭看看,總結提高。
總結
以上是生活随笔為你收集整理的干货 | 携程是如何做AB实验分流的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入浅出!阿里运维专家三种方法教你如何应
- 下一篇: 职场最可怕事情!