火山引擎 DataTester 广告投放 A/B 测试平台的重构实践

一、核心问题:广告投放测试的“混乱困境”

  1. 账号授权混乱:每个平台登录方式不同(有的用密码,有的用微信/支付宝授权),手动管理token和密码容易泄露,且授权流程重复开发(比如每个平台都要写一遍登录代码)。
  2. 数据处理低效:每天要从各平台拉取广告数据(如点击量、消耗金额),但数据格式五花八门(有的按“账户-广告组-计划”分层,有的按“账号-项目-广告”分层),用定时任务逐个拉取,就像用勺子舀水,慢且容易漏。
  3. 系统耦合严重,可维护性差:广告创建、数据查询等逻辑混在一起,改一个小功能可能影响整个系统,就像牵一发而动全身的毛衣,debug时无从下手。定制化需求导致代码碎片化,单测覆盖率低,线上故障频发。
  4. 查询速度慢:想看一周的广告报表要等几分钟,定时任务激增(一类数据对应一个任务),单平台日数据量达 GB 级,查询缓慢。

二、解决方案:分而治之的“模块化改造”

1. 服务拆分:让团队分工明确

  • 授权团队(授权服务):专门处理登录授权,支持密码登录和OAuth2令牌登录(类似手机的“一键登录”功能),自动刷新过期令牌(比如每天凌晨自动续期,不用手动重新登录)。
  • 数据团队(数据抓取服务):负责从各平台拉取数据,用“任务计划表”(DAG)安排任务顺序,比如先拉取广告基础信息(如广告ID、名称),再拉取报表数据(如点击量),就像做饭时先洗菜再切菜。
  • 业务团队(业务后端):专注广告创建和查询,比如根据授权的账号快速生成广告计划,或汇总数据生成报表。

2. 数据存储优化:给数据找“合适的柜子”

  • MySQL(小抽屉):存常用的基础数据(如广告名称、创建时间),方便快速更新和查询,像抽屉里的常用文件,随取随改。
  • ClickHouse(大仓库):存大量报表数据(如每天的点击、消耗),用“大柜子”的分层设计(Map字段)灵活扩展字段(比如不同平台的“转化率”“ROI”),查询速度比传统数据库快5倍以上。

3. 任务调度:用“时钟”管理任务

  • 时间轮算法:像钟表的指针,每小时检查一次该做什么任务(天级时间轮),每分钟检查一次细节任务(秒级时间轮)。比如每天8点自动拉取前一天数据,每小时5分同步最新点击量,避免同时处理上万任务导致卡顿。
  • DAG任务依赖:用“任务流程图”确保顺序正确,比如必须先有广告计划(元数据),才能生成报表(报表数据)。就像组装家具,必须先装框架再装抽屉。

4. 代码优化:像拼积木一样开发

  • DDD领域驱动设计:把业务拆成独立模块(如“广告创建模块”“数据查询模块”),每个模块像积木块,可单独开发和替换。比如新增一个广告平台时,只需修改“授权模块”的积木,其他模块不用动。
  • 单元测试+CI/CD:每个功能模块都写“小测试”(如检查授权是否成功),就像考试前做模拟题,确保代码正确。每次更新代码自动跑测试(CI/CD流水线),像流水线质检,不合格的代码不让上线。

三、关键技术细节:通俗版解析

1. OAuth2授权:免密码的“钥匙串”

  • 流程: 用户点击“用抖音授权”,跳转到抖音登录页(类似用微信登录其他APP)。登录后,抖音给平台发一个“临时钥匙”(auth_code),平台用这个钥匙换“长期钥匙”(Access Token),有效期24小时。快过期时,用“备用钥匙”(Refresh Token)自动续期,不用用户重新登录。
  • 模板方法模式
  • 把授权流程的“固定步骤”(如跳转、换钥匙)写成通用代码,不同平台只需调整“个性化步骤”(如抖音和百度的回调地址不同),避免重复写代码。

2. 时间轮算法:高效的“任务管家”

  • 传统方法:每天检查10万个任务,像逐个翻作业本,慢且容易漏。
  • 时间轮方法:建两个“任务表”,一个按天分类(每天8点做A任务,9点做B任务),一个按分钟分类(每分钟5秒做C任务)。指针走到对应时间点时,只处理该时间点的任务,就像课表按时间安排课程,不用一直盯着所有任务。

3. DDD分层:清晰的“业务三层楼”

  • 第一层(用户接口层):前台页面,只负责收用户指令和返回结果,像餐厅服务员,只负责点餐和上菜。
  • 第二层(应用层):中间协调层,告诉厨房(领域层)该做什么菜,比如“用户要创建广告,调用领域层的创建功能”。
  • 第三层(领域层):核心厨房,处理具体业务逻辑,比如“广告创建需要检查预算、素材合规性”,不依赖外部工具(如数据库),像厨师专注做菜,不管用什么品牌的锅。

四、成果:从“手忙脚乱”到“井然有序”

  1. 效率飙升: 新增一个广告平台从2周缩短到3天(因为授权模块可复用,像换锁不用重装门)。数据拉取延迟从小时级降到分钟级,报表查询从30秒缩短到5秒(用ClickHouse大仓库快速查数据)。
  2. 稳定性提升: 线上故障减少80%,因为模块解耦后,一个模块出问题不影响其他模块(如授权模块故障不影响数据查询)。单测覆盖率从30%提到85%,像考试模拟题覆盖85%的考点,上线后bug大幅减少。
  3. 成本降低: 定时任务数量减少50%,因为DAG和时间轮合并了重复任务(如多个平台的日数据拉取合并成一个任务)。一套代码支持SaaS和私有化部署,像一件衣服正反两面穿,节省开发资源。

五、总结:技术背后的“通用思维”

  • 分治思想:复杂问题拆成小问题(如服务拆分、DDD分层),就像把大象装进冰箱分三步。
  • 类比思维:用生活场景理解技术(如时间轮→钟表、DAG→任务流程图),降低理解门槛。
  • 数据驱动:通过重构让数据更准确、更及时,帮助企业科学决策,避免“拍脑袋”投放,就像用导航避开堵车,走最快的路。

火山引擎 DataTester 的重构实践通过架构分层解耦领域建模数据存储优化,解决了广告投放场景下多平台兼容、数据处理效率和系统可维护性的核心问题。其核心价值在于将复杂业务逻辑抽象为可复用的技术框架,同时通过工程化手段保障质量,为企业提供了高效、科学的 A/B 测试能力。未来可进一步扩展至跨平台数据融合、智能化实验推荐等场景,深化数据驱动增长的价值。

全部评论

相关推荐

评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务