来自一个Kafka主题源的并发Spark流作业

时间:2019-10-03 10:07:51

标签: java apache-spark apache-kafka stream

我们从kafka主题(具有8个分区)中创建了一个简单的火花流,该主题如下创建,并由2个执行者(每个4个核心)提交。

dataSet
   .writeStream()
   .trigger(Trigger.ProcessingTime(0))
   .format("kafka");
   .start();

现在考虑这种情况:

  1. 一个请求来到该主题的分区#0。
  2. 火花作业将从8个任务开始,并且其中只有一个正在运行(其他任务成功)。
  3. 假设处理此请求需要1分钟。
  4. 在此1分钟内,此主题(在所有8个分区中)有100个请求。
  5. Spark等待当前作业完成,然后创建另一个作业来处理新请求。

我们的期望是,Spark在处理第一个请求时会处理另一个作业中的其他请求,但这没有发生。现在,假设第一个作业需要1个小时而不是1分钟,而其他请求在7个内核处于空闲状态时正在等待处理!那是我们的问题。

我已经尝试从4个不同的线程多次(例如4次)发送此作业,但是行为仍然相同。 我也尝试将此配置 spark.streaming.concurrentJobs 设置为大于1,但没有更改!

所以我的问题是一个kafka流数据集是否可以同时具有多个作业?如果可以,怎么办?

我们正在使用Spark 2,Kafka 1和Java 8。

1 个答案:

答案 0 :(得分:0)

因此,经过几天的研究和测试,我终于发现,并发作业设置或在不同线程中发送作业都不是解决方案。

唯一可行的解​​决方案是为每个(或一组)主题分区 创建不同的流

kafka中的并行性因素是分区。并且Spark(和kafka)具有仅从特定分区读取的功能。因此,如果我们的分区有4个主题,那么我将Spark作业分为4个不同的作业,每个作业都在侦听(分配)到一个分区,但是所有这些作业都陷入了相同的目标。

因此,现在,如果一个作业忙于耗时的过程,则其他作业(此处为3个)仍可以处理其分配的分区中的数据,而无需等待其他分区上的完成过程。

配置如下:

assign: {"topic-name":[0,1,2]}

代替

subscribe: "topic-name"

请注意配置结构,它应为有效JSON ,并且主题列表应以逗号分隔的字符串提及(不支持范围或排除)