为什么Spark中有这么多的MapWithStateRDDs

时间:2018-03-20 16:22:37

标签: apache-spark spark-streaming

我有一个Spark流应用程序,它使用了很多状态转换。回想起来,Spark可能不是最佳选择,但我仍然试图让它发挥作用。

我的问题是为什么我的MapWithStateRDD占用了这么多内存?作为一个例子,我有一个转换,其中状态大约是1.5 Gb的内存,我看到每个批次都恢复相同的RDD。因此,在第3批之后,它在UI上显示有3个具有完全相同大小的MapWithStateRDD,而状态在这些批次中没有变化。这些实际占用了3倍的空间吗?这似乎是一个巨大的浪费,它不应该只存储增量直到一个检查点,然后将它们压缩到一个RDD或类似的东西?我认为它是如何工作的,并且进行更多有状态转换会占用大量内存。

1 个答案:

答案 0 :(得分:0)

正如注释链接中所指出的那样,这是因为mapWithState每10个批次后都会检查一次数据,因此它将RDD保留到该点为止。

要消除这种空间浪费,您可以选择在每个批次中检查状态。就我而言,这并不是很昂贵。

JavaInputDStream<ConsumerRecord<String, Object>> rtStream = ...
JavaMapWithStateDStream<String, Object, Object, Tuple2<String, Object>> mapWithStateSTream = rtStream .mapToPair(..).mapWithState(...);

mapWithStateSTream.checkpoint(Durations.seconds(10)); //keep this same as your batch interval, or feel free to change acc to your requirement

mapWithStateSTream.forEachRdd(...your logic here..);

然后你去了,魔术!您不会再在“存储”标签中看到那些令人讨厌的MapWithStateRDD。