Apache flink 什么';s KeyedStream#timeWindow#进程中键和窗口实例之间的关系
对于Apache flink 什么';s KeyedStream#timeWindow#进程中键和窗口实例之间的关系,apache-flink,Apache Flink,对于KeyedStream#timeWindow#process,我想知道一个窗口实例是否只包含相同的键,而不同的键将使用不同的窗口实例 从以下应用程序的输出中,我看到一个窗口实例将只包含相同的键,而不同的键将使用不同的窗口 但我想问一下并确认一下,谢谢 import org.apache.flink.streaming.api.functions.source.{RichParallelSourceFunction, SourceFunction} import scala.util.Ran
KeyedStream#timeWindow#process
,我想知道一个窗口实例是否只包含相同的键,而不同的键将使用不同的窗口实例
从以下应用程序的输出中,我看到一个窗口实例将只包含相同的键,而不同的键将使用不同的窗口
但我想问一下并确认一下,谢谢
import org.apache.flink.streaming.api.functions.source.{RichParallelSourceFunction, SourceFunction}
import scala.util.Random
class KeyByAndWindowAndProcessTestSource extends RichParallelSourceFunction[Int] {
override def run(ctx: SourceFunction.SourceContext[Int]): Unit = {
while (true) {
val i = new Random().nextInt(30)
ctx.collect(i)
ctx.collect(i)
ctx.collect(i)
Thread.sleep(1000)
}
}
override def cancel(): Unit = {
}
}
申请表格如下:
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.scala.function.ProcessWindowFunction
import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.util.Collector
import org.apache.flink.api.scala._
object KeyByAndWindowTest {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
env.getCheckpointConfig.setCheckpointInterval(10 * 1000)
env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime)
val ds: DataStream[Int] = env.addSource(new KeyByAndWindowAndProcessTestSource)
val ds2 = ds.keyBy(i => i).timeWindow(Time.seconds(4)).process(new MyProcessFunction())
ds2.print()
env.execute()
}
}
class MyProcessFunction extends ProcessWindowFunction[Int, String, Int, TimeWindow] {
override def process(
key: Int,
ctx: Context,
vals: Iterable[Int],
out: Collector[String]): Unit = {
println(new java.util.Date())
println(s"key=${key}, vals = ${vals.mkString(",")}, hashCode=${System.identityHashCode(ctx.window)}")
}
}
输出为:
Sat Sep 14 13:08:24 CST 2019
key=26, vals = 26,26,26, hashCode=838523304
Sat Sep 14 13:08:24 CST 2019
key=28, vals = 28,28,28, hashCode=472721641
Sat Sep 14 13:08:24 CST 2019
key=18, vals = 18,18,18,18,18,18, hashCode=1668151956
原始答复:
我希望我能正确回答你的问题
ProcessWindowFunction#进程
将为每个窗口和键调用一次(或多次,具体取决于窗口的触发器)。在内部,窗口和键组成了一个复合分区键
就Java对象实例而言,ProcessWindowFunction
的一个实例将处理许多键。具体来说,许多ProcessWindowFunction都具有一定的并行度
后续行动:
所以我没有弄对:)
对于由WindowOperator
处理的每条记录,将创建一个新的Window
对象,该对象具有正确的记录开始/结束时间
这意味着每次调用ProcessWindowFunction#process
都会传递一个新的Window
对象
必须了解,Flink中的窗口
是一个非常轻的对象,它只是用作整个键的附加部分(命名空间)。它不包含任何数据和/或逻辑
我可以问一下这个问题的背景吗 实际上,对于ProcessingTimeWindow,会为每个元素创建一个新的window对象 以下是TumblingProcessingTimeWindows#assignWindows的源代码:
public Collection<TimeWindow> assignWindows(Object element, long timestamp, WindowAssignerContext context) {
final long now = context.getCurrentProcessingTime();
long start = TimeWindow.getWindowStartWithOffset(now, offset, size);
return Collections.singletonList(new TimeWindow(start, start + size));
}
公共集合分配窗口(对象元素、长时间戳、WindowAssignerContext上下文){
final long now=context.getCurrentProcessingTime();
long start=TimeWindow.GetWindowsStartWithOffset(现在,偏移量,大小);
返回集合.singletonList(新的时间窗口(开始,开始+大小));
}
因此,System.identityHashCode
将始终为不同的键返回一个唯一的哈希代码,而您的测试代码不会证明任何东西
在引擎盖下,元素按
elementKey+assignedWindow
的键进行分组,因此我认为可以说“一个窗口实例将只包含相同的键,不同的键将使用不同的窗口实例”。谢谢@snntrable。我的问题是关于一个键将有一个窗口实例。例如,我有两个键,a、b,两个键落在同一个时间窗口中(例如,08:00-08:15),但窗口实例不同(它们是不同的窗口对象)。谢谢@snntrable。这里没有什么特别的背景,我只是好奇它的内部工作情况。如果我对它的内部工作有更好的了解,我将能够正确而自信地编写代码。。