簡體   English   中英

在第一批處理后關閉Spark Streaming上下文(嘗試檢索kafka偏移量)

[英]Closing Spark Streaming Context after first batch (trying to retrieve kafka offsets)

我正在嘗試為我的Spark Ba​​tch作業檢索Kafka偏移量。 檢索偏移量后,我想關閉流上下文。

我嘗試將streamlistener添加到流上下文中,並實現onBatchCompleted方法以在作業完成后關閉流,但是我收到異常“無法在偵聽器總線線程內停止StreamingContext”

有針對這個的解決方法嗎? 我正在嘗試檢索偏移量以調用KafkaUtils.createRDD(sparkContext,kafkaProperties,OffsetRange [],LocationStrateg)

private OffsetRange[] getOffsets(SparkConf sparkConf) throws InterruptedException {
    final AtomicReference<OffsetRange[]> atomicReference = new AtomicReference<>();

    JavaStreamingContext sc = new JavaStreamingContext(sparkConf, Duration.apply(50));
    JavaInputDStream<ConsumerRecord<String, String>> stream =
            KafkaUtils.createDirectStream(sc, LocationStrategies.PreferConsistent(), ConsumerStrategies.<String, String>Subscribe(Arrays.asList("test"), getKafkaParam()));
    stream.foreachRDD((VoidFunction<JavaRDD<ConsumerRecord<String, String>>>) rdd -> {
                atomicReference.set(((HasOffsetRanges) rdd.rdd()).offsetRanges());
                // sc.stop(false); //this would throw exception saying consumer is already closed
            }
    );
    sc.addStreamingListener(new TopicListener(sc)); //Throws exception saying "Cannot stop StreamingContext within listener bus thread."
    sc.start();
    sc.awaitTermination();
    return atomicReference.get();
}



public class TopicListener implements StreamingListener {
private JavaStreamingContext sc;

public TopicListener(JavaStreamingContext sc){
    this.sc = sc;
}
@Override
public void onBatchCompleted(StreamingListenerBatchCompleted streamingListenerBatchCompleted) {
    sc.stop(false);
}

非常感謝stackoverflow-ers :)我已經嘗試搜索可能的解決方案,但到目前為止尚未成功

編輯 :我用KafkaConsumer來獲取分區信息。 一旦獲得分區信息,就創建一個TopicPartition pojos列表,並調用position和endOffsets方法分別獲取我的groupId的當前位置和結束位置。

final List<PartitionInfo> partitionInfos = kafkaConsumer.partitionsFor("theTopicName");
final List<TopicPartition> topicPartitions = new ArrayList<>();
partitionInfos.forEach(partitionInfo -> topicPartitions.add(new TopicPartition("theTopicName", partitionInfo.partition())));
final List<OffsetRange> offsetRanges = new ArrayList<>();
kafkaConsumer.assign(topicPartitions);
topicPartitions.foreach(topicPartition -> {
    long fromOffset = kafkaConsumer.position(topicPartition);
    kafkaConsumer.seekToEnd(Collections.singleton(topicPartition));
    long untilOffset = kafkaConsumer.position(topicPartition);
    offsetRanges.add(new OffsetRange(topicPartition.topic(), topicPartition.partition(), fromOffset, untilOffset));
});
return offsetRanges.toArray(new OffsetRange[offsetRanges.size()]);

如果要控制流,則可以考慮使用輪詢而不是流式API。 這樣一來,您就可以在達到目標后清楚地停止輪詢。

還檢查一下...

https://github.com/dibbhatt/kafka-spark-consumer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM