我最近一直使用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秒时的图表。
答案 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
来避免此问题。
有时间我可能会描述更多细节。