【问题标题】:Combining low-latency streams with multiple meta-data streams in Flink (enrichment)在 Flink 中将低延迟流与多个元数据流结合(丰富)
【发布时间】:2017-11-28 17:05:52
【问题描述】:

我正在评估 Flink 的流式分析场景,但没有找到足够的信息来说明如何实现我们今天在遗留系统中进行的一种 ETL 设置。

一个非常常见的场景是,我们有键控的、低吞吐量的元数据流,我们想使用这些流来丰富高吞吐量数据流,如下所示:

这引发了关于 Flink 的两个问题:如何通过缓慢更新时间窗口重叠但不相等的流来丰富快速移动的流(元数据可以存在几天,而数据可以存在几分钟)?以及如何使用 Flink 高效地连接多个(最多 10 个)流,比如一个数据流和九个不同的丰富流?

我知道我可以使用非窗口外部 ETL 缓存来实现我的 ETL 场景,例如使用 Redis(这是我们今天使用的),但我想看看 Flink 提供了哪些可能性。

【问题讨论】:

    标签: apache-flink flink-streaming


    【解决方案1】:

    Flink 有几种可用于丰富的机制。

    我将假设所有流共享一个可用于连接相应项目的公共密钥。

    最简单的方法可能是使用 RichFlatmap 并在其 open() 方法 (docs about rich functions) 中加载静态丰富数据。这仅适用于扩充数据是静态的,或者您愿意在想要更新扩充数据时重新启动扩充作业的情况。

    对于下面描述的其他方法,您应该将扩充数据存储为托管的键控状态(请参阅docs about working with state in Flink)。这将使 Flink 能够在失败的情况下恢复和恢复您的扩充作业。

    假设您想要实际流入丰富数据,那么RichCoFlatmap 更合适。这是一个有状态的运算符,可用于合并或连接两个连接的流。但是,对于RichCoFlatmap,您无法将流元素的时间考虑在内。例如,如果担心一个流领先或落后于另一个流,并希望以可重复、确定的方式执行丰富,那么使用CoProcessFunction 是正确的方法。

    您将在Apache Flink training materials 中找到详细示例和代码。

    如果您有许多流(例如 10 个)要加入,您可以级联一系列这些两个输入的 CoProcessFunction 运算符,但诚然,这在某些时候确实变得相当尴尬。另一种方法是使用联合运算符将所有元数据流组合在一起(请注意,这要求所有流具有相同的类型),然后是 RichCoFlatmapCoProcessFunction 加入这个统一的丰富流与主流。

    更新:

    Flink 的 Table 和 SQL API 也可用于流丰富,Flink 1.4 通过添加流时间窗口内连接扩展了这种支持。请参阅 Table API joinsSQL joins。例如:

    SELECT *
    FROM Orders o, Shipments s
    WHERE o.id = s.orderId AND
      o.ordertime BETWEEN s.shiptime - INTERVAL '4' HOUR AND s.shiptime
    

    如果发货发生在下订单的 4 个订单内,则此示例将订单与其对应的发货连接。

    【讨论】:

    • 谢谢!我能够通过一组自定义 CoProcessFunction 和自定义状态管理来解决我的用例,基本上解决了 Flink 在 DSL 样式 API 中缺乏的两件事:在不同的窗口大小上连接两个流(我微管理连接逻辑),并且真的滑动窗口(即不只是重叠的滚动窗口,不幸的是,Flink 社区将其称为滑动窗口)。不过,我相信 Jira 中的这两个功能都有问题单。
    • 很高兴您找到了解决方案。我添加了关于使用表和 sql API 进行时间窗口连接的更新,这可能更适合您的用例。这是在 Flink 1.4 中出现的,应该会在本周晚些时候发布。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 2015-06-28
    • 2020-06-29
    • 2012-10-17
    • 1970-01-01
    • 2017-10-29
    相关资源
    最近更新 更多