在Spark Structured Streaming(版本2.2.0)中,如果使用mapGroupsWithState
查询并使用更新模式作为输出模式,似乎Spark正在存储内存状态使用java.util.ConcurrentHashMap
数据结构的数据。有人可以向我详细解释当状态数据增长并且内存不足时会发生什么?另外,是否可以使用spark配置参数来更改将状态数据存储在存储器中的限制?
答案 0 :(得分:2)
有人可以向我详细解释当州政府会发生什么 数据增长,内存不足
执行程序将因OOM异常而崩溃。由于使用mapGroupWithState
,您是负责添加和删除状态的人,如果您使用无法为其分配内存的数据压倒JVM,则进程将崩溃。
是否可以更改存储状态数据的限制 内存,使用spark配置参数?
无法限制存储在内存中的字节数。同样,如果这是mapGroupsWithState
,则必须以不会导致JVM到OOM的方式管理状态,例如设置超时和删除状态。如果我们讨论Spark管理状态的有状态聚合,例如agg
组合器,那么你可以使用watermark来限制状态,这将在时间范围内从内存中驱逐旧数据通行证。
答案 1 :(得分:2)
现有的状态存储实现使用内存中的HashMap(用于存储)+ HDFS(用于容错) HashMaps是版本化的(每个微批处理一个)。在工作程序的执行程序内存中,每个聚合分区的每个版本都有一个单独的键值映射。 (要维护的版本数是可配置的) 要回答您的问题:
有人可以向我详细解释一下,当状态数据增长并且没有足够的内存时会发生什么。
状态存储HashMaps与随机任务共享执行程序内存。因此,随着状态的增长或任务改组需要更多的内存,频繁的GC和OOM会发生,导致执行器失败。
是否可以使用spark config参数更改将状态数据存储在内存中的限制?
当前不可能。您只能指定将由状态存储和执行程序任务共享的执行程序内存,无法在它们之间划分内存。实际上,这会使当前的实现在突发数据突发情况下不可靠,即使在这种情况下,甚至水印也无济于事。
如果想了解状态存储在结构化流中如何内部工作,本文可能会有用:https://www.linkedin.com/pulse/state-management-spark-structured-streaming-chandan-prakash/
p.s。我是作者