web-dev-qa-db-ja.com

KafkaコンシューマAPIを最初から使用してデータを読み取る方法は?

コンシューマーjarを実行するたびに、最初からKafka Consumer APIを使用してメッセージを読む方法を教えてください。

32
Nits

これは0.9.xコンシューマーで機能します。基本的に、コンシューマを作成するとき、プロパティ_ConsumerConfig.GROUP_ID_CONFIG_を使用して、このコンシューマにコンシューマグループIDを割り当てる必要があります。このproperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID().toString());(プロパティはコンストラクタnew KafkaConsumer(properties)に渡すJava.util.Propertiesのインスタンスです)のようにコンシューマを起動するたびに、ランダムにコンシューマグループIDを生成します。

クライアントをランダムに生成するということは、新しい消費者グループにkafkaで関連付けられたオフセットがないことを意味します。したがって、このシナリオでポリシーを設定する必要があります。 _auto.offset.reset_プロパティのドキュメントには次のように書かれています:

Kafkaに初期オフセットがない場合、または現在のオフセットがサーバー上にもう存在しない場合(そのデータが削除されたためなど):

  • 最も早い:オフセットを最も早いオフセットに自動的にリセットします
  • latest:オフセットを最新のオフセットに自動的にリセットします
  • none:以前のオフセットが見つからない場合、またはコンシューマーのグループがない場合、コンシューマーに例外をスローします
  • その他:例外をコンシューマにスローします。

したがって、上記のオプションからearliestポリシーを選択して、新しいコンシューマグループが毎回最初から開始されるようにする必要があります。

Javaでのコードは、次のようになります。

_properties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID().toString());
properties.put(ConsumerConfig.CLIENT_ID_CONFIG, "your_client_id");
properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumer = new KafkaConsumer(properties);
_

ここで理解する必要があるのは、同じコンシューマーグループに属する複数のコンシューマーがランダムIDを生成し、それらをすべて同じコンシューマーグループに属するようにそれらのインスタンス間で配布する方法を配布する場合です。

それが役に立てば幸い!

38
Nautilus

これを行う1つのオプションは、開始するたびに一意のグループIDを持つことです。これは、Kafkaがトピックのメッセージを最初から送信することを意味します。 KafkaConsumerのプロパティ:

properties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID().toString());

もう1つのオプションはconsumer.seekToBeginning(consumer.assignment())を使用することですが、これはKafka=コンシューマーがpollメソッドを呼び出すことによって最初にコンシューマーからハートビートを取得しない限り機能しません。したがって、poll() 、その後seekToBeginning()を実行し、最初からすべてのレコードが必要な場合はpoll()を再度呼び出します。これは少しハッキーですが、これは0.9リリースの時点で最も信頼できる方法のようです。

// At this point, there is no heartbeat from consumer so seekToBeinning() wont work
// So call poll()
consumer.poll(0);
// Now there is heartbeat and consumer is "alive"
consumer.seekToBeginning(consumer.assignment());
// Now consume
ConsumerRecords<String, String> records = consumer.poll(0);
15
ucsunil

考えられる解決策の1つは、1つ以上のトピックをサブスクライブするときにConsumerRebalanceListenerの実装を使用することです。 ConsumerRebalanceListenerには、新しいパーティションが割り当てられたとき、またはコンシューマから削除されたときのコールバックメソッドが含まれています。次のコードサンプルはこれを示しています。

public class SkillsConsumer {

private String topic;

private KafkaConsumer<String, String> consumer;

private static final int POLL_TIMEOUT = 5000;

public SkillsConsumer(String topic) {
    this.topic = topic;
    Properties properties = ConsumerUtil.getConsumerProperties();
    properties.put("group.id", "consumer-skills");
    this.consumer = new KafkaConsumer<>(properties);
    this.consumer.subscribe(Collections.singletonList(this.topic),
            new PartitionOffsetAssignerListener(this.consumer));
    }
}

public class PartitionOffsetAssignerListener implements ConsumerRebalanceListener {

private KafkaConsumer consumer;

public PartitionOffsetAssignerListener(KafkaConsumer kafkaConsumer) {
    this.consumer = kafkaConsumer;
}

@Override
public void onPartitionsRevoked(Collection<TopicPartition> partitions) {

}

@Override
public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
    //reading all partitions from the beginning
    for(TopicPartition partition : partitions)
        consumer.seekToBeginning(partition);
}

}

これで、パーティションがコンシューマに割り当てられるたびに、各パーティションが最初から読み込まれます。

6
skm

1) https://stackoverflow.com/a/17084401/382165

2) http://mail-archives.Apache.org/mod_mbox/kafka-users/201403.mbox/%3CCAOG_4QYz2ynH45a8kXb8qw7xw4vDRRwNqMn5j9ERFxJ8RfKGCg@mail.gmail.com%3E

コンシューマグループをリセットするには、ZookeeperグループIDを削除できます

 import kafka.utils.ZkUtils;
 ZkUtils.maybeDeletePath(<zkhost:zkport>, </consumers/group.id>);`
4
KingJulien

ConsumerConfigの作成時に高レベルコンシューマセットprops.put("auto.offset.reset", "smallest");を使用している間

2
user2720864

Java consumer api、より具体的にはorg.Apache.kafka.clients.consumer.Consumerを使用している場合、seek *メソッドを試すことができます。

consumer.seekToBeginning(consumer.assignment())

ここで、consumer.assignment()は、特定のコンシューマに割り当てられたすべてのパーティションを返し、seekToBeginningは、特定のパーティションのコレクションの最も早いオフセットから開始します。

1

だから私にとっては、上で提案されたものの組み合わせが効果的でした。主な変更点は、

props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");

ランダムに生成されるグループIDを毎回持っています。しかし、これだけではうまくいきませんでした。何らかの理由で、私が初めて消費者に投票したとき、それは記録を取得していませんでした。動作させるためにハッキングする必要がありました-

consumer.poll(0); // without this the below statement never got any records
final ConsumerRecords<Long, String> consumerRecords = consumer.poll(Duration.ofMillis(100));

私はKAFKAが初めてで、なぜこれが起こっているのか分かりませんが、まだこれを機能させようとしている人にとっては、これが役立つことを願っています。

1
karthiks3000
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");

オフセットの保存を単に避けると、コンシューマは常に最初にリセットされます。

0
offroff