为GenericRecord分配内部对象的时间戳

时间:2019-06-12 15:35:20

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

由于Windows的存在,处理流事件并在每小时的存储桶中写入文件是一个挑战,因为传入小时中的某些事件可能会进入以前的事件中。

我一直在研究Apache Beam及其触发器,但是我正在努力按如下方式使用时间戳来管理触发器...

Window.<GenericRecord>into(FixedWindows.of(Duration.standardMinutes(1)))
                    .triggering(AfterProcessingTime
                     .pastFirstElementInPane()
                     .plusDelayOf(Duration.standardSeconds(1)))
                    .withAllowedLateness(Duration.ZERO)
                    .discardingFiredPanes())

到目前为止,这是我一直在做的事情,无论时间戳是什么,都会触发1分钟的窗口。但是,我想将时间戳记包含在对象中,以便仅针对其中的对象触发时间戳记。

Window.<GenericRecord>into(FixedWindows.of(Duration.standardMinutes(1)))
                .triggering(AfterWatermark
                    .pastEndOfWindow())
                .withAllowedLateness(Duration.ZERO)
                .discardingFiredPanes())

我要处理的对象具有时间戳记对象,但是,这是一个长字段,而不是Instant字段。

"{ \"name\": \"timestamp\", \"type\": \"long\", \"logicalType\": \"timestamp-micros\" },"

让我的POJO类具有long字段不会触发任何操作,但是如果我将其交换为Instant类并正确地重新创建对象,则每当读取PubSub消息时都会引发以下错误。 / p>

Caused by: java.lang.ClassCastException: org.apache.avro.generic.GenericData$Record cannot be cast to java.lang.Long

我也一直在考虑围绕GenericRecord创建一种包装类,其中包含一个时间戳,但是一旦准备好将FileIO写入.parquet,就需要在其中使用GenericRecord部分。

我还必须使用其他哪些方式使用水印触发器?

编辑:@Anton评论之后,我尝试了以下方法。

.apply("Apply timestamps", WithTimestamps.of(
            (SerializableFunction<GenericRecord, Instant>) item -> new Instant(Long.valueOf(item.get("timestamp").toString())))
        .withAllowedTimestampSkew(Duration.standardSeconds(30)))

即使它已被弃用,但它似乎已通过管道,但仍未写入(由于先前显示的触发器,由于某种原因仍在被丢弃之前写入?)。

还使用outputWithTimestamp尝试了另一种提到的方法,但是由于延迟,它打印出以下错误...

Caused by: java.lang.IllegalArgumentException: Cannot output with timestamp 2019-06-12T18:59:58.609Z. Output timestamps must be no earlier than the timestamp of the current input (2019-06-12T18:59:59.848Z) minus the allowed skew (0 milliseconds). See the DoFn#getAllowedTimestampSkew() Javadoc for details on changing the allowed skew.

0 个答案:

没有答案