Kafka主题分区到Spark流处理

17

我有一些使用案例需要更加明确,关于Kafka主题分区 -> Spark流资源利用。

我使用Spark独立模式,因此我只有"执行器总数"和"执行器内存"这两个设置。据我所知并根据文档,在Spark流中引入并行性的方法是使用分区的Kafka主题 -> RDD将具有与Kafka相同数量的分区,当我使用spark-kafka直接流集成时。

所以,如果主题中有1个分区,并且有1个执行器内核,那个内核将按顺序从Kafka读取。

如果我有:

  • 主题中有2个分区,但只有1个执行器内核?那个内核是否会先从一个分区读取,然后再从第二个分区读取,所以在分区主题方面没有好处?

  • 主题中有2个分区和2个内核?那么第一个执行器内核将从1个分区读取,第二个内核将从第二个分区读取?

  • 1个Kafka分区和2个执行器内核?

谢谢。

1个回答

24
基本规则是您可以扩展到Kafka分区的数量。如果您将 spark.executor.cores 设置为大于分区数,则某些线程将处于空闲状态。如果小于分区数,Spark 将使线程从一个分区读取,然后再读取另一个分区。所以:
  1. 2个分区,1个执行者:从一个分区读取,然后再读取另一个分区。(我不确定 Spark 如何决定在切换之前从每个分区读取多少)

  2. 2p、2c:并行执行

  3. 1p、2c:一条线程处于空闲状态

对于情况 #1,请注意,拥有比执行者更多的分区是可以的,因为它允许您稍后进行扩展而无需重新分区。诀窍是确保您的分区可以均匀地被执行者数整除。Spark 必须在传递数据到管道中的下一步之前处理所有分区。因此,如果您有 "余数" 分区,这可能会减慢处理速度。例如,5个分区和 4 条线程 => 处理需要 2 个分区的时间 - 同时处理 4 个分区,然后一条线程单独运行第 5 个分区。
还要注意,如果您在函数中明确设置数据分区的数量(如 reduceByKey()),则在整个管道中保持分区/ RDD 的数量相同,也可以看到更好的处理吞吐量。

1
除此之外,我建议你查看这个项目:https://github.com/dibbhatt/kafka-spark-consumer,它实现了更好的工作器-主题分区分配。 - Vale
@sean-owen 请您能否评论一下以确认此事?我特别希望能够确认第二点。我不确定第三点是否正确 - 它暗示着Spark不能给消费者提供超过1个线程。 - samthebest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接