Apache spark Spark Streaming-window()是否正在缓存数据流?

Apache spark Spark Streaming-window()是否正在缓存数据流?,apache-spark,spark-streaming,Apache Spark,Spark Streaming,有人能解释一下Spark Streaming是如何执行window()操作的吗?从Spark 1.6.1文档来看,窗口化的批处理似乎会自动缓存在内存中,但从web UI来看,在以前的批处理中已经执行的操作似乎会再次执行。为方便起见,我在下面附上我正在运行的应用程序的屏幕截图: 通过查看web UI,似乎flatMapValues()RDD已被缓存(绿点-这是我在数据流上调用window()之前执行的最后一个操作),但同时,似乎以前批处理中导致flatMapValues()的所有转换都再次执行。

有人能解释一下Spark Streaming是如何执行window()操作的吗?从Spark 1.6.1文档来看,窗口化的批处理似乎会自动缓存在内存中,但从web UI来看,在以前的批处理中已经执行的操作似乎会再次执行。为方便起见,我在下面附上我正在运行的应用程序的屏幕截图:

通过查看web UI,似乎flatMapValues()RDD已被缓存(绿点-这是我在数据流上调用window()之前执行的最后一个操作),但同时,似乎以前批处理中导致flatMapValues()的所有转换都再次执行。如果是这种情况,window()操作可能会导致巨大的性能损失,特别是当窗口持续时间为1或2小时时(正如我的应用程序所期望的那样)。您认为在那个时候检查数据流会有帮助吗?考虑到预期的幻灯片窗口大约5分钟。 希望有人能澄清这一点

编辑 我添加了一个代码片段。Stream1和Stream2是从HDFS读取的数据源

JavaPairDStream<String, String> stream1 = cdr_orig.mapToPair(parserFunc)
                                                 .flatMapValues(new Function<String, Iterable<String>>() {
                                                   @Override
                                                   public Iterable<String> call(String s) {
                                                     return Arrays.asList(s.split(","));
                                                   }
                                                 }).window(Durations.seconds(WINDOW_DURATION), Durations.seconds(SLIDE_DURATION));


JavaPairDStream<String, String> join = stream2.join(stream1);
JavaPairdStream1=cdr_orig.mapToPair(parserFunc)
.flatMapValues(新函数(){
@凌驾
公共Iterable调用(字符串s){
返回数组.asList(s.split(“,”);
}
}).窗口(持续时间.秒(窗口持续时间),持续时间.秒(幻灯片持续时间));
JavaPairDStream join=stream2.join(stream1);
这两个流由另一个系统周期性地产生。这些流是异步的,这意味着时间t时stream2中的记录在时间t′时出现在stream1中。首先,yes window()通过调用persist来缓存数据流。这里的缓存是指数据保存在内存中。默认存储级别为StorageLevel.MEMORY\u ONLY\u SER,即

将RDD存储为序列化Java对象(每个分区一个字节数组)。 这通常比反序列化对象更节省空间, 特别是在使用快速序列化程序时,但对 阅读

窗口转换所做的是返回一个新的数据流,其中每个RDD包含在该数据流的滑动时间窗口中看到的所有元素。在内部,它创建了一个WindowedDStream对象,该对象调用persist()来缓存数据流,根据Spark API文档,“它默认在父级保持,因为这些RDD显然将被重用。”

因此,您不能依赖Windows来缓存数据流。如果您想减少转换,应该在进行其他转换之前对该数据流调用persist()

在您的情况下,请尝试调用persist,如图所示:

cdr_orig.persist(StorageLevel.MEMORY_AND_DISK);

在执行mapToPair变换之前。您将看到一个更紧凑的DAG,顶部带有绿点。

代码将非常有用,检查点用于容错而不是性能增强。据我所知,通过接收器接收的输入数据存储在执行器的内存中,带有StorageLevel.memory\u和磁盘\u SER\u 2。因此,根据窗口间隔,数据首先将驻留在内存中,但之后也将存储在磁盘上,因为内存是有限的。因此,窗口持续时间约为1-2小时并不是最好的方法。您是否可以重写业务逻辑以更定期地执行中间执行,并使用updateStateByKey()作为示例?在这种情况下,检查点将非常有用。