升级到Spark 1.6.1后,我开始重构一个应用程序,用updateStateByKey
替换mapWithState
。
为了利用新API的性能优势,我不想调用加载所有状态的stateSnapshots
。我只想要更新的状态。
mapWithState
API返回DStream
[key, input, state, output]
,其中每个州在摄取输入后处于部分更新状态。如何从DStream
中提取最新状态(即所有相应输入被摄取/映射后的状态)?
我可以在map
上执行reduceByKey
(删除输入和输出)和MapWithStateDStream
,选择具有较新时间戳的状态(我在更新函数中设置) ,但我不能保证不会有两个具有相同时间戳的部分状态,即使使用自定义按键分区也是如此。
如何判断MapWithStateDStream
的{{1}}输出中哪个部分状态是最新状态?
答案 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。然后每个键只有一个更新,没有部分状态输出。