在Spark Streaming中使用mapWithState指定超时

时间:2016-10-04 04:49:06

标签: scala apache-spark spark-streaming

我正在关注sample of mapWithState function on Databricks website

trackstatefunction的代码如下:

def trackStateFunc(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)
}

在状态为超时(state.isTimingout()==true)的情况下我有一个问题,然后该函数再次更新可能导致异常的状态。这样的样本是真的吗?

1 个答案:

答案 0 :(得分:4)

  

在状态为超时(state.isTimingout() == true)的情况下,该函数再次更新可能导致异常的状态。

是的,这是正确的。如果在mapWithState上设置显式超时并在状态处于最后一次超时迭代时调用state.update,这将导致异常被抛出,因为一旦发生超时,您就无法更新状态。明确说明in the documentation

  

如果状态已被删除,则状态无法更新(即,   已经调用了remove())或者它将被删除   超时(即isTimingOut()为真)。

在您的示例中,需要进行额外检查:

def trackStateFunc(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)
  if (!state.isTimingOut) state.update(sum)
  Some(output)
}

或者,因为value一旦发生超时就应该只有None,你也可以使用模式匹配:

def trackStateFunc(batchTime: Time, 
                   key: String, 
                   value: Option[Int], 
                   state: State[Long]): Option[(String, Long)] = {
  value match {
    case Some(v) => 
      val sum = v.toLong + state.getOption.getOrElse(0L)
      state.update(sum)
      Some((key, sum))
    case _ if state.isTimingOut() => (key, state.getOption.getOrElse(0L))
  }
}

有关有状态流媒体的评论,请参阅this blog post(免责声明:我是作者)。