繁体   English   中英

从火花工作到卡夫卡花费太多时间

[英]Sending to Kafka from a spark job taking too much time

我有一个火花流工作,它消耗来自kafka的数据,并在对每个数据进行一些处理后发送回kafka。 为此,我正在对数据进行一些地图操作,

val lines = KafkaUtils.createStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParams, topicNameMap, StorageLevel.MEMORY_AND_DISK)
var ad = ""
val abc = lines.map(_._2).map { x =>
  val jsonObj = new JSONObject(x)
  val data = someMethod(schema, jsonObj)
  data
}

然后我正在对它进行foreach操作,我没有收集所有数据给驱动程序,因为我想在执行程序本身内发送这些记录。

abc.foreachRDD(rdd => {
  rdd.foreach { toSend =>
    val producer = KafkaProducerUtils.getKafkaProducer(kafkaBrokers)
    println("toSend---->" + toSend)
    producer.send(new ProducerRecord[String, String](topicToSend, toSend))
  }

我尝试使用此代码获取1405个数据10秒钟,但完成这项工作大约需要2.5分钟。 我知道创建KafkaProducer是昂贵的,还有其他方法来减少处理时间。 为了我的测试目的,我使用2个执行器,每个2核和1GM。

经过大量搜索,我发现了这篇关于KafkaSink的文章。 这将为您提供有效生成火花流中kafka数据的想法。

处理此类消息的这种巨大延迟必须有几个原因:

  1. 问题可能在于您的消费阶段。 如果你使用“createStream”,至少,Spark的次要版本使用高级消费者实现,需要Zookeeper来存储属于特定组的消费者的偏移量。 因此,我会检查此通信,因为它可能需要在提交阶段花费太多时间。 如果由于任何原因而逐一提交承诺,您的消费率可能会受损。 首先,检查一下。

  2. 由于写入日志记录到文件系统,还有另一个原因。 虽然您的配置表明内存是磁盘,但您可以在Spark文档中看到:

效率:在第一种方法中实现零数据丢失需要将数据存储在Write Ahead Log中,这进一步复制了数据。 这实际上是低效的,因为数据有效地被复制两次 - 一次由Kafka复制,第二次由Write Ahead Log复制。 第二种方法消除了问题,因为没有接收器,因此不需要Write Ahead Logs。 只要您有足够的Kafka保留,就可以从Kafka恢复消息

为了更好的消费率,我会使用createDirectStream。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM