使用MongoSpark将流式DataFrame保存到MongoDB

时间:2018-03-24 17:17:25

标签: mongodb scala apache-spark apache-kafka spark-dataframe

一些背景故事:对于大学的家庭作业项目,我们的任务是以可扩展的方式实施选择算法。我们选择使用Scala,Spark,MongoDB和Kafka,因为这些是在课程中推荐的。为了从MongoDB中读取数据,我们选择使用MongoSpark,因为它允许对数据进行简单且可扩展的操作。我们还使用Kafka来模拟来自外部源的流式传输。我们需要对Kafka生成的每个条目执行多个操作。问题来自将此数据的结果保存回MongoDB。

我们有以下代码:

val streamDF = sparkSession
    .readStream
    .format("kafka")
    .option("kafka.bootstrap.servers", "localhost:9092")
    .option("subscribe", "aTopic")
    .load
    .selectExpr("CAST(value AS STRING)")

从现在开始,我们不知所措。我们不能使用.map因为MongoSpark只对DataFrame,Datasets和RDD进行操作而且不可序列化,并且使用MongoSpark.save不能像指定的那样使用流式DataFrame。我们也不能使用默认的MongoDB Scala驱动程序,因为这会在添加依赖项时与MongoSpark冲突。请注意,算法的其余部分严重依赖于连接和groupbys。

我们如何从这里获取数据到我们的MongoDB?

编辑: 为了便于重现,可以尝试以下方法:

val streamDF = sparkSession
    .readStream
    .format("rate")
    .load

.write添加到MongoSpark.save所需的{{1}}将导致异常,因为无法在流数据帧上调用write。

1 个答案:

答案 0 :(得分:0)

  

在MongoSpark.save中添加.write会导致异常,因为无法在流数据帧上调用write。

MongoDB Connector for Sparksave()方法接受RDD(截至当前版本2.2)。在MongoSpark中使用DStream时,您需要获取批量'流中的RDD写入。

wordCounts.foreachRDD({ rdd =>
  import spark.implicits._
  val wordCounts = rdd.map({ case (word: String, count: Int)
          => WordCount(word, count) }).toDF()
  wordCounts.write.mode("append").mongo()
})

另见: