如何将数据集写入Kafka主题?

时间:2018-04-06 13:36:33

标签: scala apache-spark apache-kafka apache-spark-sql

我使用的是Spark 2.1.0和Kafka 0.9.0。

我正在尝试将批量火花作业的输出推送到kafka。这项工作应该每小时运行一次,但不能作为流媒体运行。

在网上寻找答案时,我只能找到kafka与Spark流的集成,而不是与批处理作业的集成。

有谁知道这样的事情是否可行?

由于

更新:

正如user8371915所述,我尝试按照Writing the output of Batch Queries to Kafka中的内容进行操作。

我使用了火花壳:

spark-shell --packages org.apache.spark:spark-sql-kafka-0-10_2.11:2.1.0

以下是我尝试的简单代码:

val df = Seq(("Rey", "23"), ("John", "44")).toDF("key", "value")
val newdf = df.select(to_json(struct(df.columns.map(column):_*)).alias("value"))
newdf.write.format("kafka").option("kafka.bootstrap.servers", "localhost:9092").option("topic", "alerts").save()

但我收到错误:

java.lang.RuntimeException: org.apache.spark.sql.kafka010.KafkaSourceProvider does not allow create table as select.
at scala.sys.package$.error(package.scala:27)
at org.apache.spark.sql.execution.datasources.DataSource.write(DataSource.scala:497)
at org.apache.spark.sql.DataFrameWriter.save(DataFrameWriter.scala:215)
... 50 elided

知道这与此有什么关系吗?

由于

3 个答案:

答案 0 :(得分:7)

tl; dr 您使用过时的Spark版本。写入在2.2及更高版本中启用。

开箱即用,您可以使用Kafka SQL连接器(与结构化流媒体使用的连接器相同)。包括

    您的依赖项中的
  • spark-sql-kafka
  • 将数据转换为DataFrame,其中至少包含valueStringType类型的BinaryType列。
  • 将数据写入Kafka:

    df   
      .write
      .format("kafka")
      .option("kafka.bootstrap.servers", server)
      .save()
    

关注Structured Streaming docs了解详情(从Writing the output of Batch Queries to Kafka开始)。

答案 1 :(得分:1)

如果您有一个数据框,并且想将其写入 kafka 主题,则需要先将列转换为包含 json 格式数据的“值”列。在 Scala 中是

import org.apache.spark.sql.functions._

val kafkaServer: String = "localhost:9092"
val topicSampleName: String = "kafkatopic"

df.select(to_json(struct("*")).as("value"))
  .selectExpr("CAST(value AS STRING)")
  .write
  .format("kafka")
  .option("kafka.bootstrap.servers", kafkaServer)
  .option("topic", topicSampleName)
  .save()

答案 2 :(得分:0)

针对此错误 java.lang.RuntimeException:org.apache.spark.sql.kafka010.KafkaSourceProvider不允许将表创建为select。 在scala.sys.package $ .error(package.scala:27)

我认为您需要将消息解析为键值对。您的数据框应具有“值”列。

如果您有一个带有Student_id的数据框,得分。

total_seconds

然后应将数据框修改为

df.show()
>> student_id | scores
    1         |  99.00
    2         |  98.00

要进行转换,您可以使用类似的代码

value
{"student_id":1,"score":99.00}
{"student_id":2,"score":98.00}