Spark mapWithState更新了状态输出

时间:2016-05-20 12:47:23

标签: scala apache-spark spark-streaming

升级到Spark 1.6.1后,我开始重构一个应用程序,用updateStateByKey替换mapWithState

为了利用新API的性能优势,我不想调用加载所有状态的stateSnapshots。我只想要更新的状态。

mapWithState API返回DStream [key, input, state, output],其中每个州在摄取输入后处于部分更新状态。如何从DStream中提取最新状态(即所有相应输入被摄取/映射后的状态)?

我可以在map上执行reduceByKey(删除输入和输出)和MapWithStateDStream,选择具有较新时间戳的状态(我在更新函数中设置) ,但我不能保证不会有两个具有相同时间戳的部分状态,即使使用自定义按键分区也是如此。

如何判断MapWithStateDStream的{​​{1}}输出中哪个部分状态是最新状态?

2 个答案:

答案 0 :(得分:3)

只会在当前微批次中更新的每个州调用

mapWithState。实现目标的一种方法是在状态更新的情况下返回Some[S]

StateSpec.function采用具有以下签名的方法:

mappingFunction: 
    (Time, KeyType, Option[ValueType], State[StateType]) => Option[MappedType]

我们可以做的是确保在值更新后Option[MappedType]始终为Some[MappedType],否则为None

例如:

def updateState(key: Int, value: Option[Int], state: State[Int]): Option[Int] = {
    value match {
      case Some(something) if something > 10 =>
        val updatedVal = something * something
        state.update(updatedVal)
        Some(updatedVal)
      case _ => None
    }
}

然后你可以这样做:

val spec = StateSpec.function(updateState _)
ssc.mapWithState(spec).filter(!_.isEmpty).foreachRDD(/* do stuff on updated state */)

通过这种方式,您可以过滤掉任何未更新的状态,并仅保留您正在寻找的更新快照。

答案 1 :(得分:0)

如果可以使用更新算法,那么可以使用的一种解决方案是在调用mapWithstate之前调用输入流上的reduceByKey。然后每个键只有一个更新,没有部分状态输出。