Google cloud dataflow Apache BEAM管道IllegalArgumentException-时间戳偏移?

Google cloud dataflow Apache BEAM管道IllegalArgumentException-时间戳偏移?,google-cloud-dataflow,apache-beam,fluentd,Google Cloud Dataflow,Apache Beam,Fluentd,我有一个现有的BEAM管道,它正在处理通过2条路径摄取的数据(来自Google Pubsub主题)。“热”路径执行一些基本转换并将其存储在数据存储中,“冷”路径执行固定的每小时窗口,以便在存储之前进行更深入的分析 到目前为止,管道一直运行良好,直到我在发布到Pubsub之前开始对数据进行一些本地缓冲(因此数据到达Pubsub可能会晚几个小时)。引发的错误如下所示: java.lang.IllegalArgumentException: Cannot output with timestamp 2

我有一个现有的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)
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()));
它似乎引用了我的代码(withTimestamps方法)中执行每小时窗口的部分,如下所示:

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)
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()));
Window-Window=Window.into
(固定窗口(持续时间标准小时(1)))
.triggering(重复.forever(pastEndOfWindow()))
.允许延迟(持续时间.标准秒(10))
.丢弃燃烧的汽油();
PCollection keyToDataList=eData.apply(“添加事件时间戳”,带有timestamps.of(new EventTimestampFunction()))
.应用(“窗口化”,窗口)
.apply(“按键分组”,GroupByKey.create())
.apply(“按日期排序”,ParDo.of(new SortDataFn()));
我不确定我是否完全明白我在这里做错了什么。是因为数据延迟才抛出错误吗?据我所知,如果数据到达的时间超过了允许的延迟时间,那么应该丢弃它,而不是抛出像我看到的那样的错误


想知道设置一个无限制的时间戳是否能解决这个问题?迟到的数据可以免于分析,我只需要确保不会抛出会阻塞管道的错误。在其他任何地方,我都不会添加/更改数据的时间戳,因此我不确定抛出错误的原因。

看起来您的DoFn正在使用,您正在尝试设置一个比输入元素的时间戳旧的时间戳。通常,输出元素的时间戳来自输入,这对于确保水印计算的正确性非常重要

您可以通过增加时间戳倾斜和允许的延迟来解决这个问题,但是,有些数据可能会丢失,您可以确定这种丢失在您的场景中是否可以接受

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

你可以问自己的其他问题有:

  • 为什么与最新时间戳关联的输入元素比与输出元素关联的元素多
  • 在发布到PubSub之前,您真的需要缓冲这么多数据吗