基于kafka分区的结构化流读取

时间:2018-10-09 20:26:22

标签: apache-kafka spark-structured-streaming apache-spark-2.0

我正在使用Spark结构化流技术来读取来自Kafka主题的传入消息,并根据传入消息将其写入多个实木复合地板表中 因此,我创建了一个readStream,因为Kafka源很常见,并且为每个镶木表在循环中创建了单独的写流。这可以正常工作,但readstream会创建一个瓶颈,因为它为每个writeStream创建一个readStream,并且无法缓存已读取的数据帧。

val kafkaDf=spark.readStream
      .format("kafka")
      .option("kafka.bootstrap.servers", conf.servers)
      .option("subscribe", conf.topics)
      //  .option("earliestOffset","true")
      .option("failOnDataLoss",false)
      .load()

foreach table   {  
//filter the data from source based on table name
//write to parquet
 parquetDf.writeStream.format("parquet")
        .option("path", outputFolder + File.separator+ tableName)
        .option("checkpointLocation", "checkpoint_"+tableName)
        .outputMode("append")
        .trigger(Trigger.Once())
       .start()
}

现在,每个写入流都在创建一个新的使用者组,并从Kafka读取全部数据,然后进行过滤并写入Parquet。这造成了巨大的开销。为了避免这种开销,我可以将Kafka主题分区为具有与表数一样多的分区,然后readstream应该仅从给定的分区读取。但是我看不到在Kafka读取流中指定分区详细信息的方法。

1 个答案:

答案 0 :(得分:1)

如果数据量不是很高,则编写您自己的接收器,收集每个微批处理的数据,那么您应该能够缓存该数据帧并写入不同的位置,尽管需要进行一些调整,但仍然可以使用