爱奇艺数据湖实战-广告数据湖应用

01

   背景

广告数据主要包括效果、品牌和ADX等广告形式的请求和投放链路中产出的一系列日志,经过处理后,用于算法模型训练、广告运营分析、广告投放决策等场景。广告业务对数据的时效性、准确性以及查询性能要求较高。目前,广告数据链路整体采用Lambda架构,存在离线、实时两条链路,带来较高的使用成本和数据不一致性风险。

为了解决这些问题,广告数据团队与爱奇艺大数据团队一起积极调研大数据前沿技术,很早就关注到数据湖技术的兴起与发展。数据湖不仅支持大规模的数据存储,还具备近实时的时效性和交互级查询效率,非常契合广告数据场景需求。针对广告数据的一些痛点和难点,我们在数据湖中进行了一系列尝试,本文将按照不同的需求和业务场景进行简单介绍。

除了广告业务,数据湖已在爱奇艺二十几个业务场景下应用,大幅提升数据流通效率,促进业务提速增效。关于数据湖的技术细节及应用,可以阅读之前发表的《爱奇艺数据湖实战》。

02

   广告数据架构

广告业务数据分析场景经常需要查询过去几个月的数据,涉及大量的数据,同时又要求端到端低时延、查询速度快。基于Hive构建的数据仓库没法满足这样的需求,在迁移到数据湖之前,广告数据链路采用业界通用的Lambda架构:

  • 实时数据链路:通过Spark Streaming任务消费Kafka实时流数据写入到Kudu。为了提高查询性能,Kudu服务部署在独立OLAP集群。同时,基于成本考虑,仅保留最近7天的数据

  • 离线数据链路:广告业务查询还需要最近90天的数据,因此需要将公共集群(多业务共用)上的最近90天的广告Hive数据同步至独立OLAP集群上的Hive表中

  • 数据查询:基于数据进度拆分查询到实时表和离线表,使用Impala自动拼接Kudu和Hive中的数据

如图2-1所示。

4f246b6c8d3400982295a6eb544c795c.png

图2-1 广告Lambda架构

该方案存在以下几个缺点:

  • Lambda架构使用到多种不同的技术框架,带来较高的数据开发和使用成本

  • 离线数据定时同步,存在较大的数据延迟

  • 实时数据链路强依赖Kudu,无法保证端到端数据一致性

  • 独立OLAP集群造成数据冗余,存在额外的存储成本

为了解决这些痛点,广告引入了数据湖技术。数据湖的特性可以较好满足广告业务的需求:

  • 近实时写入:数据湖基于提交频率,数据延时可做到分钟级

  • 存储流批一体:数据湖既支持实时写入,也支持离线覆盖,无需异构的两套存储系统

  • 强一致性:数据湖修改保证原子性,可实现实时写入Exactly Once语义

  • 成本低:数据湖可共用现有的HDFS等大规模存储

目前,广告多个数据场景已接入数据湖,大幅提升数据的时效性。下一章节将介绍我们对这些场景的架构改造和相关优化。

03

   广告数据湖应用

  • 业务数据实时检索

广告主在查看广告的相关信息时,一般会查看广告本身的预算、当前的消耗以及广告的库存情况。其中,消耗和库存数据可从流量数据中通过计算获得,提供了实时和离线报表可供查询,但预算相关数据在业务库MySQL中保存,通过Sqoop拉取,只提供离线报表,延迟在1小时以上。为了优化用户体验提升整体的时效性,必须提高预算表的实时性。我们利用Flink CDC以及Iceberg v2类型支持update的特性,对预算链路进行改造,如图3-1。

5842494561a19e4c93211996d61501cb.png

图 3-1 预算链路

预算相关数据主要涉及广告主和广告订单等多张表的join,使用Flink CDC Connector访问MySQL的binlog日志,将结果集写入Iceberg v2类型的数据表。该表上线初期由于每次update都会生成一个文件,导致表的小文件数量过多,运行几天后,出现数据无法查询的情况。为解决该问题,首先在表结构上做了调整,设置了bucket分区,并配合bucket分区的定时合并策略,其次配置写表的分布式模式为hash,在数据落表之前根据分区进行shuffle,避免了每个节点都生成一个文件。

对外提供的数据报表都具有时间分区,比如小时或天级数据。上述Flink CDC导出的表不能直接对外使用,经过后续定时调度,全量读取后生成小时级报表,延迟由1小时降低到5分钟,至此就可与消耗和库存数据同时查看,完成整体链路的延迟优化。

  • 实时数仓

增量读取Iceberg是使用数据湖构建实时数仓的关键,为了进一步验证和测试可行性,使用数据量较大的库存数据来进行验证。广告实时数据的中间结果都输出至Kafka中,只有对外的报表数据落地。虽然Kafka在效率上能够满足广告的需求,但是数据不能保留太久,如果遇到问题需要排查,由于没有中间明细数据,排查起来十分困难。基于Iceberg的大存储高效率的特性,使用Iceberg构建的实时数仓能满足数据可追溯能重跑的需求,同时数据延迟在5分钟以内,具体方案如图3-2 所示。

7ac4bd16ceec40230cd694c91f0c6542.png

图3-2 增量读取Iceberg

原始日志关联字典表后入湖生成ODS表,后续的报表通过读该ODS表进行维度和指标计算生成中间表,进而生成ADS表。在该过程中,如果后续数据有问题,或需要排查故障,中间明细数据都保存至Iceberg中,随时可供查看。

