ABtest一个总的目的和意图是,判断哪种种UI或rerank策略更优,通过事实的依据( CTR或下单率)判断哪种策略更符合用户的习惯和需求。
一、需求驱使
我们经常会面临多个设计方案的选择,比如app或pc端某个界面的某个按钮是用红色还是用蓝色,是放左边还是放右边。传统的解决方法通常是集体讨论表决,或者由某位专
家或领导或文青来拍板,实在决定不了时也有随机选一个上线的。虽然传统解决办法多数情况下也是有效的,但A/B 测试(A/B Testing)可能是解决这类问题的一个更好的方法。
所谓 A/B 测试,简单来说,就是为同一个目标制定两个方案(比如两个页面),让一部分用户使用 A 方案,另一部分用户使用 B 方案,记录下用户的使用情况,看哪个方案更符
合设计目标。
下面看一个例子:
在展示“格林秀上午酒店”这个poi时有客户端两种UI:
方案A:如左图,评分展示星状图片,消费人数再右边;
方案B:如右图,只展示评分分数,后边添加消费人数;
我们很难知道那种方案比较好,那我们可以做个实验,把a和B方案同时放到线上的生产环境,让一部分用户使用 A 方案,另一部分用户使用 B 方案,记录下用户的使用报表如下图,通过大自然的优胜劣汰法则,我们可以通过CTR或下单率等指标看哪个方案更符合设计目标。
二、系统模型
abtest实验可以分成两种,客户端client实验和服务端server实验,客户端实验一般来说只是UI上的实验,比如上面的例子,纯粹是展示端的策略;而服务端的实验是返回给client数据的内容做实验,比如推荐的策略,订单列表rerank策略等。下面通过client和服务端的实验分别做介绍。
(1)客户端实验:
方案1:
ABTest业务流程描述:
(1)客户端在需要获取ABTest策略的地方,通过RPC接口获取uuid在ABTest1这个实验下的规则:- {
- "data": [
- {
- "name": "test1",//实验key
- "strategy": "strategy1", //策略key,客户端根据策略key选择策略方案
- "flow": "flow1", //流量组,用于上报。每个流量组只属于一个策略。
- "finished": false //标识实验是否终止,如果已经终止,则不再向utm_compaign参数的F字段append该规则,但是不影响规则,原规则依然生效。
- }
- ]
- }
其中testkey参数可以是多个ABTest实验的key:abtest1,abtest2。
(2)之后客户端向server发起的全部请求,URL的utm_compaign参数中的F位添加字符串:Fabtest1__strategy1__flow1,Nginx将utm_compaign打印到access日志。
(3)客户端在另一个需要获取ABTest策略的地方,通过http接口/get/abtest/{testkey}/{uuid} 获取uuid在ABTest2这个实验下的规则:
|
- {
- "data": [
- {
- "name": "abtest2",//实验key,
- "strategy": "strategy2", //策略key,客户端根据策略key选择策略方案
- "flow": "flow2", //流量组,用于上报。每个流量组只属于一个策略。
- "finished": false //标识实验是否终止,如果已经终止,则不再向utm_compaign参数的F字段append该规则,但是不影响规则,原规则依然生效。
- }
- ]
- }
方案二
流程:
- (1)(客户端的工作):app启动或切换城市,会请求abtest服务后台,获得所有的实验的以及命中的策略缓存在app中。
- (2)(abtest后台的工作):abtest接收一个uuid+ci+pt的请求,返回给app所有的实验的以及命中的策略,同时将这次请求和结果通过flume_agent收集日志,同步到Hadoop,最后导入Hive。
- (3)(客户端的工作):在第1步的请求中的获得的所有的实验的以及命中的策略缓存在app中。
- (4)(客户端的工作) : 进入到一个做ab实验的界面,按照第3步命中的实验的策略+展示的业务数据处理展示逻辑。
- (5)(客户端的工作:):会把第4步这个界面的信息和埋点信息上传到数据中心的原始日志,异步步少重试的方式上报埋点,
按HTTP GET/POST 日志收集方式,MGE,MGP,MPT的信息定义可以。移动页面流跟踪事件,这些事件封装为MPT事件,具体格式如下:
- </pre><pre name="code" class="javascript">"nm":"MPT",//页面流跟踪事件(PageTrack)
- "val":{
- "root": //层级前缀
- "name": //页面名/组件名/弹窗名
- "content": //数据请求URL内容/弹窗内容
- "type": //page/alert
- }
- "nm":"MGE",//Event跟踪,需要客户端手工埋点,用于解决临时统计需求
- "val":{
- "cid": //页面名 ||||类别 category id
- "act": //动作名 ||||动作 action
- "lab": //动作描述 ||||注释 label
- "val": //页面描述 ||||权值 value
- }
- "nm":"MGP",//页面跟踪,需要客户端手工埋点,用于解决临时统计需求
- "val":{
- "root": //层级前缀(非必需)
- "name": //页面名/组件名/弹窗名(必须)
- "content": //数据请求URL内容/弹窗内容(必须)
- "type": //page/alert
- }
(6)(数据组的工作):应用系统可以通过flume,将原始日志同步到Hadoop,最后导入Hive表,通过关联的条件将两个hive表关联,同时关联一些点击下单等数据,清洗数据成报表。