专栏名称: 蚂蚁技术AntTech
分享蚂蚁集团的技术能力和技术文化。
目录
相关文章推荐
程序员技术  ·  前美团员工求助:在美团背了个C绩效,慌得不行 ... ·  21 小时前  
51CTO技术栈  ·  突发!刚被OpenAI收购就惨遭Claude ... ·  2 天前  
极客之家  ·  22k star,微软硬核开源,让 ... ·  3 天前  
51好读  ›  专栏  ›  蚂蚁技术AntTech

万字长文详解|蚂蚁数据湖深度探索与业务应用实践

蚂蚁技术AntTech  · 公众号  · 程序员  · 2025-04-03 18:39

正文

请到「今天看啥」查看全文


checkpoint间隔 = 1分钟

方案三:append表

探索问题:

  • Flink写入表的方案有两种,用哪种比较合适?

1. 明细写入时在Flink任务去重

2. 明细写入时不去重,在下游聚合时去重

表设计:

广告曝光、点击、转化表

表类型

append表

基本参数设计

分区类型: 分区表

生命周期: 1天,按更新时间

分桶: 动态分桶

checkpoint间隔 = 1分钟

表高级参数设计

明细表的高级参数,主要针对表的写入和消费进行优化,此处列举我们考虑的参数如下

2.1.4 资源比较

写入任务

方案

表设计

方案一

宽表

aggregation宽表(小时分区)

aggregation宽表(天分区)

partial udpate宽表(天分区)

方案二

first_row主键表

动态分桶-曝光

动态分桶-点击

动态分桶-转化

固定分桶-曝光、点击、转化明细写入一张表

方案三

append表

flink不去重,写入点击、曝光、转化append表

flink去重,写入点击、曝光、转化append表

结论:
  • 整体资源消耗方面,方案三(不去重)<方案三(去重)<方案二(固定分桶)<方案二(动态分桶)<=方案一(天分区, partial update)<=方案一(天分区, aggregation),宽表>单一主键表>非主键表

  • 如果数据延迟较大且数据量大, 使用天分区 比较合适

  • 用Paimon去重数据时,数据量较大的情况下,使用 固定分桶的资源消耗较少 ,这是因为动态分桶会不断加大分桶数,导致写入资源消耗无限制扩大。

  • 明细数据是否去重写入append表,大致会带来两倍的资源消耗差距 ,所以在实际场景中,需要根据下游消费任务的数量是否足够多,数量越多,节约的下游去重资源就越多,这部分资源节约可能>在明细去重的资源消耗。

  • 方案一、二消耗几乎一致,但是宽表方案在 数据的存储上减少了冗余字段的存储 ,额外有节约存储资源。

消费任务

消费任务选择 【广告创意曝光次数】汇总场景的资源消耗情况 进行对比,用Paimon进行聚合计算。

方案

方案一 aggregation宽表(天分区),下游需要去重

方案一 partial update宽表(天分区),下游不需要去重

方案二,固定分桶表,下游不去重

方案三,写入时不去重,在下游去重

实验结论:

  • 涉及到 下游去重 的资源消耗几乎是 下游不去重 两倍

2.1.5 技术复杂度比较

写入任务

方案一 > 方案二 > 方案三

  • 方案一:开发调试需要花费较多的时间,因为涉及多个任务的同时写入更新,需要预估分桶数,写入宽表的任务调试花了不少时间

  • 方案二:一个任务直接写入三个主键表

  • 方案三:一个任务写入一个表,append表参数也是最少的

消费任务

方案一 > 方案三 > 方案二

  • 方案一:消费较为复杂,由于多种行为被关联了,需要判断不同行为对应的字段是否为空来判断是否为目标行为,涉及到aggregation表还需要对数据进行去重

  • 方案二:直接消费明细

  • 方案三:

  • flink去重:直接消费明细

  • 没有去重:下游消费时,需要在flink任务中去重

2.1.6 小结

结合上述资源比较和开发复杂度比较,笔者认为,在广告流量场景,选取 flink去重写入append表 方案资源消耗和开发复杂度是最优的。

2.2 维度表设计探索

2.2.1 现状与痛点

广告场景有众多实体关系(如下图),针对维度表的探索,我们聚焦在广告投放诊断产品场景,该产品需要针对“单元”实体的各类维度数据进行诊断,具体来说,需要将 创意、单元、计划、委托人、广告主维度表入湖,将多个维度的指标作为“状态指标”映射到 单元 上,以进行进一步的“诊断逻辑”判断。


当前该产品的数据加工链路中,实时使用Lindorm(类Hbase的存储引擎)作为维度宽表存储最新状态数据,离线用odps表存储历史状态数据,针对这两部分数据各自设计产品模块供用户使用。在数据湖中,怎么以实时离线一体化的形式将大量维度数据存储和映射?维度数据的历史存储问题怎么解决?这都是我们在数据湖维度表设计中遇到的问题。

2.2.2 探索思路

1. 基础维度表入湖及其schema设计探索

2. 维度宽表schema设计探索

3. 尝试实现将离线和实时数据在同一张湖表中存储,统一写入与消费方式

2.2.3 基础维表设计

表类型

适用场景

构建方案

非分区表

不需要留存历史数据

批任务初始化存量+流任务增量同步

分区表

需要留存历史的维度数据,实现流批一体

分区有两类:

  • 最新状态分区(latest)

  • 历史状态分区(YYYYMMdd)

写入方式:(1个初始化批任务,1个流任务,1个日调度批任务)

  • 最新状态分区:1个批任务初始化+1个流任务增量数据写入

  • 历史分区存储方式:

    • 方式一:【tag快照留存】每日0点生成tag,0点后通过flink批任务调度读取tag的数据,写入历史分区存档。--【缺陷】 可能存在0点左右的数据漂移偏差

    • 方式二:【增全量合并】t-1天增量 union t-1天之前的存量,每天flink批任务运行,具体可见下方数据链路

分区维度表-【增全量合并】写入方案示意 ⬇️
2.2.4 维度宽表设计

打宽方式

要创建一张维度宽表,首先需要确定如何进行打宽操作。Paimon主键表支持非主键关联(1:N)的扩展,因此可以使用多个实体的基础维表进行互相关联,以实现宽表(通过父维度left join子维度实现扩展)。打宽任务可以分为两个步骤:

1. 批任务初始化

2. 流任务增量数据写入
需要特别注意的是,如果直接采用这种方式进行打宽,当“父子维度对象均为新建(insert)且子维度数据比父维度数据晚到”时,父维度在关联子维度时将无法找到对应的子维度对象,从而导致这部分数据丢失。为避免这种情况,写入任务可以采用双流join、延迟关联或批任务回补等方式。

非分区表

适用场景: 不需要留存历史数据
方案:
    • 批任务初始化存量,有多少个上游数据来源,对应多少个批任务
    • 流任务增量同步,有多少个上游数据来源,对应多少个流任务

分区表

【讨论-使用标签留存历史快照】
维度表设置分区,主要是为了存储历史维度数据,而历史状态存储主要需要面对数据漂移的问题,而 维度宽表 的写入任务可能非常多,如果全都按照前述 基础维表方案 进行流批一体设计,复杂度会比较高,因此,如果用户能够容忍宽表的部分数据漂移,可以考虑结合Paimon的标签、分区机制,较简单地留存维度宽表历史数据,因此笔者在此处对标签的使用进行了一系列讨论。







请到「今天看啥」查看全文