如何访问mapGroupsWithState中的stateSnapshot或在流之间共享GroupState?

时间:2017-11-24 20:50:25

标签: apache-spark spark-structured-streaming

使用DStream API,可以使用MapWithStateDStream.stateSnapshots()访问有状态流的快照状态。在新的Structured Streaming API中,在我看来,只有传递给mapGroupsWithState的函数才能访问和更新状态。

我想基于它的输入事件创建流的内存分布式状态。然后通过将事件连接到第一个事件的(完整)状态来丰富来自另一个流的事件,即不是第一个流本身。

使用DStream API我只需将第二个流加入第一个流的stateSnapshot。新结构化流媒体API是否缺少此功能,还是在两个流之间有一个新的更好/更清晰的共享 GroupState方式?

2 个答案:

答案 0 :(得分:1)

  

新的Structured Streaming API上是否缺少此功能   有一种新的更好/更清洁的方法吗?

结构化流媒体(SS)中没有提供开箱即用的stateSnapshot。我假设这可以在SS的更高版本中完成。我不确定它是否符合他们的设计目标,因为对于任意流,状态完全被最终用户屏蔽掉了,尽管这对于通过(flat)mapGroupsWithState使用自定义状态的人来说非常有用。

为了滚动您自己的“快照”,您始终可以输出GroupState[S]中所生成的每个批次的中间状态,即:

def updateSessionEvents(
  id: Int,
  userEvents: Iterator[UserEvent],
  state: GroupState[UserSession]): Option[UserSession] = {
    // Do stuff
    val someState = ??? // update state
    someState
}

然后,你一直暴露在整个状态。这意味着您现在需要维护一些标志,指示状态是否实际完成,以便不向下游发送不完整的状态。

答案 1 :(得分:0)

mapGroupsWithState就像功能map一样,您必须提供输出的每个输入。这是map广义上的契约,mapGroupsWithState跟随它。

如果我理解正确,您真正需要的是KeyValueGroupedDataset.flatMapGroupsWithState,因为您似乎正在构建一个所谓的任意有状态流聚合

  

flatMapGroupsWithState [S,U](outputMode:OutputMode,timeoutConf:GroupStateTimeout)(func:(K,Iterator [V],GroupState [S])⇒迭代器[U])(隐式arg0:编码器[S ],arg1:编码器[U]):数据集[U] 将给定函数应用于每组数据,同时保持用户定义的每组状态。

这个看似复杂的flatMapGroupsWithState函数为你提供了有状态聚合的最强大的抽象,我的理解是,如果它不能给你预期的结果,那么它就不太可能有更好的功能(我很高兴被告知我错了。)