Flink的广播状态行为

时间:2018-06-25 09:38:51

标签: scala apache-flink broadcast flink-streaming

我试图通过一个简单的案例来了解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()
  }
}

编辑:我使用Flink 1.5,广播状态文档为here

1 个答案:

答案 0 :(得分:1)

Flink不同步流的摄取,即流尽可能快地产生数据。对于常规输入和广播输入都是如此。 BroadcastProcess在提取常规输入之前不会等待第一个广播输入到达。

当您在常规输入中添加更多数字时,序列化,反序列化和提供输入内容将花费更多时间,以便在第一个常规数字到达时已经存在广播输入。