a/b testing at the edge
TRANSCRIPT
Segmentation
sub vcl_recv {
if (randombool(5,100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = "A"; }
}
Segmentation
sub vcl_recv {
if (randombool(5,100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = "A"; }
}
Segmentation
sub vcl_deliver {
add resp.http.Set-Cookie = "FastAB=" req.http.X-FastAB ”; expires=Thu, 20-Jul-17 19:47:08;”;
return(deliver); }
Segmentation
sub vcl_deliver {
if (!req.http.Cookie:FastAB){
add resp.http.Set-Cookie = "FastAB=" req.http.X-FastAB ”; expires=Thu, 20-Jul-17 19:47:08;”;
}
return(deliver); }
Segmentation
sub vcl_recv {
if (randombool(5,100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = "A"; }
}
Segmentation
sub vcl_recv { if (!req.http.Cookie:FastAB) {
if (randombool(5,100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = "A"; } }
}
Segmentation
sub vcl_recv { if (!req.http.Cookie:FastAB) {
if (randombool(5,100)) { set req.http.X-FastAB = "B"; } else {
set req.http.X-FastAB = "A"; } } else {
set req.http.X-FastAB = req.http.Cookie:FastAB;
} }
HTTP Vary
- The chef (or server) tells us what is important information (e.g. flavor)
- The customer (or browser) tells us the flavor
- Max of 200 variations!
- Otherwise change the hash
- Don’t vary on too big a set (e.g. user-agent)
HTTP Vary
if (beresp.http.Vary) { set beresp.http.Vary = beresp.http.Vary ", X-FastAB"; } else { set beresp.http.Vary = "X-FastAB"; }
HTTP Vary
if (beresp.http.Vary) { set beresp.http.Vary = beresp.http.Vary ", X-FastAB"; } else { set beresp.http.Vary = "X-FastAB"; }
# e.g. Vary: Accept-Encoding, X-FastAB
HTTP Vary
• What is a hash?
{ set req.hash += req.url; set req.hash += req.http.host; set req.hash += "#####GENERATION#####"; return (hash); }
Backend AB
if (randombool(5,100)) { set req.backend = backend_b; } else { set req.backend = backend_a; }
Edge Dictionary
Change weights via API
table page_segments {
"/" : “5”, # percentage ‘b’ ”/page1" : "30", "/page2" : “40",
}
Edge Dictionary
Change weights via API
if (randombool(5,100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = "A"; }
Edge Dictionary
set req.http.X-Weight = table.lookup(page_segments, req.url.path);
if (randombool(5,100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = "A"; }
Edge Dictionaryset req.http.X-Weight = table.lookup(page_segments, req.url.path);
if (randombool(req.http.X-Weight,100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = "A"; }
Edge Dictionaryset req.http.X-Weight = table.lookup(page_segments, req.url.path);
if (randombool(std.atoi(req.http.X- Weight),100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = "A"; }
Cookie-less
if (randombool(5,100)) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = “A"; }
Cookie-less
if (randombool_seeded(5,100,seed))) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = “A"; }
Cookie-less
set req.http.X-ClientIDHash = digest.hash_md5(client.ip req.http.User-Agent)
# e.g. 3aaf91f17e7c63b07f8490ab242f9335
if (randombool_seeded(5,100,seed))) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = “A"; }
Cookie-less
set req.http.X-ClientIDHash = digest.hash_md5(client.ip req.http.User-Agent)
set req.http.X-ClientID = std.strtol(req.http.X-ClientIDHash,16)
# e.g. 9223372036854775807
if (randombool_seeded(5,100,seed))) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = “A"; }
Cookie-less
set req.http.X-ClientIDHash = digest.hash_md5(client.ip req.http.User-Agent)
set req.http.X-ClientID = std.strtol(req.http.X-ClientIDHash,16)
# e.g. 9223372036854775807
if (randombool_seeded(5,100,std.atoi(req.http.X-ClientID))) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = “A"; }
Cookie-less
if (randombool_seeded(5,100,std.atoi(req.http.X-ClientID))) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = “A"; }
Still the seed
Cookie-less
if (randombool_seeded(5,100,std.atoi(req.http.X-ClientID))) { set req.http.X-FastAB = "B"; } else { set req.http.X-FastAB = “A"; }
Still the seed