为什么要做ABtest
OpenSearch是为用户提供数据搜索解决方案的平台,目前已经通过阿里云平台为集团内外大量客户提供服务。为了更好地提供搜索服务,OpenSearch打算把集团内部已经成熟的算法功能输出给外部客户使用,如类目预测、查询分析等。但是在我们开放类目预测功能之后却发现鲜少有人使用,调研了一些相关客户后,发现原因是无法证明使用了类目预测功能之后真的能提升搜索服务效果,以及提升了多少,因此客户不敢贸然使用,于是ABtest功能应运而生。
实现方案调研
什么是ABtest
ABtest是指为了达成某一优化目标,提出两种方案A和B,让一部分用户使用A方案,另一部分用户使用B方案,然后通过比较这两部分用户的行为数据来说明哪个方案更优的实验方法。当然真实的实验场景会更复杂,包含更多的方案做比较。此外,为了为有限流量的用户提供同时做多个实验的能力,ABtest实验还可以分层,不同层共享100%的流量,层内实验按比例切分流量并做比较。
已有的实现
通过调研,我们发现公司内部已有ABtest的实现方案,即Hyperspace。它提供RESTful API以编辑ABtest实验,将配置存入DB并同步到diamond中,用户可以使用C++ SDK从diamond同步数据并对流量分实验。这些功能基本满足OpenSearch对ABtest功能的需求,同时,Hyperspace本身的积淀也能让OpenSearch的ABtest功能少走很多弯路,因此我们决定采用Hyperspace作为ABtest的实现方案。
OpenSearch上的ABtest
产品设计
实验编辑
考虑到OpenSearch的很多用户没有使用ABtest的经验,为了降低用户的使用难度,我们基于ABtest抽象出了实验场景、实验组和实验三个概念:
实验场景:实验场景指的是准备进行实验的全部流量集合。产生方式是由用户在发送给OpenSearch的Query中用http参数的方式带上实验场景的标签,并在实验配置中指定标签集合。
实验组:实验组为实验的容器,即对应ABtest中层的概念。
实验:测试功能的随机流量及其配置,也就是ABtest中实验的概念。目前实验可支持的配置有查询分析、粗排表达式、精排表达式以及类目预测。
在产品设计上,我们使用如下图所示向导的功能让用户分别创建场景、实验组和实验,并在相应的界面上添加对相应概念的解释,尽量降低用户的理解成本。
在用户的查询api中,我们提供了scene_tag和flow_divider两个ABtest相关参数。scene_tag用户让用户标识流量的场景,用于区分流量是否参加实验。flow_divider是ABtest用来对流量分实验的一个哈希字段,一般我们建议用户使用他的用户的编号,这样能保证同一个终端用户始终进入同一个实验,为其提供稳定的体验。
实验数据报表
在用户编辑完ABtest实验之后需要持续观察流量的变化以确定哪个方案更优,因此OpenSearch为用户每天统计一次各实验的PV、IPV、UV、IPV_UV、CTR、无结果率等核心指标(IPV、IPV_UV、CTR三个指标需要用户开通数据采集功能)展现给用户对比。
通过编辑实验和对比指标,用户的设计决策就有了数据支撑,在使用新的算法功能时也就不必担心,一切靠数据说话。
技术方案
ABtest实现
在OpenSearch之前,Hyperspace对其他项目的ABtest功能的支持方式是每个项目对应一个配置集合,即Hyperspace中的project。但是OpenSearch是一个搜索平台,需要支持成千上万的用户使用ABtest功能,即要在Hyperspace上开通成千上万个project,而Hyperspace所用的diamond配置管理系统支持的配置数据量有限,无法满足这个需求,因此Hyperspace同学部署OpenSearch的服务的时候把diamond替换成了基于etcd实现的配置中心。此外,为了把OpenSearch的用户与Hyperspace上其他用户隔离开来,Hyperspace还引入了命名空间的概念,将OpenSearch平台上开通的project单独放入一个命名空间下。
使用Hyperspace后,ABtest在OpenSearch上的实现架构如下图所示:
前端提供界面供用户编辑ABtest实验,并通过API与Hyperspace交互,Hyperspace把实验配置存入数据库并同步给配置中心。agg使用Hyperspace的C++ SDK从配置中心拉取实验配置,并据其确定实验,改写搜索请求,查询ha3引擎,将查询结果返回给前端。同时,agg也会记录每个搜索请求最终进入的是哪个实验,为各项指标的统计提供支持。
数据报表统计
实验数据报表的数据来源分为agg上的pv日志以及用户推送的行为数据两部分。计算流程使用aflow管理,通过各区域主控机上的crontab指令来每天定时触发执行。为了与OpenSearch上现有的算法任务(目前主要是类目预测)兼容,数据报表的统计任务分为计算较为通用的基础数据(主要包括app级别的搜索和点击日志)和报表数据(PV、UV等指标)两部分。基础数据不仅可以用来生成报表数据,同时也可以被其他算法任务所使用。
基础数据生成流程
- 准备阶段:获取整个aflow过程中需要解析的app_group_id列表,通过odps_jobs_status来过滤掉已经被解析过的app
- 通过MapReduce产生数据阶段:
- MR1: 解析agg的pv日志表,将其按app分开,并生成request2experiment(记录搜索请求与实验编号的对应关系)表备用
- MR2: 从用户的行为数据表中抽取出点击相关记录,生成click_log_basic表
报表生成流程:
- 总体流程:
- user_request表的生成:user_request根据终端用户编号来join不同表的信息,主要用于统计报表指标中与用户编号有关的部分指标
后续工作
为了降低用户的理解成本,目前上线的ABtest功能不允许用户在一个实验场景下创建多个实验组,即不支持分层实验。