作为一款面向ToB市场的产品——火山引擎A/B测验(DataTester)为了满足客户对数据安全、合规问题等需求,探究私有化布置是产品无法绕开的一条路。

在面向ToB客户私有化的实际落地中,火山引擎A/B测验(DataTester)也遇到了字节内部服务和企业SaaS服务都不容易遇到的问题。在解决这些问题的落地实践中,火山引擎A/B测验团队沉淀了一些流程办理、性能优化等方面的经历。

本文首要共享 火山引擎A/B测验 当前的私有化架构,遇到的首要问题以及从事务视点出发的解决思路。

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

火山引擎A/B测验****私有化架构

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

架构图整套系统采用 Ansible+Bash 的方式构建,为了习惯私有化小集群布置,既答应各实例对等布置,复用资源,完结最小三节点交给的方针,,又能够做在线、离线资源阻隔提高集群安稳性。集群内能够划分为三部分:

  1. 事务服务: 首要是直接向用户提供界面或许功用服务的, 例如试验办理、试验陈述、OpenAPI、数据接入等。
  2. 根底服务: 不直接面向用户,为上层服务的运转提供支撑,例如支撑试验陈述的核算引擎、为目标创立提供元信息的元信息服务;根底服务一起还会充当一层对根底设施的适配,用来屏蔽根底设施在 SaaS 和私有化上的差异, 例如 SaaS 采用的实时+离线的 Lambda 架构, 私有化为了削减资源开支,习惯中小集群布置只保存实时部分, 核算引擎服务向上层屏蔽了这一差异。
  3. 根底设施: 内部团队提供一致私有化根底设施底座 minibase,采用宿主机和 k8s 结合的布置方式,由 minibase 适配底层操作系统和硬件, 上层事务直接对接 minibase。

私有化带来的应战

应战 1:版别办理

传统 SaaS 服务只需求布置保护一套产品供悉数客户运用,因而产品只需求针对单个或几个服务更新,快速上线一个版别特性,而不需求考虑从零开始搭建一套产品。SaaS 服务的版别发布周期往往以周为单位,坚持每周 1-2 个版别更新频率。可是,在私有化交给中,咱们需求确定一个基线版别而且绑定每个服务的小版别号以保证相同版别下每套环境中的交给物等价,以减轻后续晋级运维本钱。通常,基线版别的发布周期往往以双月为单位。

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

版别发布周期

由于私有化和 SaaS 服务在架构、完结、根底底座上均存在不同,上述的发布节奏会带来一个显着的问题:

团队要投入很多的开发和测验人力会集在发版周期内做前史 Feature 的私有化适配、私有化特性的开发、版别发布的集成测验,挤占其他需求的人力排期。

为了将周期内会集完结的作业分散到 Feature 开发阶段,从头规范了分支运用逻辑、完善私有化流水线和上线流程,让研制和测验的介入时刻前移。

解法:

1、分支逻辑

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

分支办理

SaaS 和私有化均根据 master 分支发布,非私有化版别周期内不特别区分 SaaS 和私有化。

私有化发布周期内独自创立对应版别的私有化分支,发布完结后向 master 分支合并。这样保证了 master 分支在任何状况下都应当能一起在 SaaS 环境和私有化环境中正常作业。

2、发布流水线

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

功用上线流程

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

发布流水线

内部搭建一套私有化预发布环境,建设了一套流水线,对 master 分支的 mr 会触发流水线一起在 SaaS 预发布环境和私有化预发布环境更新最新 master 分支代码,并履行自动化回归和人工回归测验。这样做的好处在于:

  • 推动了详细 Feature 的研制从技术方案规划层面考虑不同环境的 Diff 问题,削减了后期返工的本钱
  • 测验同学的作业化整为零,防止短时刻内的密集测验
  • 削减研制和测验同学的上下文切换本钱,SaaS 和私有化都在 Feature 开发周期内完结

应战2:性能优化

火山引擎 A/B 测验东西的陈述核算是根据 ClickHouse 完结的实时剖析。SaaS 采用多租户共用多个大集群的架构,资源弹性大,能够合理地复用不同租户之间的核算资源。

私有化则大部分为小规模、独立集群,不同客户一起运转的试验个数从几个到几百个不等,陈述观测时刻和用户习惯、公司作息相关,有显着的峰谷现象。因而试验陈述产出推迟、实时剖析慢等现象在私有化上愈加容易露出。

解法:

1、 试验陈述体系

首要,介绍下火山引擎 A/B 测验产品的试验陈述体系。以下图的试验陈述为例:

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

从上往下看产出一个试验陈述必要的输入包括:

  • 剖析的日期区间及过滤条件
  • 挑选合适的目标来评价试验带来的收益
  • 试验版别和对照版别
  • 陈述类型, 例如:做多天累计剖析、单天的趋势剖析等

目标如何定义呢?

组成目标的中心要素包括:

  • 由用户行为发生的事情及特点
  • 预置的算子

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

  • 四则运算符

即对于一个用户的某几个行为依照算子的规矩核算 value 并运用四则运算组合成一个目标。

由此,咱们能够大约想象出一个惯例的 A/B 试验陈述查询是经过试验射中状况圈出试验组或对照组的人群,剖析这类集体中在试验周期内的目标值。

