处理不同的状态

时间:2016-04-15 08:29:20

标签: scala apache-spark state spark-streaming

我想知道是否有可能在应用程序中保持完全不同的状态?例如,让第一个州的update function从第二个州调用一个吗?

我不记得经历过任何这样的例子,也没有找到任何反指示......基于https://docs.cloud.databricks.com/docs/spark/1.6/examples/Streaming%20mapWithState.html的例子,我知道我没有理由不能具有不同trackStateFunc s的不同State,并且仍然会通过Key更新这些内容,如下所示:

def firstTrackStateFunc(batchTime: Time, 
                        key: String, 
                        value: Option[Int], 
                        state: State[Long]): Option[(String, Long)] = {
    val sum = value.getOrElse(0).toLong + state.getOption.getOrElse(0L)
    val output = (key, sum)
    state.update(sum)
    Some(output)
}

def secondTrackStateFunc(batchTime: Time, 
                         key: String, 
                         value: Option[Int], 
                         state: State[Int]): Option[(String, Long)] = {
    // disregard problems this example would cause
    val dif = value.getOrElse(0) - state.getOption.getOrElse(0L) 
    val output = (key, dif)
    state.update(dif)
    Some(output)
}

我认为这是可能的,但仍然不确定。我希望有人来验证或使这个假设失效......

2 个答案:

答案 0 :(得分:2)

  

我想知道是否有可能保持根本不同   整个申请中的州?

mapWithStateDStream[(Key, Value)]的每次通话都可以容纳一个State[T]个对象。对于T的每次调用,此mapWithState必须相同。为了使用不同的状态,您可以链接mapWithState来电,其中Option[U]是其他输入,或者您可以拆分DStream并应用不同的mapWithState来电每个人。但是,您不能在另一个内部调用另一个State[T]对象,因为它们彼此隔离,并且不能改变另一个的状态。

答案 1 :(得分:1)

@Yuval给链mapWithState函数提供了很好的答案。但是,我有另一种方法。您可以将sum和diff放在同一个State [(Int,Int)]中,而不是有两个mapWithState调用。

在这种情况下,您只需要一个mapWithState函数,您可以在其中更新这两个函数。像这样:

def trackStateFunc(batchTime: Time, 
                   key: String, 
                   value: Option[Int], 
                   state: State[(Long, Int)]): Option[(String, (Long, Int))] =
{
    val sum = value.getOrElse(0).toLong + state.getOption.getOrElse(0L)
    val dif = value.getOrElse(0) - state.getOption.getOrElse(0L)
    val output = (key, (sum, diff))
    state.update((sum, diff))
    Some(output)
}