Hazelcast Jet流处理结束窗口发射

时间:2018-07-25 19:16:28

标签: hazelcast-jet

我踩过一个有趣的观察,试图对流处理的聚合结果进行交叉检查。我创建了一个测试用例,其中将预定义的数据集输入到日记地图中,并且聚合应该填充1个结果,因为它与窗口大小/滑动度和带有预定时间戳的数据量一致。但是结果从未公布。没有发出窗口,但是执行了很少的累加/组合操作。它与实际数据的工作方式不同,但是聚合的结果始终“落后于”从源提取的数据量。我想这与水印有关吗?如何在测试用例中确保它不等待更多数据出现。允许延迟帮助吗?

2 个答案:

答案 0 :(得分:2)

首先,我将为您介绍手册中的两个部分,它们描述水印的工作方式,并讨论流偏斜的概念:

  1. http://docs.hazelcast.org/docs/jet/0.6.1/manual/#unbounded-stream-processing
  2. http://docs.hazelcast.org/docs/jet/0.6.1/manual/#stream-skew

Jet中的“当前时间”概念只有在时间戳记提前的情况下才有所发展。通常,有几个因素在起作用:

允许的延迟时间:假设您使用的是Kafka之类的分区源,这定义了每个分区的延迟。这描述了单个分区中时间戳的可容许乱序程度。如果允许的延迟为2秒,则仅当您在所有输入分区的N + 2秒处收到事件时,窗口才会关闭。

流偏斜:例如,当您有10个Kafka分区但只有3个正在产生任何事件时,就会发生这种情况。当Jet从所有分区合并水印时,这将导致流等待直到其他7个分区具有一些数据。超时后,这些分区将被视为空闲,但是默认情况下为60秒,并且当前无法在管道API中进行配置。因此,在这种情况下,除非将这些分区标记为空闲,否则您将没有任何输出。

使用测试数据时,事件量很少且分区很多是很常见的,这可能会给正确延长时间带来挑战。

答案 1 :(得分:1)

Can Gencer的答案中的点是有效的。但是为了进行测试,您也可以使用批处理源,例如Sources.list。通过将时间戳添加到BatchStage,可以将其转换为StreamStage,可以在其上进行窗口聚合。 aggregate转换将在批处理结束时发出挂起的窗口。

    JetInstance inst = Jet.newJetInstance();
    IListJet<TimestampedEntry<String, Integer>> list = inst.getList("data");
    list.add(new TimestampedEntry(1, "a", 1));
    list.add(new TimestampedEntry(1, "b", 2));
    list.add(new TimestampedEntry(1, "a", 3));
    list.add(new TimestampedEntry(1, "b", 4));

    Pipeline p = Pipeline.create();
    p.drawFrom(Sources.<TimestampedEntry<String, Integer>>list("data"))
     .addTimestamps(TimestampedEntry::getTimestamp, 0)
     .groupingKey(TimestampedEntry::getKey)
     .window(tumbling(1))
     .aggregate(AggregateOperations.summingLong(TimestampedEntry::getValue))
     .drainTo(Sinks.logger());

    inst.newJob(p).join();
    inst.shutdown();

上面的代码打印:

TimestampedEntry{ts=01:00:00.002, key='a', value='4'}
TimestampedEntry{ts=01:00:00.002, key='b', value='6'}

请记住,当我们使用allowedLag=0时,将您的数据按时间顺序排列在列表中。

答案对Jet 0.6.1。有效。