Apache Flink:具有并行性的有序时间戳

我有一个数据流,其中事件的顺序很重要。时间特征设置为 EventTime,因为传入的记录中包含时间戳。

为了保证顺序,我将程序的并行度设置为 1。当我的程序变得更复杂时,这会成为性能方面的问题吗?

如果我理解正确,我需要为我的事件分配水印,如果我想保持按时间戳排序的流。这很简单。但我读到即使那样也不能保证顺序?稍后,我想对该流进行有状态计算。因此,为此我使用了一个 FlatMap 函数,它需要对流进行键控。但是,如果我键入流,订单将再次丢失。AFAIK 这是因为不同的流分区是由并行性“引起”的。

我有两个问题:

  • 我需要并行性吗?这里需要考虑哪些因素?

  • 我将如何通过上述内容实现“有序并行”?


千巷猫影
浏览 154回答 1
1回答

扬帆大鱼

需要考虑的几点:将整个作业的并行度设置为 1 将阻止扩展您的应用程序,这将影响性能。这是否真的重要取决于您的应用程序要求,但这肯定是限制,并且可能是一个问题。如果您提到的聚合旨在跨所有事件记录全局计算,那么并行操作将需要并行执行一些预聚合。但在这种情况下,您必须在作业图的后期阶段将并行度减少到 1,以产生最终(全局)结果。另一方面,如果要为某个键的每个值独立计算这些聚合,那么考虑对流进行键控并使用该分区作为并行操作的基础是有意义的。您提到的所有操作都需要某种状态,无论是计算最大值、最小值、平均值还是正常运行时间和停机时间。例如,您无法在不记住目前遇到的最大值的情况下计算最大值。如果我正确理解 Flink 的 NiFi 源连接器的工作原理,那么如果源并行运行,则对流进行键控将导致无序事件。但是,您提到的所有操作都不需要按顺序交付数据。在无序流上计算正常运行时间(和停机时间)将需要一些缓冲——这些操作需要等待无序数据到达才能产生结果——但这当然是可行的。这正是水印的用途;它们定义了等待乱序数据的时间。您可以在 ProcessFunction 中使用事件时间计时器来安排在处理完所有早期事件后调用 onTimer 回调。您始终可以对键控流进行排序。这是一个例子。使用 Flink 的 CEP 库(对输入进行排序,顺便说一句)应该很容易计算正常运行时间/停机时间。更新:确实,在将 ProcessFunction 应用于键控流后,流不再被键控。但是在这种情况下,您可以安全地使用reinterpretAsKeyedStream来通知 Flink 流仍然是键控的。至于 CEP,该库代表您使用状态,从而更容易开发需要对模式做出反应的应用程序。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java