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

时间:2018-11-05 16:20:13

标签: java apache-flink

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

为了保证顺序,我将程序的并行度设置为1。当我的程序变得更复杂时,这是否会成为一个问题,从性能角度考虑?

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

我有两个问题:

  • 我需要并行性吗?我需要在这里考虑哪些因素?
  • 如何用上述方法实现“有序并行性”?

1 个答案:

答案 0 :(得分:1)

要考虑的几点:

将整个作业的并行度设置为1将阻止扩展应用程序,这会影响性能。这是否真正重要取决于您的应用程序要求,但这肯定是限制,并且可能是一个问题。

如果您提到的聚合是针对所有事件记录进行全局计算,那么并行操作将需要并行进行一些预聚合。但是在这种情况下,您将不得不在工作图的后期将并行度降低到1,以产生最终的(全局)结果。

另一方面,如果这些聚合是针对某个键的每个值独立计算的,那么考虑对流进行键控并使用该分区作为并行操作的基础是有意义的。

您提到的所有操作都需要某种状态,无论是计算最大值,最小值,平均值还是正常运行时间和停机时间。例如,您不能不记住到目前为止所遇到的最大值就无法计算最大值。

如果我正确理解Flink的NiFi源连接器是如何工作的,那么如果源并行运行,则对流进行键控将导致乱序事件。

但是,您提到的所有操作都不需要按顺序传送数据。计算乱序流的正常运行时间(和停机时间)将需要一些缓冲-这些操作将需要等待乱序数据到达才能产生结果-但这确实是可行的。这正是水印的目的。他们定义等待无序数据的时间。您可以在ProcessFunction中使用事件时间计时器,以安排在处理所有较早的事件时调用onTimer回调。

您始终可以对键控流进行排序。这是an example

使用Flink的CEP库(对输入进行排序),可以很容易地进行正常运行时间/停机时间的计算。

更新:

的确,在将ProcessFunction应用到键控流之后,该流不再被键控。但是在这种情况下,您可以放心使用reinterpretAsKeyedStream来通知Flink流仍为键控。

对于CEP,该库代表您使用状态,这使得开发需要对模式做出反应的应用程序更加容易。