Scala 火花流DF并行处理

Scala 火花流DF并行处理,scala,apache-spark,apache-spark-sql,spark-streaming,Scala,Apache Spark,Apache Spark Sql,Spark Streaming,在Spark流数据帧中,我面临着并行处理记录的问题。 流程如下: 卡夫卡主题->火花流数据帧-->实施业务规则->将结果发送到卡夫卡主题。 当前代码正在按顺序处理数据,Spark StreamingDataFrame作业运行正常 但是,对foreach中的每个记录进行顺序处理需要花费大量时间。 每分钟卡夫卡产生300条信息,Spark需要30分钟来处理。业务规则并不复杂 问题: 我试图在Foreach上调用并行函数,但一旦调用它,Spark就会多次处理同一条记录。 如果您能在此时帮助实现并行性,

在Spark流数据帧中,我面临着并行处理记录的问题。 流程如下: 卡夫卡主题->火花流数据帧-->实施业务规则->将结果发送到卡夫卡主题。 当前代码正在按顺序处理数据,Spark StreamingDataFrame作业运行正常 但是,对foreach中的每个记录进行顺序处理需要花费大量时间。 每分钟卡夫卡产生300条信息,Spark需要30分钟来处理。业务规则并不复杂

问题:

我试图在Foreach上调用并行函数,但一旦调用它,Spark就会多次处理同一条记录。 如果您能在此时帮助实现并行性,我将非常感谢您的帮助

环境详情:

1数据格式:Json

2数据详细信息

客户、部门、等级、详细信息

客户1、22、C1、maf

Cust2,23,C2,喷漆

客户3、24、C3、运输

Cust4、22、C4、一般

3停车版本:CDH 6.3上的2.4.0

4Scala:2.11.11

5Straming:Spark流式数据格式

6分区:3

7经纪人:3

下面是代码片段

输入数据:

Cust4、22、C4、一般

客户1、22、C1、maf

Cust2,23,C2,喷漆

客户3、24、C3、运输

预期产出:

专题A:

Cust4、22、C4、一般

专题B:

客户1、22、C1、maf

Cust2,23,C2,喷漆

客户3、24、C3、运输

实际产量:

专题A:

Cust4、22、C4、一般

Cust4、22、C4、一般

Cust4、22、C4、一般

专题B:

客户1、22、C1、maf

Cust2,23,C2,喷漆

客户3、24、C3、运输

客户1、22、C1、maf

Cust2,23,C2,喷漆

客户3、24、C3、运输


谢谢

请尝试在foreachPartitions下实现业务逻辑,以便在执行者之间实现数据分布,最终促进并行性。另一方面,收集操作,在驱动程序级别执行,因此在实现并行性方面胡不起作用。

是需要的PAR?您的业务规则只取决于第一个字段发送到不同的主题的不同吗?Q:是否需要PAR?蓝色幻影9小时制是的。现在Spark Streaming正在按顺序处理数据,我想并行处理。批次具有多个记录。比如说在微批量中,有200条记录。如果我们使用Foreach而不使用.parr,那么它将按顺序进行处理。为了获得更好的性能和并行性,.parr调用两个不同的线程。请让我知道是否有其他选项可以实现平行。Q:您的业务规则仅取决于发送到不同主题的第一个字段答:是的,根据条件,信息将发送到两个不同的主题。为了简化,假设所有偶数都指向卡夫卡主题A,所有奇数都指向卡夫卡主题B。谢谢。我们试过了,但还是一样的表现。Foreach.parr正在导致重复。我注意到,使用in-forach,我们的业务逻辑非常繁重,需要5-6秒,一旦完成,我们将使用Kafka offset。现在,批处理可能在foreach中,多个执行器使用相同的记录,运行业务逻辑5-6秒,然后提交。这可能是根本原因吗?Plz建议解决方案。它有多个方面,可以讨论。对于任何给定的批处理,每一次数据流的大小是多少,以及您针对它提供的spark配置是什么。此外,您试图从中使用的主题包括多少个分区,并且最终输出也为您提供相同数量的零件文件?
val df = spark.readStream.format("kafka").option("kafka.bootstrap.servers",get_details("kafka_bootstrap_server")).option("subscribe",get_details("topic_ora")).option("startingOffsets", get_details("startingOffsets")).load()

val input_data = stream_action_function_data.select($"customer",$"deptid",$"grade",$"details")

val check_User=input_data.writeStream.foreachBatch ((batchDF: DataFrame, batchId: Long) => {
batchDF.persist()

val funcn = batchDF.collect.par.foreach( col =>  {  
import org.apache.spark.sql.Row
import spark.implicits._  
val data=col
println(data)
val descri= data.getString(4)

import org.apache.spark.sql.types.{StructType, StructField, StringType,TimestampType,IntegerType};
println("Description  "+ descri)  

val sc=spark.sparkContext

val rdd = sc.parallelize(Seq(data))

val schema = StructType(Array(StructField("customer", StringType, true),StructField("deptid", StringType, true),StructField("grade", StringType, true),StructField("details", StringType, true)

val df_record=spark.createDataFrame(rdd, schema) 

if ( df_record.getString(4)== "general")
{ 
Send KafkaTopicA()//Send Schema contents to Kafka Topic A in json format                                }  
else 
{ 
Send KafkaTopicB()//Send Schema contents to Kafka Topic B in json format    
}               
})

batchDF.unpersist() 

}).option("checkpointLocation",s"$functions_checkpointLocation").outputMode("append").start()*