支撑Pinterest日均1000+次试验的A/B测试平台揭秘

时间:2022-12-04 12:34:33

编者按:本文详细介绍了 Pinterest 内部A/B测试平台的搭建过程,对于无论是有技术能力和资源想要自建A/B测试系统的大公司,还是想在业务中引入第三方A/B测试方法和工具的中小公司都极具参考意义。

作为一家数据驱动的公司, Pinterest 是非常依赖试验来指导产品和功能迭代的。

Pinterest 随时都有大约1000个试验在进行,并且试验的数量每天都在增加。 因为试验数量和相应记录数据的持续增加,衍生了向工程师提供一个可靠易用平台的需求,来保证他们使用的时候没有错误。 为了避免由试验者造成的一般错误, Pinterest 引入了轻量级的配置 UI ,QA 工作流和简化的 API 接口来支持跨平台的A/B测试。

在构建试验平台时, Pinterest 优先考虑以下要求:

1.实时配置更改:需要能够快速地关闭试验或实时启动试验,不需要每次更改配置的时候都进行代码部署,特别是在修复网站故障的情况下。

2.轻量化过程:设置试验不应该比一个正常的功能启动更复杂,这样就可能阻止用户做出可以预测到的错误。

3.客户端不可知:使用者不必为每个平台学习新的试验方法。

4.试验分析:为了得出更好的试验结论,我们建立一个易于使用的分析控制面板。

5.可扩展性:要求整个系统在线上服务和离线试验数据的过程中都可以扩展。

简化的过程

Pinterest 的试验都遵循一个共同的模式:

1)通过初始设置创建试验,建立假说,记录验证该假说的方法。

2)将试验披露给 Pinners ,增加新群组和禁用组,通过筛选器来优化用户。

3)结束试验时,将代码提交给所有的 Pinners ,或者回滚代码并记录试验结果(根据试验结果决定提交新代码或回滚)。

在以前的框架中,这些变化全都是通过代码实现的。 然而, Pinterest 希望建立一个新的架构,在这个架构中,用户可以在 UI 界面里实现变更,提供交互反馈和验证,并且这个基于配置的框架的变更推送独立于代码发布之外。

支撑Pinterest日均1000+次试验的A/B测试平台揭秘

像语法错误、不平衡组分配、重叠群或违反试验程序这样的常见实验错误都会进行交互验证。 Pinterest 的A/B测试平台主动提供了预先搜索建议来减少人为输入,如下图2所示。 现在进行一次试验通常只是需要进行一些点击。

支撑Pinterest日均1000+次试验的A/B测试平台揭秘

为了让配置可以被任意客户端实时访问, Pinterest 利用内部系统以序列化格式存储所有试验设置,并在数秒内将它们同步到试验系统的每个主机。 一个典型的配置文件在反序列化之后具有以下内容:

{“holiday_special”:

{

“group_ranges”: {

“enabled”: {“percent”: 5.0, “ranges”: [0, 49]},

“hold_out”: {“percent”: 5.0, “ranges”: [50, 99]}

},

“key”: “holiday_special”,

“global filter”: user_country(‘US’),

“overwrite_filter”: {“enabled”: is_employee()},

“unauth_exp”: 0,

“version”: 1

}

}

配置与代码分离的好处是可以对试验设置进行即时更新,这意味着配置变化,如增加试验组的流量不需要重新进行代码部署。 这就将试验从生产部署中解放出来,大大加快了迭代速度,特别是在需要紧急更改时。

质量保证

一个简单的试验可能会影响到数以百万计的 Pinners ,所以 Pinterest 配备了高标准的测试操作流程和严格的质量保证工具。 试验应用程序还配置了一个审查工具,这个工具可以为每个试验变化创建一个审查过程。 图3显示了一个修改组范围和筛选器的待定更改。 审批人可以通过 UI 界面指定,并以电子邮件方式通知。

支撑Pinterest日均1000+次试验的A/B测试平台揭秘

对于大多数试验,有一个由平台开发者、用户和数据科学家组成的跨团队协助小组。几乎每个更改都需要协助者仔细检查规划,假设,关键结果,触发逻辑,过滤器设置,组验证和文档。这样的过程在我们的网络应用程序上执行,以使每次更改都需要填充一名帮助者。除此之外,还有一个定期的试验助手培训计划,以确保每个团队至少有一个人得到认证。

一个试验通常伴随着代码变化,比如将对比组/实验组的信息嵌入到决策逻辑中。 Pinterest 要求试验用户通过 Pull Requests 按钮在试验平台添加一个 Pull Request(PR) 链接,这样帮助者和分析师就很容易跟踪试验行为,并在需要时进行调试。 此外,它们还将每一个变化作为评论发送到 Phabricator (我们的库管理工具)中对应的 PR 中,如图4所示。

支撑Pinterest日均1000+次试验的A/B测试平台揭秘

用户还可以在 UI 界面创建一个正在进行试验的测试拷贝(如图1所示)。 它们将被移植到如图5所示的测试面板中。 在测试面板中所做的任何更改都不会影响到正在进行的产品试验,并且测试结果仅对测试工程师可见。如果测试结果不错,测试工程师就可以通过点击 Copy To Prod 按钮将其移植到产品中。

支撑Pinterest日均1000+次试验的A/B测试平台揭秘

API

试验 API 是用户通过 UI 将他们的应用代码链接到试验设置的接口。两种主要的应用方法如下:

def get_group(self, experiment_name)

def activate_experiment(self, experiment_name)

要注意的是, get_group 方法返回的是调用者所指示的组的名称。 在内部,组是通过计算基于试验信息的哈希值得到的,并且这种方法没有副作用。 另一方面,调用 active_experiment 方法向日志系统发送消息,并对分析结果做出贡献。这有助于分析实验结果。 这两种方法足以覆盖大多数用户案例,并且通常以如下方法使用:

# Get the experiment group given experiment name and gatekeeper object, without actually triggering the experiment.

group = gk.get_group(“example_experiment_name”)

# Activate/trigger experiment. It will return experiment group if any.

group = gk.activate_experiment(“example_experiment_name”)

# Application code showing treatment based on group.

if group in [‘enabled’, ’employees’]:

# behavior for enabled group

pass

else:

# behavior for control group

pass

上述代码中的 Gatekeeper 对象 gk 是一个试验所需要的用户/会话/元信息的封装器。 除了上述的 Python 库,我们还有一个独立的 JVM (Scala 和 Java) 库,可以对 Javascript 和移动APP(安卓和 iSO )提供支持。

设计和架构

支撑Pinterest日均1000+次试验的A/B测试平台揭秘

试验平台从逻辑上可以分为三个部分:配置系统,一组 API 接口和分析路径。 它们通过定向数据流连接:

1.配置系统将用户在 Web UI 所做的修改保存到我们试验数据库中,这些信息以序列化的格式在一分钟以内的时间间隔内同步到每一台服务器中。

2.试验对象更新试验配置,通过 API 来验证试验逻辑,比如试验类型和组分配。

3.由试验对象所产生的活跃试验记录将通过内部 Singer 服务器传送到 Kafka 。 分析路径将根据这些试验记录,按照用户定义的参数创建试验报告,并发送到控制面板。

总结

这套系统于去年夏天推出后,支持了 Pinterest 内部的大部分实验。 一些团队功能,比如实时参数控制面板、实验邮件通知、交互文档和协作工具,以及 SEO API/UI 也被添加到系统中。

本文由 吆喝科技 编译自 Pinterest 博客,原文链接:

https://engineering.pinterest.com/blog/building-pinterest%E2%80%99s-ab-testing-platform