Scala 火花流DF并行处理
在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、运输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就会多次处理同一条记录。 如果您能在此时帮助实现并行性,
谢谢 请尝试在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()*