数据缺乏的渠道正在推迟水印

时间:2018-05-18 15:18:17

标签: apache-flink flink-streaming

我有一个事件时间处理管道 类似的东西:

env.keyBy(_.key).process(myProcessFunction)

流程函数仅处理水印事件(这是因为它需要对事件进行排序,并根据该排序发出事件)。这样的过程功能已经多次显示,第一个与我在谷歌here上找到的相似。简而言之,它看起来像这样:

class MyProcessFunction extends ProcessFunction[Input, Output] {
   def open(config: Configuration) {
      //setup an ordered queue here
   }

   def processElement(event: Input, ..., out: Collector[Output]) {
      updateQueue(_.enqueue(event))
      context.timerService().registerEventTimeTimer(even.timestamp)
   }

   def onTimer(timestamp: Long, ..., out: Collector[Output]) {
      val watermark = ctx.timerService().currentWatermark()
      updateQueue{ queue =>
         while(queue.headOption.exists(_.timestamp < watermark) { 
            val event = queue.dequeue()
            out.collect(event)
         }
      }
   }
}

现在,假设我使用8的并行性,因为在大多数情况下,许多键都会流经这个系统。我自己编写了一些集成/单元测试,可以处理一小组数据。让我们说在这个数据中我们只有4个键。我遇到的可能是没有那么好记录的flink行为。

如果您查看StreamInputProcessor.processInput,特别是line 189处理水印并进入StatusWatermarkValve.inputWatermark,最后StatusWatermarkValve.findAndOutputNewMinWatermarkAcrossAlignedChannels,您会发现,分配给流的水印是所有“活跃”的MIN都是该流的频道。在运行时调试期间,我发现由于这些通道初始化为ACTIVE(StatusWatermarkValve的构造函数),因此它们会将流水印设置为Long.MIN_VALUE,直到至少一个水印进入每个通道。

这会产生一种行为,如果您拥有我上面列出的处理程序而您只有4个密钥,那么它们将永远不会被处理。

我有点担心水印不会传播到每个通道(可能是内存优化)。其次,我非常惊讶默认情况下将频道设置为ACTIVE,甚至在任何事件传递到它们之前。

我的问题是:在某种程度上可以解决这个问题吗?我希望能够处理这4个键。

我谈到了集成测试,因此解决方案可能只是减少测试中的并行性或添加密钥。但是我可以想到在实际执行期间我不喜欢这种行为的时间:在白天我有比夜晚更多的事件,所以我以一种处理当天的方式调整并行度,但在夜间管道将缺乏数据= &GT;一些频道将被闲置,因此会阻止其他频道的水印。这几乎让我相信这是一个错误,但我不能确定,这可能是有原因的。

0 个答案:

没有答案