“58 同城”架构师分享:联盟广告平台架构及实践
分享嘉宾:曲瑶 58 同城 架构师
导读:随着大数据的快速发展,大数据应用已经融入各行各业。在很多场景中得到了商业化实践。今天和大家分享下 58 同城联盟广告平台架构及实践。主要包括:58 联盟广告 SSP 媒体平台、投放平台、程序化创意等核心模块的设计和实现,以及对联盟业务的思考与展望。
01
联盟广告平台简介
1. 业务概述
58 联盟广告平台主要是以 58 站内的广告主为基础并结合站外流量,帮助 58 站内广告主获取站外潜在用户,从而实现流量变现。流量获取主要通过 SSP 和 DSP 这两种方式。
联盟 SSP 平台可直接与媒体对接,直接在媒体上展示投放的广告。DSP 是通过投放平台(例如百度 SEM、腾讯广点通等)投放到媒体上展示广告。
2. 业务架构
主要介绍以下四个模块:
① 同城宝 SSP
同城宝 SSP 主要是服务于媒体方(例如公众号,blog 站点),媒体方可以在此注册广告位,帮助媒体方实现流量变现。核心模块主要包括
媒体管理、广告位管理、广告管理、媒体报表、广告位报表、财务结算、流水记录等。
② 直投平台
直投平台是基于一些媒体平台(百度 SEM、广点通等)的 Marketing API 开发的一个平台,主要是更高效的进行广告投放,帮助我们更好的运营。核心模块主要包括统一投放网关、程序化创意生成、OCPX、账号管理、物料管理、报表服务、优化工具(批量操作、程序化调价等)等。
③ 联盟 DSP
主要与一些主流的 ADX 对接,服务于 58 运营,将运营创建的广告投放到媒体上。详细介绍见下文。
④ 创意平台
其实广告很重要的一部分就是创意,广告位的规格各种各样,比较碎片化。创意平台提供通过程序化工具生成创意图片、标题、描述等,来提高创意制作效率和效果。
02
媒体平台
1. 业务介绍
媒体平台主要服务于媒体方的,媒体方可以在此平台注册公司、注册媒体和注册广告位,获得投放链接、js 或 api,然后部署到自己的媒体上,从而通过提供广告位进行变现。
2. 对接模式
对接模式目前主要支持固定链、标签云、快捷图标和 API。
3. 架构
① 媒体方先在 SSP 平台上注册好广告位(包括公司、媒体和广告位配置信息),然后获取广告投放链接、js 或 api 接口等相关信息。
② 媒体方将获得的链接、js 或 api 接口等信息,部署到媒体方 App 或站点上。
③ 媒体方 App 或站点请求联盟广告 API,会转向到联盟 ADX,从而对接 58 站内广告库(包括房产、招聘、二手车、黄页等),对广告库内广告进行召回并在媒体方上投放广告。
④ 媒体方 App 或站点上的广告被展示或点击,会向联盟监测上报请求,最后数据落入联盟数据平台。
⑤ 根据最终广告效果,基于分成或服务费的模式,媒体方获取提供广告位的收入。
4. 效果评估
关于如何评估每个媒体的广告效果,主要有以下三种方式,目前 58 联盟主要使用 Cookie 方式。
① url
通过 URL 透传的方式,一直向下游传递广告来源参数,但维护成本高,中途容易丢失。
② 日志追溯
通过记录用户行为日志的方式进行离线归因的方式。处理用户行为日志是通过用户 SessionId 串联用户的所有行为,并按照时间戳进行排序,获取该用户第一次进入系统 URL,只需用户一跳带上来源标识即可获取用户的来源信息。缺点是工程层面无法实时归因。
③ Cookie
基于 Cookie 传输,维护成本低,各个系统可以从 Cookie 中实时获取用户信息,支持实时归因。
5. 劫持防范
流量劫持通常通过 DNS 劫持或路由器劫持的方式,将正常访问 58 的用户访问链接重定向为 302,然后在访问链接后面加上一些参数。可以采用使用全局 HTTPS、手动指定 DNS 和 HTTPS-DNS 解决流量劫持。
03
投放平台
1. 投放平台(MKT API)
由于线上主流的投放平台众多,如百度搜索、百度信息流、神马搜索、360 搜索、头条搜索、腾讯广点通、头条信息流等,每个投放平台都拥有自己的私有流量,如果想要全网投放广告,需要对接平台非常之多,运营营销人员维护起来非常繁琐。MKT API 投放平台主要是整合各投放平台,降低维护难度,减少运营成本。
2. 投放平台 ( MKT API ) 架构
Marketing API 模式存在的问题:
Marketing API 投放平台的模型依赖媒体侧用户画像,更适合拉新场景,但在 RT 场景无法充分利用广告主侧画像和模型;
无法按一次曝光精细化购买流量(频控、跨屏联动);
策略模型、投放数据、投放规则散落在各个外部 DSP,难以沉淀
3. 投放平台 ( DSP )
广告竞价流程:
通过 ADX(包含外部广告媒体(如广点通、今日头条 ADX) 和联盟 SSP 平台的 ADX)与我们联盟 DSP 平台对接,媒体方发起广告请求时,ADX 会将广告请求发送到 DSP,DSP 收到请求后会做简单的参数映射处理后,然后将请求转发给 DSP 广告检索服务,检索服务会从联盟 DMP 平台获取用户的画像,然后根据用户的偏好从广告库中检索广告,通过预算控制或 CPM 报价服务预估广告的出价返回给 ADX,ADX 竞价成功、广告展示或点击都会上报到监测接口。
广告所产生的数据(包括出价、获胜、展示、点击等)最终均落在数仓中。实时数据会基于 Flink 框架进行数据处理加工,最终存储在 Druid 或 ES 中。离线主要基于 Kylin 预计算进行 OLAP 多维分析
4. 投放平台 ( DSP ) 性能优化
RTB 实时竞价过程对性能要求非常高,对接外部 ADX 要求在 70ms 内返回竞价结果,我们 58 联盟内部的性能要求是在 50ms 之内返回竞价结果。由于我们 DSP 对接多方 ADX,QPS 达到了 10 万左右。如何提高我们系统性能呢?我们目前采用异步和延时这两种方式优化系统性能。
异步
异步一般适用 IO 比较密集、请求处理时间过长、线程数较多、高负载等场景。
起初我们使用的是阻塞线程模型,遇到一些 IO 操作(如查询 Redis,调用其他服务等),线程处于阻塞状态,导致一个线程只能处理一个请求,想要提高系统处理的请求数,只能通过增加线程数类解决。线程数过大会导致线程切换开销过大,内存占用较大。
我们采用 EventLoop-Thread 线程处理多个请求,减少锁的开销,避免线程爆炸问题。在代码层面采用 Future/Promise 解决异步回调开发繁琐,代码结构复杂,嵌套较多的问题。
异步与同步压测结果对比:
延时
我们的 DSP 平台主要是基于 Java 生态的,GC 问题会导致性能下降,对广告系统影响较大。这里介绍下我们关于 GC 遇到的一个问题及解决方案。
背景:在 DSP 竞价时,需要获取当前用户所在的城市信息,之前我们是通过 IP 来查询用户所在城市,并将 IP 和 CityId(城市信息)的对应关系使用 LRU 缓存起来。
问题:上线以后,发现每 2 小时出发一次 FullGC(Old 区内存为 2G),造成 600ms STW。
分析:发现我们线上服务 TP99 在 80ms 左右,理论上应该不会有存活对象进入老年代,但是发现每次 YoungGC 有 2M 左右,发现主要是 LRU 缓存中对象进入 Old 区。
解决方案:
我们之前 LRUCache 的对象数量将近 1600w 多个,进行 GC 时 JVM 会扫描存活的对象,这将产生 1000 多万次对象扫描的开销。为了避免这个问题,我们采用 Free GC 设计,通过声明一个 long 类型的三维数组(前 32 位代表时间戳,后 32 位地域 id),使用一块固定内存,这样在 GC 时只扫描一个对象。另外在凌晨 4:00 手动触发 System.gc(),避免对系统白天运行的影响。
效果:FullGC 间隔从之前的 2h 变成 30h;TP99 从 80ms 降低到 50ms;MEAN 从 13ms 降低到 11ms。
5. 投放平台 ( DSP ) 索引设计
目前 DSP 平台主要是对 58 内部运营开放,推广数并不是很大。我们目前采用一个主分片和多个从分片(主要是分摊查询流量),为保证索引可用性,我们采用了双索引设计。
6. 投放平台 ( DSP ) TB 级竞价缓存
由于一般 URL 的长度有限制,携带的信息有限,我们采用两级 Cache,将竞价信息,如召回策略、排序策略、预估 CTR 等中间环节数据写到到缓存中,在获胜、展示和点击时从缓存中获取数据。
7. 投放平台 ( DSP ) 竞价引擎
竞价引擎包含流量优选、召回、智能预算、过滤、CPM 报价策略和创意展示模块。
流量优选:基于反作弊手段和投放效果过滤掉一部分流量,从而减轻后链路数据计算处理的压力。
召回:基于广告排期人群定向媒体定向等规则从索引中召回广告。
智能预算:基于预算策略(快速消耗和平滑消耗),快速消耗则正常出价,平滑消耗使用 pCTR 出价策略。
过滤:基于频控策略,包含 DSP 内部频控策略和 ADX 联合频控策略。
报价策略:支持 CPM 和 CPC 两种报价模式,均提供固定模式和基于 ROI 调控模式报价。
创意展示:包含个性化创意和创意优选功能,个性化创意根据用户画像特征示,创意优选根据模板基于历史效果选择最优进行展示。
8. 投放平台(DSP) OLAP 多维分析
DSP 系统目前采用 Lambda 架构,以离线数据为准,保证数据的稳定性,历史数据可追溯。
9. 用户画像标签体系
标签体系主要是基于业务线构建的,上层支持 DSP、ADX、创意、落地页动态路径等应用。
04
程序化创意
由于站外媒体提供的广告位规格碎片化、创意长期投放会导致 CTR 下降需要定期更新和人工制作上传效率低,站内存在大量低质图片,导致用户体验不友好等问题,基于这些问题我们开发了程序化创意平台。建设程序化创意平台需要面临如何程序制作符合美学的图片和如何应对数据量和检索量过大的挑战。
1. 图片渲染
2. 架构
提供服务发布 API,供 DSP 投放平台、站内广告系统等。
创意图片渲染引擎(Creative-Builder),提供图片自动化生成,包含特征抽取、配置组装、规则优选、图片渲染等模块。从广告中抽取一些核心元素(如标题、标签等),根据用户的需求配置检索合适的模板然后进行组装,基于标签、配色等组合策略优选出合适的素材,然后进行渲染,并上传到 CDN,同时同步到创意索引中。
创意索引会基于 CTR 预估将多张创意图片针对不用用户进行优选,创意的展示点击数据会回传到我们平台,形成数据链路闭环。
3. 索引设计
程序化创意索引设计采用的是 58 自研云搜体系,当 shard 数量过多时,会导致读写扩散,增加 CPU 和 IO 额外开销,产生性能瓶颈。针对上述问题,我们对路由策略进行优化,尽量将查询路由到较少的分片上。
route-key 设计:58 大多数广告是城市加类别构成,很少有跨城市或类别的广告,基于这种业务场景,我们在路由设计时采用一级城市加二级类别作为 route-key,这样可以保证 95%的请求同一个 route-key,仅查询 1 个分片即可。
route-strategy:根据 route-key 的 hash 值取模来指定 soltId,另外还需人工配置路由表,配置中会记录每个分片和 soltId 的对应关系,并将配置记录在 Zookeeper 中。
路由策略仅由 IndexBuilder 和 Router(Redis) 控制,索引扩容时只需修改 RoutetConfig,增量数据就会使用新的路由策略构建索引,再针对待迁移 slot 触发重建即可,从而解决了索引扩容和重建的问题。
4. 展望
今天的分享就到这里,谢谢大家。
原文:https://mp.weixin.qq.com/s/ns0GtvI0NDFAZf-Q1TlYbA
推荐阅读
看完三件事
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
关注公众号 『 Java 斗帝 』,不定期分享原创知识。
同时可以期待后续文章 ing🚀
评论