Apache Beam:RabbitMqIO水印未增强

时间:2019-04-17 22:04:53

标签: rabbitmq apache-beam

请给我一些帮助。我正在尝试将Apache Beam与RabbitMqIO源(版本2.11.0)和AfterWatermark.pastEndOfWindow触发器一起使用。看来RabbitMqIO的水印没有提高,并且保持不变。由于此行为,AfterWatermark触发器不起作用。当我使用其他不考虑水印的触发器时,它可以工作(例如:AfterProcessingTime,AfterPane),在下面,我的代码,谢谢:

public class Main {

private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);

// Window declaration with trigger
public static Window<RabbitMqMessage> window() {
    return Window. <RabbitMqMessage>into(FixedWindows.of(Duration.standardSeconds(60)))
            .triggering(AfterWatermark.pastEndOfWindow())
            .withAllowedLateness(Duration.ZERO)
            .accumulatingFiredPanes();
}

public static void main(String[] args) {
    SpringApplication.run(Main.class, args);

    // pipeline creation
    PipelineOptions options = PipelineOptionsFactory.fromArgs(args).create();
    Pipeline pipeline = Pipeline.create(options);

    // Using RabbitMqIO
    PCollection<RabbitMqMessage> messages = pipeline
            .apply(RabbitMqIO.read().withUri("amqp://guest:guest@localhost:5672").withQueue("test"));

    PCollection<RabbitMqMessage> windowedData = messages.apply("Windowing", window());

    windowedData.apply(Combine.globally(new MyCombine()).withoutDefaults());

    pipeline.run();
    }

}

class MyCombine implements SerializableFunction<Iterable<RabbitMqMessage>,   RabbitMqMessage> {

private static final Logger LOGGER = LoggerFactory.getLogger(MyCombineKafka.class);

/**
 * 
 */
private static final long serialVersionUID = 6143898367853230506L;

@Override
public RabbitMqMessage apply(Iterable<RabbitMqMessage> input) {
    LOGGER.info("After trigger launched");
    return null;
}

}

1 个答案:

答案 0 :(得分:1)

我花了很多时间研究这个问题。打开https://issues.apache.org/jira/browse/BEAM-8347后,我将some notes留在了故障单中,我认为当前实现存在问题。

此处重新陈述:

UnboundedSource.getWatermark的文档内容如下:

  

[水印]可以近似。如果读取的记录违反了此保证,则将其视为较晚的记录,这将影响   他们将被处理。 ...

     

但是,该值应尽可能晚。在此水印通过后,下游窗口可能无法关闭   结束。

     

例如,源可能知道其读取的记录将按时间戳顺序。在这种情况下,水印可以是时间戳记   最后读取的记录。对于不自然的来源   时间戳记,可以将时间戳记设置为阅读时间,其中   如果水印是当前时钟时间。

UnboundedRabbitMqReader中的实现使用最早的时间戳作为水印,这违反了上述建议。

此外,应用的时间戳是传递时间,该时间应单调增加。我们应该可靠地能够在传递的每条消息上增加水印,这基本上可以解决问题。

最后,即使没有 消息出现,我们也可以增加水印。如果没有新消息,则应遵循所采用的方法来推进水印在流“赶上”时在kafka io TimestampPolicyFactory中。在这种情况下,我们将在看不到任何新消息时将水印增加到max(current watermark, NOW - 2 seconds),只是为了确保Windows /触发器可以触发而不需要新数据。


不幸的是,由于Rabbit实现不支持扩展,并且大多是私有或包私有的,因此很难在本地进行这些细微修改。

更新:我已经打开上游PR来解决此问题。此处的更改:https://github.com/apache/beam/pull/9820