当使用spark-streaming时,如何通过自己保存多个分区的Kafka偏移量

时间:2017-12-28 08:49:54

标签: apache-kafka spark-streaming

我使用spark-streaming来读取kafka数据,并处理每一行

我在下面用它来创建一个流媒体:

lines = KafkaUtils.createDirectStream(
            jssc,
            LocationStrategies.PreferConsistent(),
            ConsumerStrategies.<String, String>Subscribe(topics,kafkaParams)
    );

然后我使用此代码处理来自kafka的数据

    lines.foreachRDD((JavaRDD<ConsumerRecord<String, String>> rdd) -> {
          OffsetRange[] offsetRanges = ((HasOffsetRanges) rdd.rdd()).offsetRanges();
          OffsetRange[] range = new OffsetRange[1];
          range[0] = o;

          rdd.foreachPartition((Iterator<ConsumerRecord<String, String>> partitionOfRecords) -> {
          // get kafka offset
          OffsetRange o = offsetRanges[TaskContext.get().partitionId()];
          // to cache line data
          List<String> jsonData = new ArrayList<>();
          // to read all line data
          while (partitionOfRecords.hasNext()) {
                ConsumerRecord<String, String> line = partitionOfRecords.next();
                jsonData.add(line.value());
          }
          // TODO  do my own bussiness from jsonData
          .......
          //  HOW can I commit kafka Offset Here??
          // this is a method to commit offset 
          ((CanCommitOffsets) lines.inputDStream()).commitAsync(range) 
      });
    });

我已多次尝试,我发现它有一些问题:

  1. 当其他分区失败时,如果我的数据处理成功,它是如何工作的?这意味着我的所有数据流程应该回来了吗?因为kafka偏移有提交;

  2. 我已经运行了这段代码,然后我发现它真的执行commit操作是在下次执行rdd执行器时,这意味着如果进度或者被杀死,下次我从Kafka读取的一些数据将会双倍?

1 个答案:

答案 0 :(得分:0)

  

如果我的数据在其他分区时处理成功,它是如何工作的   失败了吗?这意味着我的所有数据流程应该回来了吗?因为卡夫卡   offset已提交

如果特定任务失败,Spark将尝试根据spark.task.maxFailures设置重新执行该任务。如果数字已过,则整个作业将失败。您需要确保如果commitAsync之前的部分失败,您就不会提交抵消。

  

我已经运行了这段代码,然后我发现它确实执行了commit操作   当下一次这个rdd执行程序运行时,它意味着进展oom   或者被杀,下次我从卡夫卡读到的一些数据会翻倍?

是。如果在下一次批处理迭代之前作业被终止,Spark将尝试重新读取已经处理过的数据。