Spark Streaming处理倾斜的Kafka分区



场景:
Kafka->Spark Streaming

每个Spark Streaming微批次中的逻辑(30秒(:
读取Json->解析Json->发送到Kafka

我的流媒体工作是阅读大约1000的Kafka主题,大约有100个Kafka分区,吞吐量大约为500万个事件/s

这个问题来自于Kafka分区之间的流量负载不均衡,有些分区的吞吐量大约是较小分区的50倍,这导致了RDD分区的偏斜(因为KafkaUtils创建了从Kafka到Spark分区的1:1映射(,并真正损害了整体性能,因为对于每个微块,大多数执行器都在等待负载最大的一个完成,通过查看Spark UI,我知道这一点,在每个微批次的某个时刻,只有少数执行者有"活动"任务,所有其他执行者都完成了任务并等待,还通过查看任务时间分布,MAX是2.5分钟,但MEDIAN只有20秒。

注:

  1. Spark Streaming非结构化流
  2. 我知道这个帖子Spark-重分区((与联合((,我没有问重分区(((和联合((之间的区别,负载是一致的,所以与自动缩放或动态分配也无关

我尝试了什么:

  1. Coalesce((有一点帮助,但不能消除偏度,有时甚至更糟,还会给执行器带来更高的OOM风险
  2. Repartition((确实消除了偏斜,但在这种规模下,完全混洗太贵了,惩罚不会对每个批次的执行时间产生回报,增加批次时间也不起作用,因为当批次时间增加时,每个微批次的负载也会增加,混洗的工作量也会增加

如何使工作负载在Spark执行器之间更均匀地分布,以便更有效地使用资源?性能会更好吗?

我也有同样的问题。您可以尝试spark 2.4.7 中的minPartitoin参数

很少有重要的事情需要强调。

  • 默认情况下,一个Kafka分区映射到一个spark分区,或者从spark映射到Kafka的一个
  • Kafka数据帧每个分区都有开始和结束边界
  • Kafka Dataframe maxMessagePerTrigger定义了从Kafka读取的消息数量
  • Spark 2.4.7还支持minParrations参数,该参数可以根据偏移范围将一个Kafka分区绑定到多个Kaf卡分区。默认情况下,它会尽最大努力平均分割Kafka分区(偏移范围(

因此,使用minPartitonsmaxOffsetsPerTrigger可以预先计算大量的分区。

.option("minPartitions", partitionsNumberLoadedFromKafkaAdminAPI * splitPartitionFactor)
.option("maxOffsetsPerTrigger", maxEventsPerPartition * partitionsNumber)

CCD_ 4和CCD_。

在我的情况下,有时我会出现数据峰值,并且我的消息大小可能会非常不同。因此,我实现了我自己的流媒体源,它可以按确切的记录大小拆分kafka分区,甚至可以在一个spark上合并几个kafka部分。

实际上,您已经提供了自己的答案。

没有从1000个主题中读取1个流式作业。将负载最大的作业放入单独的流作业中。重新配置,就这么简单。负载平衡,排队理论。

散漫者是Spark中的一个问题,尽管散漫者在Spark中具有稍微不同的特性。

最新更新