使用相同的spark作业的两个实例来处理Kafka主题是否可行?

时间:2018-05-23 03:48:09

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

我有一个数据丰富工作,从数据源(一个kafka主题)丰富我的数据,然后在处理后发布到另一个接收器(kafka主题)。 作业本身是IO绑定的,当我添加更多CPU /内存时,处理速度不会线性增加。 我应该使用两个或三个实例水平扩展作业,并让它们使用相同的groupId相同的Kafka主题吗?

困难在于目前我的代码在kafka经纪人中维持处理偏移量。因此,我将在下面的代码中添加一个额外的参数来定义要加载到RDD中的哪些分区,并让高级别决定他们需要读取哪个偏移量。这看起来不那么好。

  private def loadRdd[T:ClassTag](maxMessages: Long = 0, messageFormatter: ((String, String)) => T)
                             (implicit inputConfig: Config): (RDD[T], Unit => Unit, Boolean) = {
val brokersConnectionString = Try(inputConfig.getString("brokersConnectionString")).getOrElse(throw new RuntimeException("Fail to retrieve the broker connection string."))
val topic                   = inputConfig.getString("topic")
val groupId                 = inputConfig.getString("groupId")
val retriesAttempts         = Try(inputConfig.getInt("retries.attempts")).getOrElse(SparkKafkaProviderUtilsFunctions.DEFAULT_RETRY_ATTEMPTS)
val retriesDelay            = Try(inputConfig.getInt("retries.delay")).getOrElse(SparkKafkaProviderUtilsFunctions.DEFAULT_RETRY_DELAY) * 1000

val topicOffsetRanges = KafkaClusterUtils.getTopicOffsetRanges(inputConfig, topic, SparkKafkaProviderUtilsFunctions.getDebugLogger(inputConfig)).toList
                                         .map { case (partitionId, (minOffset, maxOffset)) => OffsetRange(topic, partitionId, minOffset, maxOffset) }.toArray

val (offsetRanges, readAllAvailableMessages) = restrictOffsetRanges(topicOffsetRanges, maxMessages)

val rdd: RDD[ConsumerRecord[String, String]] = RetryUtils.retryOrDie(retriesAttempts, retryDelay = retriesDelay, loopFn = {SparkLogger.warn("Failed to create Spark RDD, retrying...")},
                                failureFn = { SparkLogger.warn("Failed to create Spark RDD, giving up...")})(
  KafkaUtils.createRDD(sc, KafkaClusterUtils.getKafkaConsumerParameters(brokersConnectionString, groupId), offsetRanges, LocationStrategies.PreferConsistent))

(rdd.map(pair => messageFormatter(pair.key(), pair.value())), Unit => commitOffsets(offsetRanges, inputConfig), readAllAvailableMessages)

}

我应该继续这个方向,让高级别决定哪些分区属于哪个作业实例?或者我应该通过添加更多CPU和内存来扩展?

谢谢!

0 个答案:

没有答案