欠点は、commitSync()が成功するか、再試行不可能なエラーが発生するまでコミットを再試行する一方で、commitAsync()は再試行しないことです。
このフレーズは私にはわかりません。コンシューマーがコミット要求をブローカーに送信すると思います。ブローカーがタイムアウト内に応答しない場合、コミットが失敗したことを意味します。私が間違っている?
commitSync
とcommitAsync
の違いを詳しく説明できますか?
また、どのコミットタイプを使用したいかについて、ユースケースを提供してください。
APIドキュメントで述べられているように:
これは同期コミットであり、コミットが成功するか、回復不可能なエラーが発生するまでブロックされます(この場合、呼び出し元にスローされます)。
つまり、commitSync
はブロッキングメソッドです。これを呼び出すと、成功または失敗するまでスレッドがブロックされます。
例えば、
_while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s", record.offset(), record.key(), record.value());
consumer.commitSync();
}
}
_
Forループの各反復では、consumer.commitSync()
が正常に戻るか、例外がスローされて中断された後でのみ、コードは次の反復に移動します。
これは非同期呼び出しであり、ブロックされません。発生したエラーは、コールバック(提供されている場合)に渡されるか、破棄されます。
つまり、commitAsync
は非ブロッキングメソッドです。それを呼び出してもスレッドはブロックされません。代わりに、最終的に成功するか失敗するかに関係なく、次の命令の処理を続行します。
たとえば、前の例と同様ですが、ここではcommitAsync
を使用しています。
_while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s", record.offset(), record.key(), record.value());
consumer.commitAsync(callback);
}
}
_
Forループの反復ごとに、最終的にconsumer.commitAsync()
に何が発生しても、コードは次の反復に移動します。そして、コミットの結果は、定義したコールバック関数によって処理されます。
トレードオフ:レイテンシとデータの整合性
commitSync()
を選択してください。これにより、さらにアクションを実行する前に、オフセットコミットが成功したか失敗したかを確認できます。ただし、同期とブロックであるため、コミットが完了するまで待機する時間が長くなり、レイテンシが長くなります。commitAsync()
を選択してください。終了するまで待機しないためです。代わりに、コミット要求を送信し、後でKafka(成功または失敗))からの応答を処理し、その間、コードは実行を続けます。これはすべて一般的に言えば、実際の動作は実際のコードとメソッドを呼び出す場所によって異なります。
CommitSyncとcommitAsyncはどちらもkafkaオフセット管理機能を使用しており、両方にデメリットがあります。メッセージ処理が成功し、コミットオフセットが失敗した(アトミックではない)と同時に、パーティションの再バランシングが発生した場合、処理されたメッセージが処理されます他のコンシューマーによる(重複処理)です。重複メッセージ処理に問題がない場合は、commitAsyncを実行できます(ブロックせず、低レイテンシを提供するため、高次コミットが提供されるため、問題ありません。それ以外の場合は、オフセットの処理と更新中に原子性を処理するカスタムオフセット管理を使用します(外部オフセットストレージを使用します)。