【问题标题】:Kafka commitAsync Retries with Commit OrderKafka commitAsync 使用提交顺序重试
【发布时间】:2018-11-12 22:26:16
【问题描述】:

我正在阅读 Kafka 权威指南,在消费者章节中有一个关于“重试异步提交”的简介:

为异步重试正确获取提交顺序的一个简单模式是使用单调递增的序列号。每次提交时增加序列号,并将提交时的序列号添加到 commitAsync 回调。当您准备发送重试时,检查回调获得的提交序列号是否等于实例变量;如果是,则没有更新的提交,可以安全地重试。如果实例序列号更高,请不要重试,因为已经发送了更新的提交。

作者的一个简单示例在这里对于像我这样的密集人群来说会很棒。我对上面加粗的部分特别不清楚。

谁能阐明这意味着什么,或者更好地提供一个玩具示例来证明这一点?

【问题讨论】:

    标签: apache-kafka commit offset kafka-consumer-api


    【解决方案1】:

    这就是我的想法,但谦虚我可能是错的

          try {
            AtomicInteger atomicInteger = new AtomicInteger(0);
            while (true) {
                ConsumerRecords<String, String> records = consumer.poll(5);
                for (ConsumerRecord<String, String> record : records) {
                    System.out.format("offset: %d\n", record.offset());
                    System.out.format("partition: %d\n", record.partition());
                    System.out.format("timestamp: %d\n", record.timestamp());
                    System.out.format("timeStampType: %s\n", record.timestampType());
                    System.out.format("topic: %s\n", record.topic());
                    System.out.format("key: %s\n", record.key());
                    System.out.format("value: %s\n", record.value());
                }
    
                consumer.commitAsync(new OffsetCommitCallback() {
                    private int marker = atomicInteger.incrementAndGet();
                    @Override
                    public void onComplete(Map<TopicPartition, OffsetAndMetadata> offsets,
                                           Exception exception) {
                        if (exception != null) {
                            if (marker == atomicInteger.get()) consumer.commitAsync(this);
                        } else {
                            //Cant' try anymore
                        }
                    }
                });
            }
        } catch (WakeupException e) {
            // ignore for shutdown
        } finally {
            consumer.commitSync(); //Block
            consumer.close();
            System.out.println("Closed consumer and we are done");
        }
    

    【讨论】:

    • 感谢您的示例!有道理,但是 AtomicInteger 的实例化是否应该在循环处理记录之前发生,然后在循环中增加这个值,最后在回调中将此值设置为标记?我认为如果没有这个,您将无法检查是否提交了稍后的偏移量,因为在此示例中每个偏移量都以 0 值开头。这似乎是正确的?
    • consumer.poll 已弃用,你如何处理消费者记录?
    • @TiagoMedici consumer.poll(5) 已弃用,更改为 consumer.poll(Duration.ofMillis(5)); 或任何您想要的时间。对于第二个问题,ConsumerRecords&lt;K,V&gt; 是您迭代的记录。
    • 我更喜欢这种方式: public void receive(ConsumerRecord, ?> record, Consumer consumer) ,一旦你没有定义投票,所有的消息都会到达,如果你定义了一个投票:consumer.poll(Duration.ofMillis(5)),只有70%的消息到达,无论如何我可以从头开始检索consumerRecord,我的问题是提交一条消息而我的消费者正在提交整个分区,即使我表示偏移量,我想知道投票大小可以提供帮助!!!!
    猜你喜欢
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    相关资源
    最近更新 更多