在灰度測試的技術(shù)實(shí)現(xiàn)里,一個(gè)關(guān)鍵的部分是試用用戶樣本的選擇策略。也就是說,新版本上線測試的首批(以及后續(xù)批次)灰度用戶是怎么篩選出來,決定了灰度測試的技術(shù)選型和具體實(shí)現(xiàn)。從業(yè)務(wù)角度來說,我們要明確每一個(gè)新功能分別由哪些測試用戶來試用,誰扮演“小白鼠”的角色。
被廣泛使用的樣本選擇策略包括一下幾種:
l 白名單:我們主動(dòng)選取一批用戶,打上白名單標(biāo)簽?;叶劝姹臼紫乳_放給這批用戶。白名單用戶通常是業(yè)務(wù)同事根據(jù)業(yè)務(wù)經(jīng)驗(yàn)選取的,比如活躍的粉絲、喜愛嘗鮮的用戶、對(duì)產(chǎn)品問題比較包容的朋友等。當(dāng)然也可以是隨機(jī)選取的。
白名單最大的好處是主動(dòng)可控,出現(xiàn)問題的時(shí)候可以及時(shí)定位具體用戶,業(yè)務(wù)同事可以及時(shí)和這些具體客戶進(jìn)行溝通,獲得深入的測試反饋。
但是白名單用戶組由于不具有普遍代表性,一般不能實(shí)現(xiàn)A/B測試的效果預(yù)測能力。另外,技術(shù)上實(shí)現(xiàn)白名單通常會(huì)有性能損耗(對(duì)每一個(gè)用戶都需要掃描一遍名單),再考慮到人工篩選的工作量,我們通常不會(huì)允許白名單里的用戶數(shù)量太大。這種局限性對(duì)于用戶量較大的業(yè)務(wù)來說,比較麻煩。
l 隨機(jī)抽樣:每個(gè)用戶都有一定概率可以參與測試。
隨機(jī)抽樣原理簡單,樣本選取的代表性也比較好。多數(shù)時(shí)候隨機(jī)抽樣產(chǎn)生的試驗(yàn)組和對(duì)照組可以直接用于A/B測試檢驗(yàn)。
但是隨機(jī)抽樣不可避免的會(huì)讓試驗(yàn)管理陷入被動(dòng),萬一灰度測試給一部分用戶造成負(fù)面影響,很難挽回。這種不確定性的風(fēng)險(xiǎn)要求我們?cè)跍y試階段有強(qiáng)大魯棒的干預(yù)技術(shù)手段,比如實(shí)時(shí)監(jiān)控、實(shí)時(shí)回滾、實(shí)時(shí)捕捉到用戶在各渠道的負(fù)面反饋等。另外,要實(shí)現(xiàn)真正符合統(tǒng)計(jì)科學(xué)的真隨機(jī)(不是偽隨機(jī)),技術(shù)上也有不少坑。
l 按照某種規(guī)則抽樣:我們主動(dòng)建立抽樣規(guī)則,滿足規(guī)則條件的用戶就被指定參與測試。規(guī)則通常要考慮業(yè)務(wù)需求和測試用戶覆蓋。比如規(guī)則是“只選取手機(jī)尾號(hào)為9的用戶”,那么測試用戶覆蓋可能在10%左右。另一種規(guī)則是“下過單的用戶”,那么測試用戶大概會(huì)覆蓋已付費(fèi)客戶。
規(guī)則抽樣比白名單更加靈活方便,通常能覆蓋顯著更多的用戶,技術(shù)實(shí)現(xiàn)的性能也會(huì)比較好。
但是規(guī)則抽樣的策略介于隨機(jī)抽樣和白名單之間,既不是完全可控,也不是均勻采樣,并不是滿足業(yè)務(wù)需求的最佳選擇。
l A/B測試科學(xué)采樣:試驗(yàn)組(和對(duì)照組)用戶是通過具有代表性的隨機(jī)抽樣選取,可能還經(jīng)過了前期干預(yù),只有符合統(tǒng)計(jì)學(xué)檢驗(yàn)標(biāo)準(zhǔn)的用戶可以參與測試。
科學(xué)采樣生成的試驗(yàn)組和對(duì)照組具有很高的用戶代表性,測試得出的數(shù)據(jù)可以精確的預(yù)測新功能全面上線之后帶來的整體效果。
和隨機(jī)抽樣一樣,A/B測試需要我們具有強(qiáng)大的試驗(yàn)控制能力,能夠?qū)崟r(shí)回滾、實(shí)時(shí)開關(guān)試驗(yàn)功能、實(shí)時(shí)監(jiān)控用戶行為、實(shí)時(shí)調(diào)整分流比例。
如果有一個(gè)像AppAdhoc A/B Testing一樣強(qiáng)大的科學(xué)A/B試驗(yàn)系統(tǒng),每一個(gè)灰度測試都可以用A/B測試來實(shí)施。更重要的是,當(dāng)我們有多個(gè)新功能一起研發(fā)推進(jìn)的過程中,可以同時(shí)啟動(dòng)多組A/B測試,每組試驗(yàn)檢驗(yàn)一個(gè)功能,實(shí)現(xiàn)更精細(xì)化的產(chǎn)品管理。
A/B測試抽樣的長期問題
在實(shí)踐之中,我們注意到一個(gè)用A/B測試來做灰度上線的技術(shù)問題:長期試驗(yàn)的科學(xué)性偏差。
舉例來說,一個(gè)長期運(yùn)營的App,每個(gè)月上線一版新功能,也就是每個(gè)月上線一個(gè)A/B測試。A版對(duì)照組采樣5%的用戶,B版體驗(yàn)新功能組采樣5%的用戶,同時(shí)開始試驗(yàn)控制。兩周之后試驗(yàn)結(jié)束,用戶喜愛的新功能全面發(fā)布,用戶不喜愛的新功能全面回滾。再過兩周,新的一個(gè)月迭代周期開始,新的A/B測試上線,5%對(duì)照組5%試驗(yàn)組……每個(gè)月一組A/B測試,長此循環(huán)。
假如A/B測試的樣本篩選算法只考慮一次試驗(yàn)的科學(xué)性,那么只需要保證我們選出的5%對(duì)照組和5%試驗(yàn)組足夠均勻即可。
假設(shè)試驗(yàn)組采樣使用簡單的哈希算法:
Group ID for Client cid <= Hash(A/B Testing Client ID cid)
那么每一個(gè)用戶都會(huì)被分到固定編號(hào)的試驗(yàn)組里。
假設(shè)試驗(yàn)組資源分配使用簡單的貪心算法:
Experiment Groups for X% <= FindFirstXGroups(Groups, X)
如果試驗(yàn)頻率是一個(gè)月一次,測試流量5%,那么每次試驗(yàn)都會(huì)是前5個(gè)試驗(yàn)組(Group)被選中參與測試。也就是說,有一批用戶,被固定分配到前5個(gè)試驗(yàn)組的用戶,每個(gè)月都會(huì)被選中為“小白鼠”參與試驗(yàn)。
這會(huì)造成一個(gè)長期問題,就是這些留存很久的樣本用戶,比如使用App長達(dá)半年、一年、多年的老用戶,作為試驗(yàn)樣本,可能會(huì)出現(xiàn)“樣本偏差”。
如果一批老用戶總是在不停“嘗鮮”,一批老用戶總是體驗(yàn)穩(wěn)定版本,他們的行為習(xí)慣可能被培養(yǎng)成不同的類型,他們對(duì)產(chǎn)品的期待和需求也可能逐漸異化。比如說,長期參與試驗(yàn)的“小白素”用戶更喜歡新功能更不在乎bug,而長期在對(duì)照組的用戶不適應(yīng)新功能也對(duì)bug很敏感。一旦這種差異開始固化,這兩組用戶就異質(zhì)了,不能拿來繼續(xù)做新的A/B測試。如果繼續(xù)用這些樣本做試驗(yàn),試驗(yàn)結(jié)果是不符合A/B測試要求,結(jié)論是不可信的,無法用于業(yè)務(wù)指導(dǎo)。
其實(shí)A/B測試結(jié)果的科學(xué)和準(zhǔn)確只是一個(gè)小問題,這個(gè)問題的最大影響是在于這些被反復(fù)拿來做試驗(yàn)的“小白鼠”用戶/客戶,有可能產(chǎn)生不必要的流失,甚至個(gè)別用戶被反向培養(yǎng)成“黑粉”,對(duì)我們的產(chǎn)品形成強(qiáng)化的壞印象。這種資深黑粉用戶會(huì)嚴(yán)重影響產(chǎn)品的口碑,也幾乎沒有辦法可以召回。
這個(gè)長期偏差問題對(duì)于白名單和規(guī)則抽樣等類型的采樣策略也都或多或少的存在。當(dāng)然,白名單策略本身就是要篩選出特定的用戶群長期做“小白鼠”,我們?cè)谶x擇白名單策略之初就得處理好這個(gè)問題。
理論上說,隨機(jī)抽樣不會(huì)出現(xiàn)長期偏差問題,因?yàn)槊看螀⑴c試驗(yàn)的用戶都是隨機(jī)篩選的一批,通常同一個(gè)用戶不會(huì)被不同的試驗(yàn)反復(fù)選中。但是在實(shí)踐之中,也要注意實(shí)現(xiàn)的算法是否能支持真正的隨機(jī)性。很多時(shí)候,偽隨機(jī)數(shù)加上固定分支條件的代碼實(shí)現(xiàn)會(huì)讓某些用戶有更大的可能被選中,這些用戶還是會(huì)成為長期的“小白鼠”。
試驗(yàn)流量“洗牌”算法
意識(shí)到灰度測試的長期“小白鼠”問題,我們需要在A/B測試系統(tǒng)里引入“洗牌”機(jī)制,可以不斷把預(yù)先分配好的試驗(yàn)組里的用戶們重新打散,再重新分配到不同的試驗(yàn)組里。
“洗牌”機(jī)制有很多實(shí)現(xiàn)算法,針對(duì)A/B測試系統(tǒng),我們可以采用的一個(gè)簡單算法:對(duì)每一個(gè)用戶,每過一段時(shí)間(比如30天),就給用戶一個(gè)機(jī)會(huì),可以換到其他試驗(yàn)組里去。
假設(shè)我們用簡單的哈希算法來對(duì)用戶做試驗(yàn)分組,那么可以用類似這樣的實(shí)現(xiàn):
// Runs every 30 days
Group ID for Client cid <=
Hash(A/B Testing Client ID cid + DateTime) % #Groups
注意不同的用戶加入系統(tǒng)的時(shí)間是不同的,所以他們的“洗牌”機(jī)會(huì)也會(huì)出現(xiàn)在不同的時(shí)間。但是整體來說,試驗(yàn)組是每過一個(gè)月完成一次比較完整的“洗牌”。
引入“洗牌”機(jī)制之后,每個(gè)試驗(yàn)組在長時(shí)間尺度上是不斷變化的,即便是同一個(gè)編號(hào)的試驗(yàn)組反復(fù)參與測試,也不會(huì)總是同一批用戶。我們?cè)僖膊粫?huì)總是逮著同一群小白鼠打針喂藥了。
總之,尊重用戶/客戶,不僅要用灰度A/B測試來避免有問題的產(chǎn)品迭代影響大面積的用戶,還要避免同一批用戶總是被拿來做試驗(yàn),確保所有用戶都能享受最佳的產(chǎn)品體驗(yàn)。