火花流的奇怪延迟

时间:2017-01-18 13:25:21

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

我最近一直使用spark streaming来处理kafka中的数据。

在应用程序启动并完成几个批次后,会持续延迟。

大多数情况下,数据处理在1-5秒内完成。

然而,经过几批后,连续花了41~45秒,大部分延迟发生在从stage0获取数据的区域。

我偶然发现Kafka request.timemout.ms默认设置为40秒,并将此设置更改为10秒。

然后我重新启动了应用程序并观察到批次在11到15秒内完成。

实际处理时间为1-5秒。我无法理解这种延迟。

有什么问题?

我的环境如下。

Spark streaming 2.1.0(createDirectStream)

卡夫卡:0.10.1

批处理间隔:20秒

Request.timeout.ms:10s

/////

以下捕获是request.timeout.ms设置为8秒时的图表。

enter image description here

2 个答案:

答案 0 :(得分:0)

我找到了问题和解决方法:

基本上,当您从执行程序中读取kafka的每个分区时,为了提高性能或读取和处理而产生的Spark Streaming会将正在读取的分区的内容缓存在内存中。

如果主题的大小太大,则高速缓存可能会溢出,并且当kafka connect确实获取到kafka时,高速缓存已满并获得超时。

解决方案::如果您使用的是Spark 2.2.0或更高版本(来自spark文档),这是解决方案,是spark和cloudera已知的错误:

使用者的缓存的默认最大大小为64。如果您希望处理的卡夫卡分区超过(64 *执行者数量),则可以通过spark.streaming.kafka.consumer.cache.maxCapacity更改此设置。

如果您想为Kafka使用者禁用缓存,可以将spark.streaming.kafka.consumer.cache.enabled设置为false。要解决SPARK-19185中描述的问题,可能需要禁用缓存。解决SPARK-19185后,可以在更高版本的Spark中删除此属性。

缓存由topicpartition和group.id设置密钥,因此对于createDirectStream的每次调用都使用单独的group.id。

spark.streaming.kafka.consumer.cache.enabled设置为错误。在您的提交火花参数中,您的微型潜艇性能就像超音速飞机一样。

答案 1 :(得分:0)

我们也面临同样的问题,经过大量分析,我们发现这是由于KAFKA-4303中所述的kafka错误所致。

对于Spark应用程序,我们可以通过在使用者配置中设置reconnect.backoff.ms = 0来避免此问题。

有时间我可能会描述更多细节。