我试着用一个简单的案子来玩弄Flink的胸罩。
我只想把一个整数流乘以另一个整数,就成了一个广播流。
我的广播行为是“奇怪的”,如果我在输入流中放入太少的元素(比如10个),什么都不会发生,我的广播也会失败 MapState
是空的,但是如果我放入更多的元素(比如100),我就有了我想要的行为(这里的整数流乘以2)。
如果我给出的元素太少,为什么广播流不考虑呢?
如何控制广播流何时工作?
可选:我只想保留广播流的最后一个元素,即 .clear()
好办法?
谢谢您!
这是我的 BroadcastProcessFunction
:
import org.apache.flink.streaming.api.functions.co.BroadcastProcessFunction
import org.apache.flink.util.Collector
import scala.collection.JavaConversions._
class BroadcastProcess extends BroadcastProcessFunction[Int, Int, Int] {
override def processElement(value: Int, ctx: BroadcastProcessFunction[Int, Int, Int]#ReadOnlyContext, out: Collector[Int]) = {
val currentBroadcastState = ctx.getBroadcastState(State.mapState).immutableEntries()
if (currentBroadcastState.isEmpty) {
out.collect(value)
} else {
out.collect(currentBroadcastState.last.getValue * value)
}
}
override def processBroadcastElement(value: Int, ctx: BroadcastProcessFunction[Int, Int, Int]#Context, out: Collector[Int]) = {
// Keep only last state
ctx.getBroadcastState(State.mapState).clear()
// Add state
ctx.getBroadcastState(State.mapState).put("key", value)
}
}
还有我的 MapState
:
import org.apache.flink.api.common.state.MapStateDescriptor
import org.apache.flink.api.scala._
object State {
val mapState: MapStateDescriptor[String, Int] =
new MapStateDescriptor(
"State",
createTypeInformation[String],
createTypeInformation[Int]
)
}
还有我的 Main
:
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.api.scala._
object Broadcast {
def main(args: Array[String]): Unit = {
val numberElements = 100
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
val broadcastStream = env.fromElements(2).broadcast(State.mapState)
val input = (1 to numberElements).toList
val inputStream = env.fromCollection(input)
val outputStream = inputStream
.connect(broadcastStream)
.process(new BroadcastProcess())
outputStream.print()
env.execute()
}
}
编辑:我使用Flink1.5,广播状态文档在这里。
1条答案
按热度按时间wa7juj8i1#
flink不同步流的摄取,即流尽可能快地产生数据。这对于常规输入和广播输入是正确的。这个
BroadcastProcess
在接收常规输入之前,不会等待第一个广播输入到达。当您在常规输入中输入更多的数字时,只需要更多的时间来序列化、反序列化和服务输入,以便在第一个常规数字到达时广播输入已经存在。