我使用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)
});
});
我已多次尝试,我发现它有一些问题:
当其他分区失败时,如果我的数据处理成功,它是如何工作的?这意味着我的所有数据流程应该回来了吗?因为kafka偏移有提交;
我已经运行了这段代码,然后我发现它真的执行commit操作是在下次执行rdd执行器时,这意味着如果进度或者被杀死,下次我从Kafka读取的一些数据将会双倍?
答案 0 :(得分:0)
如果我的数据在其他分区时处理成功,它是如何工作的 失败了吗?这意味着我的所有数据流程应该回来了吗?因为卡夫卡 offset已提交
如果特定任务失败,Spark将尝试根据spark.task.maxFailures
设置重新执行该任务。如果数字已过,则整个作业将失败。您需要确保如果commitAsync
之前的部分失败,您就不会提交抵消。
我已经运行了这段代码,然后我发现它确实执行了commit操作 当下一次这个rdd执行程序运行时,它意味着进展oom 或者被杀,下次我从卡夫卡读到的一些数据会翻倍?
是。如果在下一次批处理迭代之前作业被终止,Spark将尝试重新读取已经处理过的数据。