使用foreach进行Spark结构化流式处理

时间:2019-08-02 09:45:02

标签: scala apache-spark spark-structured-streaming

我正在使用Spark结构化流技术来从kafka读取数据。

val readStreamDF = spark
  .readStream
  .format("kafka")
  .option("kafka.bootstrap.servers", config.getString("kafka.source.brokerList"))
  .option("startingOffsets", config.getString("kafka.source.startingOffsets"))
  .option("subscribe", config.getString("kafka.source.topic"))
  .load()

基于从卡夫卡读取的消息中的uid,我必须对外部源进行api调用并获取数据并写回另一个卡夫卡主题。 为此,我正在使用自定义的foreach编写器并处理每条消息。

import spark.implicits._

val eventData = readStreamDF
  .select(from_json(col("value").cast("string"), event).alias("message"), col("timestamp"))
  .withColumn("uid", col("message.eventPayload.uid"))
  .drop("message")

val q = eventData
  .writeStream
  .format("console")
  .foreach(new CustomForEachWriter())
  .start()

CustomForEachWriter进行API调用,并从服务中针对给定的uid获取结果。结果是一个id数组。然后,这些ID通过kafka生产者再次写回另一个kafka主题。

有30个kafka分区,我使用以下配置启动了火花

num-executors = 30
executors-cores = 3
executor-memory = 10GB

但是火花作业仍然开始滞后,无法跟上传入的数据速率。

传入数据速率约为每秒1万条消息。在100毫秒内处理单个味精的平均时间。

我想了解在结构化流媒体的情况下spark是如何处理的。 在结构化流传输的情况下,只有一个专用执行程序负责从kafka的所有分区读取数据。 该执行者是否根据否分配任务。卡夫卡的分区。 批处理中的数据将按顺序处理。如何并行处理以最大化吞吐量。

1 个答案:

答案 0 :(得分:0)

我认为CustomForEachWriter编写者将处理数据集的单行/记录。如果您使用的是2.4版本的Spark,可以尝试foreachBatch。但这是在不断发展的。