Spark Streaming - 窗口()缓存DStreams吗?

时间:2016-05-28 01:41:11

标签: apache-spark spark-streaming

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

Spark DAG

通过查看Web UI,似乎缓存了flatMapValues()RDD(绿点 - 这是我在DStream上调用window()之前执行的最后一个操作),但同时,它似乎也是在以前的批次中导致flatMapValues()的所有转换都会再次执行。如果是这种情况,window()操作可能会导致巨大的性能损失,特别是如果窗口持续时间为1或2小时(正如我对我的应用程序所期望的那样)。你认为那时检查点DStream会有帮助吗?考虑到预期的幻灯片窗口大约是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);

这两个流由另一个系统定期生成。这些流是异步的,这意味着在时间t的stream2中的记录在时间t'&lt; = t时出现在stream1中。我正在使用window()来缓存stream1记录1-2个小时,但如果在每个新批次上执行过去批次的stream1上的操作,这可能效率很低。

1 个答案:

答案 0 :(得分:1)

首先是yes window()通过调用persist来缓存dStream。通过缓存在这里我的意思是数据保存在内存中。默认存储级别为StorageLevel.MEMORY_ONLY_SER,即

  

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

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

因此,您不能依赖Window来缓存DStreams。如果你想减少转换,你应该在DStreams之前和其他转换之前调用persist()。

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

cdr_orig.persist(StorageLevel.MEMORY_AND_DISK);

在执行mapToPair转换之前。你会看到一个更紧凑的DAG将在顶部形成绿点。