web-dev-qa-db-ja.com

kafka公開の失敗を堅牢な方法で処理する方法

私はKafkaを使用していますが、メッセージを1つも見逃してはならないフォールトトレラントシステムを構築するためのユースケースがあります。問題は次のとおりです。Kafka何らかの理由(ZooKeeperがダウンしている、Kafkaブローカーがダウンしているなど))が原因で失敗する方法これらのメッセージを堅牢に処理し、元に戻ったら再生するにはどうすればよいですか。メッセージが1つでも失敗する可能性があります。別の使用例として、カウンター機能やカウンター機能などの理由でKafkaに公開できなかったメッセージの数を、任意の時点で知る必要があります。これらのメッセージは、再度公開する必要があります。

解決策の1つは、これらのメッセージをデータベースにプッシュすることです(Cassandra書き込みは非常に高速ですが、カウンター機能も必要です。Cassandraカウンター機能)それほど素晴らしいものではないので、使用したくありません。)この種の負荷を処理でき、非常に正確なカウンター機能も提供します。

この質問は、アーキテクチャの観点からのものであり、それを実現するためにどのテクノロジーを使用するかということです。

PS:3000TPSのようなものを扱っています。したがって、システムが失敗し始めると、それらの失敗したメッセージは非常に短時間で非常に速く成長する可能性があります。 Javaベースのフレームワークを使用しています。

ご協力いただきありがとうございます!

13
Nishant

Kafkaが分散型のフォールトトレラントな方法で構築された理由は、問題をまったく同じように処理するためです。コアコンポーネントに複数の障害が発生すると、サービスの中断を回避できます。 Zookeeperのダウンを回避するには、Zookeeperのインスタンスを少なくとも3つデプロイします(これがAWSにある場合は、アベイラビリティーゾーン全体にデプロイします)。ブローカーの障害を回避するには、複数のブローカーをデプロイし、プロデューサーのbootstrap.serversプロパティで複数のブローカーを指定していることを確認してください。 Kafkaクラスターが永続的なマナーでメッセージを書き込んだことを確認するには、プロデューサーでacks=allプロパティが設定されていることを確認してください。これにより、すべての同期レプリカがメッセージの受信を確認したときにクライアントの書き込みが確認されます(スループットが犠牲になります)。キューイング制限を設定して、ブローカーへの書き込みがバックアップを開始した場合に、例外をキャッチして処理し、場合によっては再試行できるようにすることもできます。

Cassandra(別のよく考えられた分散型のフォールトトレラントシステム)を使用して書き込みを「ステージング」することは、アーキテクチャに信頼性を追加するようには見えませんが、複雑さを増し、さらにCassandraはそうではありませんでした。メッセージキューのメッセージキューとして記述されているので、これは避けます。

適切に構成されたKafkaは、すべてのメッセージ書き込みを処理し、適切な保証を提供するために使用できる必要があります。

5
Chris Matta

クリスは、システムのフォールトトレラントを維持する方法についてすでに話しました。

Kafkaは、デフォルトでat-least onceメッセージ配信セマンティクスをサポートします。つまり、メッセージを送信しようとすると、何かが発生すると、メッセージを再送信しようとします。

Kafka Producerプロパティを作成する場合、retriesオプションを0より大きく設定することでこれを構成できます。

 Properties props = new Properties();
 props.put("bootstrap.servers", "localhost:4242");
 props.put("acks", "all");
 props.put("retries", 0);
 props.put("batch.size", 16384);
 props.put("linger.ms", 1);
 props.put("buffer.memory", 33554432);
 props.put("key.serializer", "org.Apache.kafka.common.serialization.StringSerializer");
 props.put("value.serializer", "org.Apache.kafka.common.serialization.StringSerializer");

 Producer<String, String> producer = new KafkaProducer<>(props);

詳細については、 this を確認してください。

2
Shankar