当我在流上加入两个RDD之前互相加入时,为什么spark会隐式缓存RDD

时间:2019-09-17 14:35:33

标签: scala apache-spark spark-streaming rdd

我最近继承了Spark Streaming应用程序的大型重构提交。最初的开发人员告诉我,似乎存在一些隐式缓存,但是他在离开公司之前无法解决问题。

调试代码后,我发现,如果在将另一个RDD加入一个DStream之前将其加入另一个RDD,则火花将不会为每个批次重新获取RDD。

另一方面,如果仅在DStream上加入单个RDD,则spark将每批重新获取RDD数据。

注意:这些RD​​D是通过对Mysql的jdbc调用填充的。

最初,此问题在Spark 2.1.1中引起了人们的注意。此后,我将应用程序升级到了2.4.3,但这没什么区别。
另外,我尝试使用SparkSql加入RDD,这也没有任何区别。

这将很好地工作:对于每个火花流批处理,都将从数据库中获取entity1DF值。

val wordCounts: DStream[(String, Int)] = ...
val entity1DF = sparkSession.read.format("jdbc").jdbc("jdbc:mysql://127.0.0.1/barebones", "myword", driverProperties)
val entity1Rdd = entity1DF.rdd.map(Word.rowMapper)
val joinedStream = wordCounts.transform(rdd =>
      rdd.leftOuterJoin(entity1Rdd)
    )

这不起作用:对于每个火花流批处理,从第一个批处理中重新使用entity1DF和entity2DF值。 Spark UI通过将作业显示为灰色来很好地直观显示。

    val wordCounts: DStream[(String, Int)] = ...
    val entity1DF: DataFrame = sparkSession.read.format("jdbc").jdbc("jdbc:mysql://127.0.0.1/barebones", "myword", driverProperties)
    val entity1Rdd: RDD[(String, Int)] = entity1DF.rdd.map(Word.rowMapper)

    val entity2DF: DataFrame = sparkSession.read.format("jdbc").jdbc("jdbc:mysql://127.0.0.1/barebones", "myword", driverProperties)
    val entity2Rdd: RDD[(String, Int)] = entity2DF.rdd.map(Word.rowMapper)

    val joinedRdd: RDD[(String, (Option[Int], Option[Int]))] = entity1Rdd.fullOuterJoin(entity2Rdd)

    val joinedStream: DStream[(String, (Int, Option[(Option[Int], Option[Int])]))] = wordCounts.transform(rdd =>
      rdd.leftOuterJoin(joinedRdd)
    )

我希望每个流批次都重新评估entity1DF和entity2DF值。而不是将它们缓存以备后用。

0 个答案:

没有答案