Apache BEAM管道IllegalArgumentException-时间戳偏斜?

时间:2018-06-20 02:21:12

标签: google-cloud-dataflow apache-beam fluentd

我有一个现有的BEAM管道,该管道通过2条路径处理从Google Pubsub主题提取的数据。 “热”路径进行一些基本的转换并将其存储在数据存储中,而“冷”路径执行固定的每小时窗口化,以便在存储之前进行更深入的分析。

到目前为止,管道一直运行良好,直到在开始发布到Pubsub之前我开始对数据进行一些本地缓冲(因此,到达Pubsub的数据可能要在几个小时后才开始)。引发的错误如下:

java.lang.IllegalArgumentException: Cannot output with timestamp 2018-06-19T14:00:56.862Z. Output timestamps must be no earlier than the timestamp of the current input (2018-06-19T14:01:01.862Z) minus the allowed skew (0 milliseconds). See the DoFn#getAllowedTimestampSkew() Javadoc for details on changing the allowed skew.
    at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnProcessContext.checkTimestamp(SimpleDoFnRunner.java:463)
    at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnProcessContext.outputWithTimestamp(SimpleDoFnRunner.java:429)
    at org.apache.beam.sdk.transforms.WithTimestamps$AddTimestampsDoFn.processElement(WithTimestamps.java:138)

似乎正在引用我的代码部分(withTimestamps方法),该部分执行以下每小时的窗口操作:

Window<KV<String, Data>> window = Window.<KV<String, Data>>into
                (FixedWindows.of(Duration.standardHours(1)))
    .triggering(Repeatedly.forever(pastEndOfWindow()))
    .withAllowedLateness(Duration.standardSeconds(10))
    .discardingFiredPanes();

PCollection<KV<String, List<Data>>> keyToDataList = eData.apply("Add Event Timestamp", WithTimestamps.of(new EventTimestampFunction()))
    .apply("Windowing", window)
    .apply("Group by Key", GroupByKey.create())
    .apply("Sort by date", ParDo.of(new SortDataFn()));

我不确定我是否完全了解我在这里做错了什么。是因为数据迟到引发了错误?据我了解,如果数据迟到了允许的延迟时间,则应将其丢弃,并且不会像我看到的那样引发错误。

想知道是否设置不受限制的时间戳转换可以解决此问题吗?可以将最新的数据排除在分析范围之外,我只需要确保不会抛出会阻塞管道的错误即可。在其他地方也没有添加/更改数据时间戳的地方,因此我不确定为什么会引发错误。

1 个答案:

答案 0 :(得分:0)

您的DoFn似乎正在使用“outputWithTimestamp”,并且您正在尝试设置一个比输入元素的时间戳还要早的时间戳。通常,输出元素的时间戳是从输入中得出的,这对于确保水印计算的正确性很重要。

您也许可以通过增加时间戳偏斜和允许的机翼延迟来解决此问题,但是,某些数据可能会丢失,您需要确定这种丢失是否适合您的情况。

另一种替代方法是不使用带有时间戳的输出,而是使用PubSub消息时间戳来处理每条消息。然后,将每个元素输出为KV,其中RealTimestamp的计算方式与您当前处理时间戳的方式相同(只是不要在“ WithTimestamps”中使用它),并使用GroupByKey将KV写入数据存储区。

您可以问自己的其他问题是:

  • 为什么输入元素与最近的时间戳相关联而不是输出元素?
  • 在发布到PubSub之前,您真的需要缓冲那么多数据吗?