web-dev-qa-db-ja.com

春Kafka-グループIDを使用してオフセットを最新にリセットする方法は?

私は現在、Spring Integration Kafka=を使用してリアルタイム統計を作成しています。ただし、グループ名はKafkaリスナーが読み取っていなかった以前のすべての値を検索します。

@Value("${kafka.consumer.group.id}")
private String consumerGroupId;

@Bean
public ConsumerFactory<String, String> consumerFactory() {
    return new DefaultKafkaConsumerFactory<>(getDefaultProperties());
}

public Map<String, Object> getDefaultProperties() {
    Map<String, Object> properties = new HashMap<>();
    properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);

    properties.put(ConsumerConfig.GROUP_ID_CONFIG, consumerGroupId);

    properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class);
    return properties;
}

@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {

    ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactory());
    return factory;
}

@Bean
public KafkaMessageListener listener() {
    return new KafkaMessageListener();
}

私は最新のオフセットから始めて、古い値に悩まされないようにしたいと思います。グループのオフセットをリセットする可能性はありますか?

8
Bachrc

この例は見なかったので、ここでどのようにしたかを説明します。

あなたのクラス@KafkaListenerConsumerSeekAwareクラスを実装する必要があります。これにより、パーティションが割り当てられている場合にリスナーがオフセットシークを制御できるようになります。 (ソース: https://docs.spring.io/spring-kafka/reference/htmlsingle/#seek

public class KafkaMessageListener implements ConsumerSeekAware {
    @KafkaListener(topics = "your.topic")
    public void listen(byte[] payload) {
        // ...
    }

    @Override
    public void registerSeekCallback(ConsumerSeekCallback callback) {

    }

    @Override
    public void onPartitionsAssigned(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
        assignments.forEach((t, o) -> callback.seekToEnd(t.topic(), t.partition()));
    }

    @Override
    public void onIdleContainer(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {


    }
}

ここでは、リバランス時に、指定されたすべてのトピックの最後のオフセットを探すために、指定されたコールバックを使用します。 Artem Bilan( https://stackoverflow.com/users/2756547/artem-bilan )に回答してくれてありがとう。

11
Bachrc

まあ、それはあなたが消費者のauto.offset.reset。しかし、とにかくそれがデフォルトでlatestであると私を混乱させているのは:

auto.offset.reset   What to do when there is no initial offset in Kafka or if the current offset does not exist any more on the server (e.g. because that data has been deleted):

earliest: automatically reset the offset to the earliest offset
latest: automatically reset the offset to the latest offset
none: throw exception to the consumer if no previous offset is found for the consumer's group
anything else: throw exception to the consumer.

string  latest  [latest, earliest, none]    medium
1
Artem Bilan

いくつかのトピックにサブスクライブするときに、kafkaコンシューマにConsumerRebalanceListenerを設定できます。このトピックでは、KafkaConsumer.endOffsets()メソッドによって各パーティションの最新のオフセットを取得できます、これをKafkaConsumer.seek()メソッドでコンシューマに設定します。

kafkaConsumer.subscribe(Collections.singletonList(topics),
    new ConsumerRebalanceListener() {
        @Override
        public void onPartitionsRevoked(Collection<TopicPartition> partitions) {
            //do nothing
        }

        @Override
        public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
            //get and set the lastest offset for each partiton
            kafkaConsumer.endOffsets(partitions) 
                .forEach((partition, offset) -> kafkaConsumer.seek(partition, offset));
        }
    }
);
1
A.Chinese

次のように、partitionOffsetsアノテーションを使用して、正確なオフセットで開始できます。

@KafkaListener(id = "bar", topicPartitions =
    { @TopicPartition(topic = "topic1", partitions = { "0", "1" }),
      @TopicPartition(topic = "topic2", partitions = "0",
         partitionOffsets = @PartitionOffset(partition = "1", initialOffset = "100"))
    })public void listen(ConsumerRecord<?, ?> record) {
     }
0
link

それを行う最も簡単な方法は、CONSUMER_GROUP_ID

properties.put(ConsumerConfig.GROUP_ID_CONFIG, "new-consumer-group-id");
properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");

それを行う余裕がない場合は、初期化中に目的のオフセットを探す必要があります。

ドキュメントを参照

0