站點新功能或者是站內新策略開發完畢以後,在全流量上線以前要評估新功能或者新策略的優劣,經常使用的評估方法是A-B測試,作法是在全量中抽樣出兩份小流量,分別走新策略分支和舊策略分支,經過對比這兩份流量下的各指標的差別,咱們能夠評估出新策略的優劣,進而決定新策略是否全流量。算法
上文中提到的抽樣是指按照某種肯定的隨機化方法,對線上流量進行劃分。抽樣能夠指這種劃分的方法,也能夠指劃分獲得的一個流量子集。抽樣是一種特殊的小流量,要求對流量的劃分必須保證均勻性和隨機性,而且能夠根據需求過濾掉不符合規範的部分,咱們把抽樣的過程分爲流量切分和流量篩選兩個步驟,流量切分是指把全流量進行均勻的打散,提取出其中固定的流量比例,流量篩選是對流量切分的輔助,篩選過程就是從切分好的流量中過濾掉不符合規範的部分,本文主要涉及的是流量切分的實現。cookie
作到流量切分的經常使用的方法是單層流量切分,流量切分須要以某種方式進行,即流量切分的打散依據,例如,咱們能夠依據流量中的cookie打散,或者是隨機打散等,打散的方式不一樣,切分的對象全集也就不一樣了,若是咱們依據cookie打散,那麼咱們的切分對象全集就是全部的cookie,若是是隨機打散,那麼咱們的切分對象全集就是該站點的全部的流量。架構
圖1.1 單層流量切分架構示意圖ide
有了上面的想法,咱們如何實現單層流量切分呢?如圖1.1所示,咱們按照指定的流量切分方式,將所須要的輸入參數先通過一次hash計算,產生結果的均勻性和隨機性由hash算法來保證,有了hash產生的結果,流量切分的過程尚未結束,咱們還須要將hash結果對應到切分對象的全集上面,實現方法是將切分對象全集看做是一個區間段,而後將hash結果對應到區間段上面,區間的大小是切分的最小粒度決定的,例如,若是須要最小切分粒度爲0.01%,則咱們選取的區間段爲[0,9999],有了區間段的定義,咱們能夠將hash結果對一個數值取模,這個數值等於區間段最大值加1,取模以後的結果能夠惟一的對應到切分對象全集區間上面,這樣咱們就將全部的流量打到了流量切分對象全集上面。測試
最後,咱們再將區間段按照實驗需求細分,劃分紅若干子區間,用做於實驗對比,例以下圖所示,將整個100%的區間分爲多個子區間,每一個子區間使用惟一的編號——sid,做爲區間的惟一的標識,sid=1的子區間對應的流量爲1%,那麼它的子區間就是[0,99],同理,sid=2的第二個1%的子區間對應的區間值爲[100,199],這樣咱們就將一個100%的完整區間劃分紅了若干個子區間,兩個比例相同的子區間就能夠用做於實驗策略對比。對象
圖1.2 流量子區間的劃分資源
這種單層流量切分方式是一種獨佔式的流量切分方式,一個子區間只能供給一個實驗使用,一個請求只能命中一個實驗,優勢是實驗之間解藕,不相互影響,缺點是資源有限,流量分配完畢以後,後續的需求將處於長期的等待與飢餓狀態,這種獨佔式的流量切分方式,顯然在實驗需求不斷增長的狀況下是徹底不能知足的,爲了解決獨佔的問題,咱們能夠採用多層流量切分方式。開發
多層流量切分的思想是將單層結構擴展爲多層結構,以下圖所示,多層之間必須知足正交性,這裏多層之間的正交性是指某一層的任何一個子區間能夠隨機的、均勻的對應到其餘層上面,這樣咱們就把一個子區間對其餘層的影響均勻的分散到整個層上面。hash
多層流量切分架構能夠將實驗流量從100%擴展到100%*n,也就說每層中的流量咱們均可以用作於實驗對比,一次請求能夠同時命中多個實驗,實驗流量是複用的,多層流量是知足不一樣層的實驗之間的影響都是均勻、可預估的,開展多層實驗的前提是保證這種實驗間的影響是可接受的,有一些實驗是不容許任何複用,例如,展示類的實驗,若是兩個實驗各自指定了一套展示樣式模板,而從展示模塊的角度來說一次請求只能展示一種樣式模板,所以,這裏不兼容的實驗只能位於同一層中。it
圖1.3 多層流量切分架構示意圖
多層流量切分的另外一個優點是每一層咱們可使用不一樣的切分方式進行,這樣也極大的豐富了流量切分的多樣性,那麼,還有另外一個問題,每個流量層中只能採用一種流量切分方式,若是同一層中有多種切分方式的需求又如何解決呢?答案是經過層的嵌套來實現,層的嵌套是指在一個層中能夠包含其餘的層,以下圖所示,矩形表示層,圓形表示切分出來的實驗流量,其中,1號層包含了二、三、4三個層,4號層又包含九、十、11三個層,爲了達到同一層內多種流量切分方式的目的,咱們須要將該層切分紅多個區間,例如,下圖中的2號層就被分紅了五、6兩個層,可是這兩個層也必須採用相同的切分方式,由於這兩個層至關於把其父層的流量分紅了兩部分,於是這兩部分的產生方式應該是一致的,最後,在五、6層中,咱們又能夠創建其餘的層,這兩個層就能夠採用不一樣的流量切分方式了。
圖1.4 流量切分多層嵌套示意圖
理論上,多層流量切分架構的可切分層數是無限的,能夠支持任意多的流量層,可是,從實現的角度來說,層數作到無限是很難實現的,由於,爲了保證層和層之間的正交性,咱們必需要爲每一層實現一套hash算法,保證每種hash算法的結果是正交的,要實現層數的無限,則須要實現無限多個保證正交的hash算法,hash算法的增多勢必會致使正交性的降低,咱們能夠實現有限個正交的hash算法,hash算法的數目是要求能夠知足全部的實驗需求的。下面咱們介紹一種多層流量切分架構的實現方法。
爲了實現多層流量切分,咱們的思路是先實現一種hash算法,這種hash算法的輸入是cookie、隨機值等信息,輸出是單次hash的結果,而且保證這種hash算法結果足夠的均勻和隨機,而後將這種hash進行變換,擴展出多個正交的hash算法。
爲了驗證單個hash算法的隨機性和均勻性,咱們進行了實驗驗證,以下圖所示,每一行表示一個100%的全集,每一列表示從全集中抽取出10%,測試的全集是100w,從下面的測試數據來看,每一個層中的流量切分結果是比較均勻和隨機的。
圖1.5 單hash算法均勻性、隨機性驗證明驗數據
有了單層hash算法,咱們須要將單層hash擴展成爲多層,這裏能夠採用的方法不少,本文采用的是移位變換的方法將單層hash擴展成爲多層hash,多層實驗流量切分的真實環境測試數據以下文所示。
爲了驗證其算法的可行性,咱們進行了實際數據測試,測試結果以下:
表1.2 均勻性驗證數據
by yangfangwei&huangjin&yaoshiyu