• Flink + Hudi 实现多流拼接(大宽表)


    1. 背景

    经典场景

    Flink 侧实现

    业务侧通常会基于实时计算引擎在流上做多个数据源的 JOIN 产出这个宽表,但这种解决方案在实践中面临较多挑战,主要可分为以下两种情况:

    1. 维表 JOIN
    • 场景挑战:指标数据与维度数据进行关联,其中维度数据量比较大,指标数据 QPS 比较高,导致数据可能会产出延迟。
    • 当前方案:将部分维度数据缓存起起来,缓解高 QPS 下访问维度数据存储引擎产生的任务背压问题。
    • 存在问题:由于业务方的维度数据和指标数据时间差比较大,所以指标数据流无法设置合理的 TTL;而且存在 Cache 中维度数据没有及时更新,导致下游数据不准确的问题
    1. 多流 JOIN
    • 场景挑战:多个指标数据进行关联,不同指标数据可能会出现时间差比较大的异常情况。
    • 当前方案:使用基于窗口的 JOIN,并且维持一个比较大的状态。
    • 存在问题:维持大的状态不仅会给内存带来的一定的压力,同时 Checkpoint 和 Restore 的时间会变得更长,可能会导致任务背压

    我们基于Hudi Payload的合并机制,开发出了一种全新的多流join的解决方案:

    • 多流数据完全在存储层进行拼接,与计算引擎无关,因此不需要保留状态及其 TTL 的设置。
    • 维度数据和指标数据作为不同的流独立更新,更新过程中不需要做多流数据合并,下游读取时再 Merge 多流数据,因此不需要缓存维度数据,同时可以在执行 Compact 时进行 Merge,加速下游查询。

    该方案在存储层提供对多流数据的关联能力,旨在解决实时场景下多流 join遇到的一系列问题。

    2.核心能力

    2.1 Timeline (时间线)

    在所有的表中维护了一个包含在不同的即时(Instant)时间对数据集操作(比如新增、修改或删除)的时间轴(Timeline)。在每一次对hudi表的数据集操作时都会在该表的Timeline上生成一个Instant,从而可以实现在仅查询某个时间点之后成功提交的数据,或是仅查询某个时间点之前的数据,有效避免了扫描更大时间范围的数据。

    同时,可以高效的只查询更改前的文件(如在某个Instant提交了更改操作后,仅query某个时间点之前的数据,则仍可以query修改前的数据)。

    Action(操作行为):

    • COMMITS:数据提交
    • CLEANS:数据删除
    • DELTA_COMMIT:
    • COMPACTION:小文件合并
    • ROLLBACK:回滚
    • SAVEPOINT:保存点

    Timeline是hudi用来管理提交(commit)的抽象,每个commit都绑定一个固定时间戳,分散到时间线上。在Timeline上,每个commit被抽象为一个HoodieInstant,一个instant记录了一次提交(commit)的行为、时间戳和状态。

    上图的例子展示了10:00至10:20,每5分钟在 Hudi 表的 upsert 操作,时间线有 commit,clean 和 compact。同时还可以观察到 commit time 记录的是数据到达时间(如,10:20AM),而实际是按 event time (事件时间) 从7:00每小时一个分区来组织数据的。到达时间和事件事件是平衡数据延迟及完整性的两个主要概念。

    迟到的数据到来(如,事件时间是9:00,在>1小时之后的10:20到达),会根据事件数据写入到对应的分区。在时间线的帮助下,增量查询只需要读取所有在某一瞬间(instant time)以来 commit 成功的变更文件就可以获取到新数据,而不通过扫描所有的文件。

    资料领取直通车:大厂面试题锦集+视频教程icon-default.png?t=M85Bhttps://docs.qq.com/doc/DTlhVekRrZUdDUEpy

    Linux服务器学习网站:C/C++Linux服务器开发/后台架构师icon-default.png?t=M85Bhttps://ke.qq.com/course/417774?flowToken=1028592

    2.2. 并发控制

    2.2.1. 概述

    如今数据湖上的事务被认为是 Lakehouse 的一个关键特征。 但到目前为止,实际完成了什么? 目前有哪些方法? 它们在现实世界中的表现如何? 这些问题是本文的重点。 有幸从事过各种数据库项目——RDBMS (Oracle)、NoSQL 键值存储 (Voldemort)、流数据库 (ksqlDB)、闭源实时数据存储,当然还有 Apache Hudi, 我可以肯定地说,工作负载的不同深刻地影响了不同数据库中采用的并发控制机制。本文还将介绍我们如何重新思考 Apache Hudi 数据湖的并发控制机制。 首先,我们直截了当点,RDBMS 数据库提供了最丰富的事务功能集和最广泛的并发控制机制,不同的隔离级别、细粒度锁、死锁检测/避免等其他更多机制,因为它们必须支持行级变更和跨多个表的读取,同时强制执行键约束并维护索引。而NoSQL 存储提供了非常弱的保证,例如仅仅提供最终一致性和简单的行级原子性,以换取更简单的工作负载的更好的扩展性。传统数据仓库基于列存或多或少提供了您在 RDBMS 中可以找到的全套功能,强制执行锁定和键约束,而云数据仓库似乎更多地关注存算分离架构,同时提供更少的隔离级别。作为一个令人惊讶的例子,没有强制执行键约束。

    2.2.2. 数据湖并发控制中的陷阱

    从历史看来,数据湖一直被视为在云存储上读取/写入文件的批处理作业,有趣的是看到大多数新工作如何扩展此视图并使用某种形式的“乐观并发控制”(OCC)来实现文件版本控制。 OCC 作业采用表级锁来检查它们是否影响了重叠文件,如果存在冲突则中止操作,锁有时甚至只是在单个 Apache Spark Driver节点上持有的 JVM 级锁,这对于主要将文件附加到表的旧式批处理作业的轻量级协调来说可能没问题,但不能广泛应用于现代数据湖工作负载。此类方法是在考虑不可变/仅附加数据模型的情况下构建的,这些模型不适用于增量数据处理或键控更新/删除。 OCC 非常乐观地认为真正的冲突永远不会发生。将 OCC 与 RDBMS 或传统数据仓库的完全成熟的事务功能进行比较的开发人员布道是

  • 相关阅读:
    2023年香水行业数据分析:国人用香需求升级,高端香水高速增长
    山东大学单片机原理与应用实验 3.2 拓展并行I/O口实验
    ros2 服务节点源代码
    工程师必须记住的电路元件符号及英语翻译
    【产品新体验】CSDN开发云·云IDE使用教程
    不允许还有Java程序员不了解BlockingQueue阻塞队列的实现原理
    【科普】ARM架构
    新的希望就在小雪季节,人大与加拿大女王大学金融硕士邀你来享金融知识盛宴
    记一次 .NET某设备监控自动化系统 CPU爆高分析
    Redis常见错误
  • 原文地址:https://blog.csdn.net/weixin_52183917/article/details/127769074