Java Apache beam WithTimestamps:输出时间戳不得早于当前输入的时间戳

Java Apache beam WithTimestamps:输出时间戳不得早于当前输入的时间戳,java,google-cloud-dataflow,apache-beam,windowing,Java,Google Cloud Dataflow,Apache Beam,Windowing,我试图以10秒的频率从google cloud pubsub stream中打开数据窗口,但出现以下错误: java.lang.IllegalArgumentException:无法使用时间戳2019-07-20T12:13:04.875Z输出。输出时间戳不得早于当前输入的时间戳(2019-07-20T12:13:05.591Z)减去允许的偏差(0毫秒)。有关更改允许偏差的详细信息,请参阅DoFn#getAllowedTimestampSkew()Javadoc。 org.apache.beam

我试图以10秒的频率从google cloud pubsub stream中打开数据窗口,但出现以下错误:

java.lang.IllegalArgumentException:无法使用时间戳2019-07-20T12:13:04.875Z输出。输出时间戳不得早于当前输入的时间戳(2019-07-20T12:13:05.591Z)减去允许的偏差(0毫秒)。有关更改允许偏差的详细信息,请参阅DoFn#getAllowedTimestampSkew()Javadoc。 org.apache.beam.runners.dataflow.worker.repacked.org.apache.beam.runners.core.simpledofnlunner$DoFnProcessContext.checkTimestamp(simpledofnlunner.java:587) org.apache.beam.runners.dataflow.worker.repackaged.org.apache.beam.runners.core.simpledofnlunner$DoFnProcessContext.outputWithTimestamp(simpledofnlunner.java:566) org.apache.beam.sdk.transforms.dofnOutputReceiver$WindowedContextOutputReceiver.outputWithTimestamp(dofnOutputReceiver.java:80) WithTimestamps$AddTimestampsDoFn.processElement(WithTimestamps.java:136)

以下是导致错误的代码:

eventStream
  .apply("Add Event Timestamps",
    WithTimestamps.of((Event event) -> new Instant(event.getTime())))
  .apply("Window Events",
    Window.<Event>into(FixedWindows.of(Duration.parseDuration("10s"))));
eventStream
.apply(“添加事件时间戳”,
WithTimestamps.of((Event-Event)->new-Instant(Event.getTime()))
.apply(“窗口事件”,
Window.into(FixedWindows.of(Duration.parseDuration(“10s”)));

造成这种情况的原因是什么?合适的解决方案是什么?

来自文档:

如果输入{@link PCollection}元素具有时间戳,则输出 每个元素的时间戳不得早于输入元素的 时间戳减去{@link getAllowedTimestamp()}的值。如果 输出时间戳在此时间之前,转换将抛出 执行时{@link IllegalArgumentException}。使用{@link withAllowedTimestampSkew(Duration)}更新允许的偏移

注意:使用{@link#with allowedtimestaskew(Duration)}许可证 要在水印后面发射的元素。这些元素是 被认为晚了,如果在{@link后面 窗口#允许延迟(持续时间)允许延迟} {@link PCollection}可能会被静默删除

因此,为了解决这个问题,您可以使用AllowedTimestaskew来处理

我使用了不同的API:
withTimestampAttribute
。 您可以在JSON/AVRO中设置包含时间戳字段的属性

此API在发布时可用:

.apply(publisubio.writeAvros(Someclass.class)
.withIdAttribute(“id”)
.withTimestampAttribute(“myTime”).to(主题));
订阅时:

.apply(PubsubIO.readAvros(Someclass.class) .fromSubscription(...)
       .withIdAttribute("id").withTimestampAttribute("myTime"))