由于 A/B 特有的置信水平核算需求,核算成果中需求体现方差等其他特殊核算值,所有聚合类核算如:求和、PV 数均需求聚合到人粒度核算。

2、 模型优化

如何区分用户射中哪一组呢?

集成 SDK 调用 A/B 分流方法的一起会上报一条试验曝光事情记载用户的进组信息,后续目标核算认为发生在进组之后的事情受到了试验版别的影响。举个例子:

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

进入试验版别 1 的事情 A 的 PV 数是 2,UV 数是 1,转化为查询模型是:

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

上述模型尽管最符合直觉,可是存在较多的资源糟蹋:

  • 曝光事情和普通事情存储在一张事情表中量级大
  • 曝光事情需求查找第一条记载,扫描的分区数会随着试验时刻的添加而添加
  • 曝光事情或许重复上报,核算口径中仅仅第一条曝光为有用事情

针对上述问题对核算模型做出一些优化,把曝光事情转化为特点记载在用户表中,新的模型变化为:

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

这么做带来的长处是:

  • 用户表不存在时刻的概念,数据增长=新用户增速,规模可控
  • 用户表自身会作为维度表在原模型中引进,这类状况下削减一次 join 运算 模型优化后经测验 14 天以上试验目标多天累计陈述查询时长削减 50%以上,且随试验时长添加提高。

3、 预聚合

私有化布置实施前会做前期的资源预估,现阶段的资源预估挑选了“日活用户”和“日事情量”作为首要输入参数。这里暂时没有参加一起运转的试验数量是由于:

一是,咱们期望简化资源核算的模型。

二是,一起运转的试验数量在大多数状况下无法提前预知。

可是该公式会引进一个问题:相同资源的集群在承载不同数量级的试验时核算量相差较大。试验数量少的场景下,当下数据处理架构轻量化,核算逻辑后置到查询侧,,目标核算按需运用,大大减轻了数据流使命的压力。

可是假定集群中一起运转 100 个试验,均匀每个试验关注 3 个目标加上试验的进组人数核算,在当前查询模型下每天至少扫描事情表 100*(3+1)次,假如再叠加运用自定义过滤模板等预核算条件,这个核算量会被成倍放大,直到导致查询使命堆积数据产出推迟。

从头调查试验陈述中心元素以及目标构成能发现:

  • 目标、陈述类型、试验版别是可枚举且预先知晓的
  • 试验射中和人绑定,版别对比先划分出进入对照组和试验组的人,然后做目标比较
  • 根据假定检验的置信水平核算需求按人粒度核算方差
  • 现有的目标算子均能够先按人粒度核算(按….去重除外)

是否能够经过一次全量数据的扫描核算出人粒度的所有目标和试验版别?

答案是能够的:扫描当天的事情数据,根据试验、目标装备核算一张人粒度的目标表 user_agg。

经过 user_agg 表能够核算出目标核算需求的 UV 数、目标的核算值、目标的方差。假如对 user_agg 表的才能做进一步拓宽,几乎能够替代原始表完结试验陈述中 80%以上的目标核算,一起也很好地支撑了天级时刻挑选切换、用户特点标签过滤等。

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

修改后的目标核算模型

经过经历数据,一个用户均匀每天发生的事情量在 100-500 条不等,聚合模型经过少数几回对当天数据的全表扫描得到一张 1/100-1/500 巨细的中间表,后续的目标核算、用户维度过滤均能够运用聚合表替代原始表参与运算。当然考虑到聚合自身的资源开支,收益会随着运转试验数添加而提高,而试验数量过少时或许会造成资源糟蹋,是否启用需求在两者之间需求平衡点。

应战3:安稳性

私有化服务的运维通道复杂、运维压力大,因而对服务的可用性要求愈加严厉。A/B 测验安稳性要求最高的部分是分流服务,直接决议了线上用户的版别射中状况。

分流服务自身面向故障规划, 采用降级的战略防止调用链路上的失利影响悉数试验成果,牺牲一部分实时性运用多级缓存保障单一根底设施离线的极点状况下分流成果仍然安稳。

还原火山引擎A/B测试产品——DataTester 私有化部署实践经验

分流服务全体架构

咱们将分流服务作为一个全体,一共运用了 3 级存储,分别是服务内存、Redis 缓存、关系型数据库。试验变动落库的一起,将变动音讯写入音讯行列,分流服务消费音讯行列修改内存和 Redis 缓存中的试验装备,保证多节点之间的一致性和实时性。一起分流服务敞开一个额外协程定时全量更新试验装备数据作为兜底战略,防止由于音讯行列故障导致的装备不更新;将 Redis 视作 Mysql 的备组件,恣意失效其中之一,这样分流服务即使重启仍然能够康复最新版别的分流装备,保障客户侧分流成果的安稳。

总结

火山引擎 A/B 测验(DataTester)脱胎于字节跳动内部东西,集成了字节内部丰富的事务场景中的 A/B 测验验经历;一起它又立足于 B 端市场,不断经过 ToB 市场的实践经历沉淀打磨产品来更好为内外部客户发明价值。

本文是火山引擎 A/B 测验(DataTester)团队在当前面向 ToB 客户的私有化实践中的实践共享,文中所遇到的私有化问题的破解进程也是这一产品不断打磨成熟,从 0-1 阶段走向 1-N 阶段的进程。

立即跳转 A/B测验 DataTester 了解概况!