其间遇到的主要问题是小文件过多,进而引起数据延迟。ODS表采取天、小时分区,并行度100,checkpoint间隔是1分钟。每分钟产生100个小文件,下游读ODS表的任务由于小文件太多,并且不限制一次读取的snapshot个数,引起checkpoint过大而失败,导致数据延迟较大。为了解决这一问题,表新增了bucket 分区,根据经验一个节点每分钟大概能处理160 MB左右,设置bucket分区的个数尽量一次commit的文件大小在100 MB左右。同时限制每次读取的snapshot的最大个数,另外需要注意的是任务开启checkpoint失败异常后会从checkpoint恢复,如果checkpoint无法恢复,任务需要配置start snapshot id,否则将从源表最开始读取。

上述优化上线后,ADS报表的延迟在3-4分钟左右,整体符合预期。

  • 实时OLAP分析

目前广告数据的Lambda架构中,实时数据写入Kudu,离线数据同步至OLAP集群,统一由Impala查询。由于Impala资源有限,对于频繁的百万行数据的查询,会出现查询压力较大导致集群不可用的情况。同时存在很多报表只有离线数据,数据延迟较大。为了缓解集群压力,同时提高数据的实时性,通过将实时和离线数据写入Iceberg的方案来实现。以广告奇麟小时报表为例进行具体说明。

奇麟数据目前只有小时报表,数据延迟时间大概2-3小时,时延较高,随着奇麟业务的逐步扩展,对数据时效性的要求提高,需要即时观察相关数据,进而开展了奇麟小时报表的实时化项目,如图3-3 所示。

ed14a1345a16175243cf3056797b3cc2.png

图3-3 奇麟小时报表优化

实时数据主要包括维表和原始日志,维表通过Flink CDC实时增量同步至Redis,原始日志通过关联Redis维表数据进行维度扩展(使用异步和缓存提升join效率),生成ODS表,写入Kafka,后续读取ODS表进行指标和维度计算后落Iceberg表。通过shuffle和bucket分区解决小文件等问题,同时开启主动缓存,加快数据的查询效率。

离线数据读取HDFS日志,经过离线数仓各层的报表计算关联业务维表产出奇麟报表,离线报表产出完成后,对实时表进行覆盖,包括小时级覆盖和天级覆盖,同时开启主动缓存。

通过实时和离线数据的改造,整体延迟从2-3小时降低至3-4分钟。

  • 实时ETL数据落地

效果广告中广告的一系列行为相关的日志包括广告的曝光点击等,由Tracking日志记录。随着业务需求的迭代开发,需要落盘到Tracking日志中的字段越来越多,Tracking url的长度越来越长,会造成2个问题:(1)广告应答的数据长度增加,导致响应延迟增加;(2)前端回传Tracking时可能发生截断,导致信息丢失。为了解决上述问题,将Tracking日志拆分成两部分实时数据,分别为“计费数据”与“流量数据”。但是为了便于后续链路构建及使用,在数据侧需要将这两部分数据关联合并成一个整体,同时考虑到以后的流批一体计算以及提高后续链路计算时效,所以我们决定入湖。结构如图3-4所示。

c62306008398a4cb18dff672ac30c2bb.png图3-4 实时ETL数据落地

为了下游使用方便,需要将“流量数据”、“计费数据”合二为一写入Iceberg,需要对这两部分数据做join。同时,因为业务需求和关联准确性要求,需要将“流量数据”保存很长一段时间,数据量有几十TB大小,我们选择使用HBase存储,然后使用“计费数据”实时批量关联HBase,同时考虑两条流量可能会有时间差,无法在第一次关联上,我们做了关联重试,基本上保证在合理情况下这两部数据能完全关联。因为设置了3次重试,会导致有十几分钟的数据延迟,后续可进一步优化。另外针对Iceberg数据小文件多问题,配置了小文件合并策略,显著降低小文件数量。目前已基于此入湖数据,构建了一条数据湖数仓应用链路,后续会逐渐将该链路投入应用并以此为模板推广应用到其他数据湖数仓构建。

目前该链路已经比较稳定,关键指标关联成功率在99%及以上,且相比离线链路至少小时级别的延迟,该链路只有十几分钟延迟(主要受关联重试影响),大幅提高了数据的时效性。同时基于数据湖,后续可以构建流批一体的计算,统一计算口径。

04

   未来展望

数据湖发展迅速,在公司内部成长也很快,广告数据接下来将使用数据湖实现流批一体的改造。目前离线数据落地HDFS,时效性差。实时和离线两套计算逻辑,容易造成数据不一致问题,同时开发和维护成本都很高,随着实时ETL数据的落地,将统一实时离线代码逻辑,实现流批一体。

另外,为了对外提供可查的完整数据,需要提供数据进度,当前为提供分钟级进度,Iceberg表的分区结构为 (dt,hour,timestamp),通过获取任务的延迟情况和表中分区的records数据来判断进度。分区结构导致了表的小文件较多,同时查看表的元数据耗时较长,进度存在延迟。目前正在尝试使用watermark的方案确定表的数据进度,相关结果待进一步测试验证。

同时期待数据湖在联邦查询及Flink Table Store等方面一展拳脚,为广告数据及其他数据场景提供新的启发!

e6fe1f9112c4a10e53c0a0b8b70f1872.jpeg

也许你还想看

Prometheus监控指标查询性能调优

爱奇艺DRM修炼之路

爱奇艺大数据加速:从Hive到Spark SQL

猜你喜欢

转载自blog.csdn.net/weixin_38753262/article/details/131485825