从技术角度来说,广告业务涉及到 AI算法、大数据处理、检索引擎、高性能和高可用的工程架构 等多个方向,同样有着不错的技术吸引力。
我从去年开始接触广告业务,到现在差不多一年时间了。这篇文章将结合我的个人经验,同时参考业界的优秀案例,阐述下广告系统的架构实践方案,希望让大家有所收获。内容包括以下3部分:
一、广告业务简介
广告,可以说无处不在。微信、抖音、B站、百度、淘宝等等,这些占据用户时间最长的 APP, 到处都能看到广告的影子。
我们每天随处可见的广告,它背后的业务逻辑到底是什么样的呢?在分享广告系统的架构之前,先给大家快速普及下业务知识。
为什么说广告业务的核心点是「平衡」?可以从广告的标准定义来理解。
广告被定义为:广告主以付费方式通过互联网平台向用户传播商品或者服务信息的手段。这个定义中涉及到 广告主、平台、用户 3个主体,但是这3个主体的利益关注点各不相同。
图1:广告业务的三角平衡
广告主:关注ROI,花了钱是否能带来预期收益
平台:拥有流量,关注收益能否最大化
用户:关注体验,广告是否足够精准?是否影响到了正常功能的使用?
有时候这三者的利益是冲突的,比如平台增加了广告位数量,收益肯定增加,但用户体验可能变差,因此广告业务最终要寻找的是三方的平衡。
站在平台的角度来看广告业务,它在保证用户体验的同时,要兼顾绝大部分广告主的ROI(确保他们是可以赚到钱的),在此基础上再考虑将平台的收入最大化,这样才是一个健康的广告生态。
广告业务发展了几十年,广告费用的结算方式也诞生了很多种,我们最常见的有以下几种:
图2:广告费用的结算方式演进
之所以有不同的结算方式,其实也是随着广告市场的发展逐渐衍生出来的,最开始流量稀缺,平台占优势,再到今天逐渐成了买方市场,广告主作为需求方的谈判权变大。
上面这个图可以看出,由于CPA代表了广告主最终想要的转化效果,因此按CPA结算时对广告主最有利,但是对平台最不利。结算方式演进到今天,其实也是一种平衡,所以处于平衡点附近的CPM和CPC是最常见的结算方式。
以CPC为例,收入可分解成下面这个公式:
其中,PV表示系统的访问量,PVR和ASN表示广告的填充率,CTR表示广告的点击率,ACP表示广告的平均点击价格。
上述各个指标都可以通过一系列的广告策略来提升。比如填充率可通过开发更多的广告主来实现,CTR可通过AI算法做到精准投放来提升,ACP可通过精准流量溢价或者提升广告主ROI来完成。
掌握上面这个收入分解公式,对于理解广告业务至关重要,任何业务上的动作几乎都能关联到这个公式的某个指标上。
广告业务发展到今天,随着广告主对投放效果的诉求不断加强,精准定向以及实时竞价是目前最主流的业务形态。
对互联网平台来说,初期一般都是采用「自营的竞价广告网络」来实现商业变现,简单理解:就是利用平台自有的流量以及自主开发的广告主来实现业务闭环。本文所分享的广告架构主要针对这种业务形态,它的核心业务流程如下图所示。
图3:广告的核心业务流程
上面是广告业务的核心流程,随着平台流量以及广告主规模进一步增大,往往会从「自营型竞价网络」逐渐向「联盟广告以及RTB实时竞价」方向发展,类似于阿里妈妈、腾讯广点通、头条巨量引擎,此时业务复杂度和技术架构会再上一个台阶,本文不作展开,后续再跟大家详细分享。
二、面临的技术挑战
对广告业务有了初步了解后,再来看下广告系统面临的技术挑战:
1、高并发:广告引擎和C端流量对接,请求量大(平峰往往有上万QPS),要求实时响应,必须在几十毫秒内返回结果。
2、业务逻辑复杂:一次广告请求,涉及到多路召回、算法模型打分、竞价排序等复杂的业务流程,策略多,执行链路长。
3、稳定性要求高:广告系统直接跟收入挂钩,广告引擎以及计费平台等核心系统的稳定性要求很高,可用性至少要做到3个9。
4、大数据存储和计算:随业务发展,推广数量以及扣费订单数量很容易达到千万甚至上亿规模,另外收入报表的聚合维度多,单报表可能达到百亿级别的记录数。
5、账务的准确性:广告扣费属于金融性质的操作,需要做到不丢失、不重复,否则会损害某一方的利益。另外,如果收入数据不准确,还可能影响到业务决策。
三、广告系统架构详解
了解了广告业务的目标和技术挑战后,接下来详细介绍下广告系统的整体架构和技术方案。
图4:广告系统的整体架构
上面是我们公司目前的广告系统架构图,这个架构适用于广告业务初期,针对的是「自营型的竞价网络和站内流量」,不涉及联盟广告。
下面针对各个子系统做下说明:
下面再针对架构中的技术难点展开做下介绍。
广告系统要存储的数据多种多样,特点各不相同,采用的是多模的数据存储方式。
图5:广告数据的多模存储
OLTP场景,包括广告库、创意库、会员库、广告产品库、广告策略库等,这些都存储在MySQL中,数据规模较大的广告库和创意库,按照广告主ID Hash做分库分表。
OLAP场景,涉及到非常多的报表,聚合维度多,单表的记录数可能达到百亿级别,底层采用HDFS和HBase存储。
面向广告检索场景的索引数据,包括正排索引和倒排索引,采用Redis和ES来存储。
存储上还需要解决的一个问题是:广告的同步问题。广告投放完成后,首先会存储在MySQL数据库中,接下来需要把广告实时传输到检索系统中,完成正排索引以及倒排索引的更新。
图6:广告索引的更新流程
索引更新服务,有几个要点说明下:
广告检索平台负责承接C端的流量请求,从海量广告库中筛选出最合适的前N个广告,并在几十毫秒内返回结果,它是一个多级筛选和排序的过程。
图7:广告检索平台的整体流程
Recall层侧重算法模型,Search层侧重业务。从下到上,计算复杂度逐层增加,候选集逐层减少。(说明:搜索广告场景和推荐广告场景在某些子模块上存在差异,但整体流程基本一致,这里不作展开)
性能设计是检索平台的重点,通常有以下手段:
计费平台也是一个核心系统,主要完成实时扣费功能。比如CPC结算方式下,广告主设置的预算是50元,每次点击扣1元,当扣费金额达到预算时,需要将广告及时下线。
除此之外,计费平台还需要支持CPM、CPT等多种结算方式,以及支持反作弊、余额撞线处理、扣费订单的摊销和对账等功能。
计费平台的特点是:并发高、数据量大、同时可用性要求高,需要做到不少扣,不重复扣。下面以CPC实时点击扣费为例,详细说下技术方案。
图8:CPC实时扣费流程
首先,整个扣费流程做了异步化处理,当收到实时扣费请求后,系统先将扣费时用到的信息缓存到Redis,然后发送MQ消息,这两步完成后扣费动作就算结束了。
这样做的好处是:能确保扣费接口的性能,同时利用MQ的可靠性投递和重试机制确保整个扣费流程的最终一致性。
为了提高可用性,针对Redis和MQ不可用的情况均采用了降级方案。Redis不可用时,切换到TiKV进行持久化;MQ投递失败时,改成线程池异步处理。
另外,每次有效点击都需要生成1条扣费订单,面临大数据量的存储问题。目前我们采用的是MySQL分库分表,后期会考虑使用HBase等分布式存储。另外,订单和账务系统之间的数据一致性,采用大数据平台做天级别的增量抽取,通过Hive任务完成对账和监控。
数据报表是也是广告平台的核心业务,它是广告主、平台运营人员进行投放优化、业务决策的依据。先来看下广告数据仓库的分层结构:
图9:广告数据仓库的分层结构
采用这样的分层结构,和软件分层思想类似,提高了数据的维护性和复用性。
再来看应用层报表部分面临的挑战:聚合维度多,需要分时、分广告位、分推广等几十个维度;单表最大达到百亿级别;支持时间范围的实时查询。
这部分由公司的大数据部门维护,采用了开源的技术方案,离线部分使用Kylin,数据存储在HBase中;实时部分使用Flink和Spark Streaming,数据存储在Druid中。
四、写在最后
本文详细介绍了广告系统的初期架构和核心技术方案。随着业务演进,架构也会随之变得更加复杂,但是大数据存储、高并发、高可用,始终是广告业务的技术难点。
关于广告系统的稳定性保障、广告策略的可扩展性设计、RTB实时竞价的系统架构等有价值的内容,后续再分享给大家,欢迎关注我的公号。针对本篇文章,如果有任何疑问或者建议,可以留言讨论。
如果字段的最大可能长度超过255字节,那么长度值可能…
只能说作者太用心了,优秀
感谢详解
一般干个7-8年(即30岁左右),能做到年入40w-50w;有…
230721