ADT(Advertising Tracking)广告追踪,也称它为移动广告效果监测,后面我们统称ADT。ADT的愿景是「希望帮助用户量化移动广告推广的效果,更聪明的使用每一分钱」针对这句话的字面意思能看到两个基本诉求:广告推广指标的量化和指标计算和呈现的实时性。这篇文章先介绍ADT到底是什么、它的价值何在、它又是如何工作的;再围绕ADT的愿景从技术层面展开讨论,也算是对我在TalkingData ADT团队工作的一个总结。
ADT是什么
移动广告效果监测的出现不是一个偶然,它是随着时代发展以及广告主和媒体之间不可达成一致的目标而产生的。移动广告效果监测作为第三方的监测平台主要服务于广告主和媒体两方
- 广告主
指想要推广自己产品的群体,这里的产品在移动广告中大部分指的都是一款具体的App。比如对于快驴进货App来说,广告主就是美团。 - 媒体
指帮助广告主做广告推广的渠道平台,媒体平台有大流量的也有小流量的。有些媒体会用数据画像帮广告主做更精准的投放。有的小媒体自身流量不大,靠一些非常规手段来达到赚钱目的。大的媒体比如有抖音、快手、腾讯视频、微信等等。
广告投放
广告投放过程比较容易理解,我们在日常生活中可能已经参与其中。我们就以一个互联网普通用户的角度来看一看广告投放整个过程,对于广告主而言,需要将待推广的移动App发布到各大应用商店,并在媒体平台中创建广告推广配置,其中会指定本次投放人群画像、投放时间、应用中心下载地址、投放量等等。之后媒体就可以按照广告主配置的投放规则开始投放了。我们在使用手机的时候会看到各式各样的广告,比如我们打开某个App时候会有开屏广告;在视频应用或短视频应用中也会有视频流广告;看新闻类应用时会有信息流广告。不管是哪种类型的广告,媒体平台都是根据你在平台的画像来投放匹配度更高的广告,这样才能更好的提高转换率。
从这个层面上来看,就是广告主在媒体平台上配置投放信息,之后媒体开始根据广告主的要求开始投放,其中会依赖自身平台对用户的画像做精准投放。但是广告主和媒体两方在最终结果上会存在很多认知上不一致的情况,也正是因为广告主和媒体的诸多不一致,第三方移动广告效果监测出现了。
广告监测平台解决的问题
上面介绍了广告主和媒体在场景中的角色,一个是诉求方,一个是被诉求方。那为什么还需要广告效果监测平台呢?
差异项 | 广告主 | 媒体 |
---|---|---|
广告结算 | 广告主与媒体结算没有依据 | 媒体自己提供结算清单 |
媒体质量 | 广告主难以评估媒体侧质量 | 对于媒体就是王婆卖瓜,自卖自夸 |
反作弊 | 广告主看不到投放媒体的作弊情况 | 媒体自身不会说自己在作弊 |
对接困难 | 广告主一般情况会对接多家媒体,每家媒体有自己的SDK | 没有行业标准,自行开发SDK |
数据延时 | 广告主对推广结果要求实时性较高,可以根据量化的指标实时调整投放策略 | 媒体没有实时监控能力,一般情况T+1出结果 |
广告效果监测作为第三方的监测平台以中立者的角色帮助广告主和媒体解决了以下几个问题
- 全实时系统
一套完全实时接收、实时计算、结果实时展示的系统。从数据接收到最终转换成指标展示到用户客户端,因数据窗口和指标原因数据延时一般在1秒到1分钟内。 防作弊体系
1
2跟利益有关的事情都会有团伙作案薅羊毛
━━━ 互联网从业者正式因为有羊毛薅,市面上涌现出了很多小媒体,打着为更好服务广告主的旗号薅着广告主的羊毛。而广告主可能完全被蒙在鼓里,还以为投放媒体实实在在的帮自己投放广告。作弊防护体系就是为了帮助广告主解决这样的痛点而诞生的。
- 媒体质量评估
一个好的媒体不光要保证数据的真实性,还要保证数据的准确性。准确性也会有一些指标综合来评估。 - 对接多家媒体
与各媒体、广告平台合作,对接600+广告平台,其中大的媒体包括腾讯广告、巨量引擎、Google、微博、百度、搜狗、微信、优酷、爱奇艺、快手、斗鱼、Bili等等。这样广告主在监测平台上的选择会非常多,而且非常方便。 - 广告结算
广告结算方式格式各样,比如CPM(Cost Per Mille)、CPA(Cost Per Action)、CPC(Cost Per Click)、CPS(Cost Per Sales)等等。监测平台可以根据广告主与媒体的结算方式出报告以及明细。
站在广告主与媒体之间
通过上面的分析与对比,ADT作为第三方监测平台的出现无疑是解决了广告主和媒体的许多痛点,那么广告监测平台在整个广告投放周期中是如何为广告主提供服务的?又是如何接入不同媒体的?在开始介绍之前我们先大概了解几个名词
短链
短链其实就是一个很短的连接,这条连接能确保访问到互联网上唯一一个资源。它的域名短、代表唯一资源的ID也很短。在生活中也会经常看到,比如网盘分享连接中除了域名部分剩下的就是短链;短信中也经常会出现短连接,下面就是美团发来的短信,其中包含了一个监测短连接0qd4lkh。1
【美团】因为您的良好资质,已为您调低利率,可享万元日息低至3元优惠,点击查看 dpurl.cn/0qd4lkh
定向人群
广告主投放广告时会根据媒体平台中提供的画像能力选择对应的人群投放,这样可以更精准触达同时也会更节省成本。
由于在广告主和媒体之间加了一层监测平台,数据交互起来比之前略微复杂一些。大体流程没有变化,只是在广告触发跳转的时候以及给用户反馈的时候发生了变化。另外,广告主的App中还会嵌入SDK,这样可以上报用户在App中后续的行为数据。
ADT面临的挑战
广告监测平台需要接收源源不断的曝光事件、点击事件和一大堆效果数据,并反复着、不停的实时处理一次又一次转化。对于监测平台而言,它的责任重大,不能多记,也不能少记录,如果转化记多了广告主需要多掏广告费给媒体,记少了媒体会有亏损。我们在实施落地过程中遇到了很多挑战
- 数据量大
有的媒体为了利益最大化经常会采取非正常手段模拟点击和曝光事件,所以广告监测平台除了会收到大量真实用户曝光和点击事件外也会收到许多造假的点击和曝光。在最“疯狂”的时候,监测平台仅点击事件一天就收到了45亿+的请求。要知道,这些点击事件是要保留下来作为后续效果归因用的,而且它们的有效期大不相同,从最短12小时到最长90天不等。 - 数据量不可预知
对于广告主的大推、应用商店竞价排名等一系列的推广会导致系统突发大量点击和曝光数据流入。对于这些流量不可预知的情况我们仍要保证系统的正确、稳定、实时。 - 点击和曝光存储
结合到业务最核心的功能就是归因,归因就是我们要找到用户手机里的某个App是由哪一个推广活动带来的,也就是要找到手机中的App是由于点击了哪个广告带来的。对于庞大的归因样本数据,有效期又各不相同,我们应该怎样存储点击和曝光事件才能让系统快速归因,不影响实时结果,这也是一个很大的挑战。 - 实时处理
广告主依赖广告监测平台实时处理的结果调整广告推广策略。因此广告监测平台需要支持数据实时处理,为广告主可以更快的对推广策略做出调整提供有力支撑。与此同时,广告监测平台的处理结果也要实时回传给媒体方以及广告主。可以看到准确性和实时性是系统必须要满足的基本条件。 - 事件处理顺序
事件在客户端产生时是有先后顺序的,但到了服务端由于各种原因顺序可能变了,但是又要考虑到数据处理的实时性,不能一直等待迟到数据。面对这种情况需要有一个处理方案,能尽量平衡数据的准确性和实时性。
存储容量及吞吐
面向全广告主、全媒体不可预知的曝光和点击事件数据,我们需要找到比较合适的存储选型。选型主要考虑存储的高吞吐和扩容的成本以及维护成本。经过对比最终我们选用了AWS DynamoDB,其实很多存储都可以满足我们的要求,但我们选用AWS DynamoDB的主要原因是AWS提供了全自动的扩容和缩容机制,可视化界面调整和Open API接口方式调整和监控。这比我们自建一套存储集群省去了学习成本和维护成本,把精力更多放到业务服务能力和监控上面。
梦想是伟大的,希望也是美好的。但在现实总是很残酷,我们在使用过程中遇到了问题
数据偏移
在DynamoDB中创建表时需要指定表的主键,这主要为了数据的唯一性、能够快速索引、增加并行度。主键有两种类型,「单独使用分区键」作为主键和「使用分区键+排序键」作为主键,后者可以理解为组合主键(索引),它由两个字段唯一确定/检索一条数据。DynamoDB底层根据主键的值对数据进行分区存储,这样可以负载均衡,减轻单独分区压力,同时DynamoDB也会对主键值尝试做“合理的”分区。
在开始我们没有对主键值做任何处理,因为DynamoDB会将分区键值作为内部散列函数的输入,其输出会决定数据存储到具体的分区。但随着运行,我们发现数据开始写入偏移了,而且非常严重,直接现象就是导致DynamoDB表的读写性能下降。发现这类问题之后我们考虑了两种解决办法
解决办法 | 优点 | 缺点 |
---|---|---|
对写入数据主键值追加随机数,将数据打散 | 能降低数据严重偏移 | 由于主键随机性,我们将无法根据主键查询,因此也失去了可读能力 |
对写入数据主键值做哈希 | 能降低数据严重偏移、哈希规则相同,可使用主键查询 | 好像没什么缺点 |
自动扩容潜规则
在解决了数据偏移之后读/写性能恢复了,但是运行了一段时间之后读写性能再次下降。这次数据写入并未偏移,当时我们将写入性能提升到了6万+/秒,但并不起任何作用,实际写入速度也就在2万+/秒。最后发现是我们的分区数量太多了,DynamoDB在后台自动维护的分区数量已经达到了200+个,严重影响了DynamoDB表的读写性能。
DynamoDB自动扩容、支持用户任意设定的吞吐量,这些都是基于它的两个自动扩容规则:单分区大小限制和读写性能限制
单分区大小限制
DynamoDB会自动维护数据存储分区,但每个分区大小上限为10GB,一旦超过分区大小会导致DynamoDB拆分区。这也正是数据偏移带来的影响,当数据严重偏移时,DynamoDB会默默为你的偏移分区拆分区。我们可以根据下面公式计算分区数量1
数据总大小 / 10GB 再向上取整 = 分区总数
比如表里数据总量为15GB,15 / 10 = 1.5,向上取整 = 2,分区数为2,如果数据不偏移均匀分配的话两个分区每个存储7.5GB数据。
读写性能限制
DynamoDB为什么要拆分区呢?因为它要保证用户预设的读/写性能。怎么保证呢?依靠每个分区数据在10G以内。触发自动扩容的另一个条件就是当分区不能满足预设吞吐量时,DynamoDB也会将分区进行扩充。DynamoDB对于每个分区读写容量定义如下:
- 写入容量单位
写入容量单位(WCU:write capacity untis),以每条数据最大1KB计算,最大每秒写入1000条。 - 读取容量单位
读取容量单位(RCU:read capacity units),以每条数据最大4KB计算,最大每秒读取3000条。
也就是说,一个分区的最大写入容量单位和读取容量单位是固定的,超过了分区最大容量单位就会拆分区。因此我们可以根据下面公式计算分区数量
1 | (预设读容量/3000) + (预设写容量/1000) 再向上取整 = 分区总数 |
比如预设的读取容量为500,写入容量为5000,(500 / 3000) + (5000 / 1000) = 5.1,再向上取整 = 6,分区数为6。
1 | 需要注意的是,对于单分区超过10G拆分后的新分区是共享原分区读写容量的,并不是每个表单独的读写容量。 |
冷热数据
我们一开始是单表操作。这样就算数据不偏移,但随着时间推移数据量越来越多,自然拆出的分区也越来越多。
因此,我们根据业务做了合理的拆表、设定了冷热数据表。这样做有几个好处
- 提升性能
这一点根据上面的规则显而易见,热表中数据量不会持续无限增长,因此分区也稳定在一定数量级内,保证了读写性能。 - 降低成本
无畏的为单表增加读写性能不仅效果不明显,而且费用也会极具增高,使用成本的增高对于谁都是无法接受的。DynamoDB存储也是需要成本的,所以可以将冷表数据存储到S3或其他持久化服务中,将DynamoDB的表删除,也是降低成本的一种方式。
逻辑上正确的处理顺序
用户从看到广告到把App下载安装到手机,再打开App,整个过程逻辑上的顺序应该是看到广告 -> 点击广告 -> 下载并安装App -> 打开App。这个顺序本身应该是按照先后顺序发生的,但到了服务端顺序可能就发生变化了。
图中上半部分描述的是当用户看到广告和点击广告事件触发后,监测平台收数据、处理、归因数据落盘的过程。下半部分描述的是用户将广告中推广的App安装并打开后,监测平台整体的数据接收、处理的过程。在这个过程中激活消息是有可能比对应的点击消息优先到达的,如果监测平台完全依据先到先得的顺序进行处理,那么会出现大量激活消息无法正常找到对应的点击或曝光事件,也就导致了数据错误。解决这个问题的同时还要兼顾数据处理的实时性,所以很多高延迟的办法被我们排除在外了。最终选了一个逻辑上卡时间窗的方案。
上图中描述的是一个时间窗实现的大概过程。由一个标记服务从Zookeeper中获取依赖时间窗事件的Topic元数据,再通过定时任务每一分钟触发一次,把触发时间发到Topic的每一个Partition中。就像下图一样,标记的数据和事件数据混在了每一个Partition中
数据与标记信息混在一起,由对应服务进行处理。整体原理依靠Zookeeper做分布式数据同步,消费进程消费分区中的正常事件消息和标记消息。曝光点击消息不受时间窗影响、激活受曝光点击时间窗影响,其他效果信息受激活时间窗影响。下图中仅体现了点击和激活的时间窗关系和同步原理。
反作弊
反作弊依赖各式各样的防作弊策略
- 位置迁移
- 黑名单
- 可疑设备