Apache spark 从Kafka主题读取文件路径,然后在结构化流媒体中读取文件并写入DeltaLake

Apache spark 从Kafka主题读取文件路径,然后在结构化流媒体中读取文件并写入DeltaLake,apache-spark,apache-kafka,spark-structured-streaming,delta-lake,Apache Spark,Apache Kafka,Spark Structured Streaming,Delta Lake,我有一个用例,其中存储在s3中的json记录的文件路径是kafka 卡夫卡的信息。我必须使用spark结构化流媒体处理数据 我认为设计如下: 在kafka Spark结构化流媒体中,读取包含数据路径的消息。 在驱动程序中收集消息记录。消息的大小很小 从数据位置创建数据帧。 卡夫卡夫。选择$value.castStringType .writeStream.foreachBatchbatchDf:DataFrame,batchId:Long=>{ //粗码 //向司机收取 val记录=batchD

我有一个用例,其中存储在s3中的json记录的文件路径是kafka 卡夫卡的信息。我必须使用spark结构化流媒体处理数据

我认为设计如下:

在kafka Spark结构化流媒体中,读取包含数据路径的消息。 在驱动程序中收集消息记录。消息的大小很小 从数据位置创建数据帧。 卡夫卡夫。选择$value.castStringType .writeStream.foreachBatchbatchDf:DataFrame,batchId:Long=>{ //粗码 //向司机收取 val记录=batchDf.collect //创建数据帧和进程 记录foreachrec:行=>{ printlnrecords:,rec.toString val path=rec.getAs[String]数据路径 val dfToProcess=spark.read.jsonpath .... } } 我想知道你的看法,如果这种方法是好的?特别是在调用collect后创建数据帧时出现问题。
如果有更好的方法,请告诉我。

你的想法很好用

实际上,必须向驱动程序收集数据帧。否则,无法通过在每个执行器上调用SparkSession来创建分布式数据集。如果没有collect,最终将出现NullPointerException

我稍微重写了您的代码sceleton,还实现了关于如何基于其他数据帧将数据帧写入增量表的部分。此外,我使用了Dataset[String]而不是Dataframe[Row],这使生活变得更轻松

使用Spark 3.0.1和delta core 0.7.0可以很好地工作。例如,我的测试文件如下所示

{"a":"foo1","b":"bar1"}
{"a":"foo2","b":"bar2"}
我将该文件的位置发送到一个名为test的Kafka主题,并应用以下代码解析该文件,并使用以下代码将其基于给定模式的列写入delta表:

val spark=SparkSession.builder .appNameKafkaConsumer .masterlocal[*] .getOrCreate val jsonSchema=新结构类型 .adda,StringType .addb,StringType val deltaPath=file:///tmp/spark/delta/test 导入spark.implicits_ val kafkaDf=spark.readStream 卡夫卡先生 .optionkafka.bootstrap.servers,本地主机:9092 .期权认购、测试 .选项开始偏移,最新 .选项FailOnDataloss,false 负载 .选择ExprcastValue作为字符串作为数据路径 .作为[字符串] kafkaDf.writeStream.foreachBatchbatchDf:Dataset[String],batchId:Long=>{ //向司机收取 val记录=batchDf.collect //根据文件位置和进程创建数据帧并写入Delta Lake records.foreachpath:String=>{ val dfToProcess=spark.read.schemajsonSchema.jsonpath dfToProcess.showfalse//用自定义处理逻辑替换此行 dfToProcess.write.formatdelta.savedeltaPath } }.开始 火花,溪流,等待终止 show调用的输出与预期一致:

+----+----+
|a   |b   |
+----+----+
|foo1|bar1|
|foo2|bar2|
+----+----+
数据已作为增量表写入通过deltaPath指定的位置


抱歉,stack不允许编辑评论。如果你能给出你在资源方面的观点。我的意思是,我们基本上在流媒体微批量中创建了许多独立的spark作业。而且它可能不会同时运行所有这些。这些工作如何共享资源?另一个原因是,它可能会在卡夫卡主题中产生滞后,因为下一个触发器将等待当前完成。
/tmp/spark/delta/test$ ll
total 20
drwxrwxr-x 3 x x 4096 Jan 20 13:37 ./
drwxrwxr-x 3 x x 4096 Jan 20 13:37 ../
drwxrwxr-x 2 x x 4096 Jan 20 13:37 _delta_log/
-rw-r--r-- 1 x x  595 Jan 20 13:37 part-00000-b6a540ec-7e63-4d68-a09a-405142479cc1-c000.snappy.parquet
-rw-r--r-- 1 x x   16 Jan 20 13:37 .part-00000-b6a540ec-7e63-4d68-a09a-405142479cc1-c000.snappy.parquet.crc