Apache flink 数据匮乏的通道正在延迟水印

Apache flink 数据匮乏的通道正在延迟水印,apache-flink,flink-streaming,Apache Flink,Flink Streaming,我有一个事件时间处理管道 比如: env.keyBy(_.key).process(myProcessFunction) process函数仅处理带水印的事件(这是因为它要求对事件进行排序,并根据排序发出事件)。这样一个过程函数已经展示了很多次,第一次类似于我在谷歌上发现的。简而言之,它看起来是这样的: class MyProcessFunction extends ProcessFunction[Input, Output] { def open(config: Configurati

我有一个事件时间处理管道 比如:

env.keyBy(_.key).process(myProcessFunction)
process函数仅处理带水印的事件(这是因为它要求对事件进行排序,并根据排序发出事件)。这样一个过程函数已经展示了很多次,第一次类似于我在谷歌上发现的。简而言之,它看起来是这样的:

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)
         }
      }
   }
}
MyProcessFunction类扩展了ProcessFunction[输入,输出]{ def打开(配置:配置){ //在此处设置有序队列 } def processElement(事件:输入,…,输出:收集器[输出]){ updateQueue(u.enqueue(事件)) context.timerService().registereventtimeter(偶数.timestamp) } def onTimer(时间戳:长,…,输出:收集器[输出]){ val watermark=ctx.timerService().currentWatermark() updateQueue{queue=> while(queue.headOption.exists(u.timestamp<水印){ val event=queue.dequeue() 外出。收集(活动) } } } } 现在,让我们假设我使用8的并行性,因为在大多数情况下,许多键都流经这个系统。我自己编写了一些集成/单元测试,这些测试使用一小部分数据。让我们假设在这些数据中,我们只有4个键。我遇到的可能是flink的一个没有很好记录的行为

如果您查看StreamInputProcessor.processInput,特别是在处理水印和跟踪的上,最终您会发现,分配给流的水印是该流的所有“活动”通道的最小值。在运行时调试期间,我发现,由于这些通道被初始化为活动通道,因此(StatusWatermarkValve的构造函数),他们会将streams水印设置为Long.MIN_值,直到至少有一个水印进入每个通道

这会导致一种行为,如果您有我上面概述的处理程序,并且您只有4个键,那么它们将永远不会被处理

我有点惊讶,水印并没有传播到每个通道(可能是内存优化)。其次,我非常惊讶通道在默认情况下设置为活动,甚至在任何事件传递到通道之前

我的问题是:是否有可能解决这个问题?我希望能够处理这4个键。


我谈到了集成测试,所以解决方案可能只是减少测试中的并行性,或者添加键。然而,我可以想到在实时执行期间我不喜欢这种行为的时候:白天我的事件比晚上多得多,因此我以一种处理白天的方式来调整并行性,但在晚上,管道将是最复杂的arved for data=>一些通道将不使用,因此会暂停其他通道的水印。这几乎让我相信这是一个错误,但我不能确定,这可能是有原因的。

我发现了一个可能相关的错误报告-它是相关的,因为我在描述中遗漏的是我正在使用kafka源