使用DStream API,可以使用MapWithStateDStream.stateSnapshots()访问有状态流的快照状态。在新的Structured Streaming API中,在我看来,只有传递给mapGroupsWithState的函数才能访问和更新状态。
我想基于它的输入事件创建流的内存分布式状态。然后通过将事件连接到第一个事件的(完整)状态来丰富来自另一个流的事件,即不是第一个流本身。
使用DStream API我只需将第二个流加入第一个流的stateSnapshot。新结构化流媒体API是否缺少此功能,还是在两个流之间有一个新的更好/更清晰的共享 GroupState
方式?
答案 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
函数为你提供了有状态聚合的最强大的抽象,我的理解是,如果它不能给你预期的结果,那么它就不太可能有更好的功能(我很高兴被告知我错了。)