Spark Kafka流媒体:偏移管理-Can';无法手动提交工作(Java)
我们使用JavaInputDStream从ApacheKafka读取消息(值:JSON字符串),加入一些OracleDB数据并写入ElasticSearch 我们实现了中所述的偏移管理,但现在我们才意识到偏移管理不适用于我们,并且如果当前小批量中出现故障,流不会再次读取消息。即使我们跳过这一行,它也不会再次读取消息:Spark Kafka流媒体:偏移管理-Can';无法手动提交工作(Java),java,apache-spark,apache-kafka,streaming,Java,Apache Spark,Apache Kafka,Streaming,我们使用JavaInputDStream从ApacheKafka读取消息(值:JSON字符串),加入一些OracleDB数据并写入ElasticSearch 我们实现了中所述的偏移管理,但现在我们才意识到偏移管理不适用于我们,并且如果当前小批量中出现故障,流不会再次读取消息。即使我们跳过这一行,它也不会再次读取消息: ((CanCommitOffsets) stream.inputDStream()).commitAsync(offsetRanges); 我们将代码分解为以下内容,并期望流在循
((CanCommitOffsets) stream.inputDStream()).commitAsync(offsetRanges);
我们将代码分解为以下内容,并期望流在循环中一次又一次地读取相同的消息,但事实并非如此:
stream.foreachRDD(recordRDD -> {
final OffsetRange[] offsetRanges = ((HasOffsetRanges) recordRDD.rdd()).offsetRanges();
if (!recordRDD.isEmpty()) {
LOGGER.info("Processing some Data: " + recordRDD.rdd().count());
}
});
使用者配置参数enable.auto.commit设置为false,初始化JavaInputDStream后也会显示在日志中。测试中的嵌入式Kafka代理和开发阶段的Kafka服务器都面临同样的问题。目前,这两种模式都以独立模式运行
我们尝试的是:
- 代理配置:增加offset.commit.timeout.ms
- 使用者/流配置:将isolation.level设置为“read_committed”
- 消费者/流配置:将auto.offset.reset设置为最早
- Spark:将Spark.streaming.unpersist设置为false
- Spark:增加Spark.streaming.kafka.maxRetries的值
- 流:将streamingPhaseDuration调整为比小批量所需的时间更长
- 流:启用检查点
- 流:改变位置策略
有没有什么不同的方法或事实我遗漏了?经过更多的测试后,我们发现只有当流在实际批处理过程中停止/崩溃时,手动提交才起作用。如果流停止并重新启动,它将再次使用失败的数据 因此,我们目前正在做的是,每当检测到故障时,直接停止流
javaStreamingContext.stop(false)
。
在此之后,调度程序将再次启动流,该调度程序将验证流是否在正常的时间段内处于活动状态,如果不处于活动状态,则启动流
这不是一个优雅的解决方案,但它首先适用于我们。我们面临着类似的问题。您找到了比停止javaStreamingContext更好的方法吗?