2017-08-27 18 views
2

フロントエンドサービスがKafkaのリクエストのトピックにメッセージをプッシュし、ダウンストリームのバックエンドコンシューマの別の「応答」トピックをリッスンするシステムを作成しています。最終的にKafkaにプッシュバックして) 'request'メッセージの処理を行い、最終的に 'response'トピックにプッシュします。Kafkaコンシューマとプロデューサパーティションの一致

消費者が適切なパーティションでリッスンして応答を受信し、フロントエンドコンシューマがリッスンしているパーティションにバックエンドがプッシュすることを確認する最も洗練された方法を見つけようとしています。私たちは常に、応答が最初のメッセージを生成したのと同じ消費者に流れるようにする必要があります。

私は今のところ2つの解決策を持っていますが、どちらも特に満足できません。

  1. 各フロントエンドでどのリスンするかを決定し、メッセージとともにそのパーティションを「要求」トピックに渡すようにしてください。バックエンドの処理が終了すると、メッセージのパーティションメンバーを調べ、適切なパーティションに移動します。ここで直ちに問題になるのは、フロントエンドサービスを調整して各パーティションに均等に分散する方法です(ランダム割り当て?)。
  2. 各メッセージには相関ID、GUIDがあります。フロントエンドへのリクエストごとに、パーティションの総数に対するGUIDのハッシュに基づいてパーティションのリッスンを開始し、メッセージを「要求」トピックにプッシュします。バックエンドは相関IDを調べ、適切なパーティションを決定します。ここで問題となるのは、フロントエンドは新しい要求を受け取るたびに、新しいパーティションに新しいコンシューマーを設定する必要があります(オーバーヘッドがありますか?)同じパーティション上の複数のアクティブなコンシューマーと、多くのパーティション。
  3. 消費者とパーティションの数が等しい単一の消費者グループがある場合は、(1)と同様のアプローチを採用しますが、どの消費者がどのパーティションにあるのかをKafkaが処理できるようにします。しかし、リバランスが発生した場合、特にバックエンドで既に飛んでいるメッセージ(潜在的にすべてのパーティションが変更される可能性があるため)の場合、何が起きるかを把握する必要があります。

これは一般的なパターンである必要がありますので、他の人がこれをどのように解決したのか不思議です。

答えて

3

パーティションを手動で割り当てたコンシューマは使用しないでください。それは本当に乱雑になる可能性があり、規模を拡大することは難しいです。

パーティションの代わりに、フロントエンドコンシューマごとのトピックを使用できます。各フロントエンドサービスは、フロントエンドサービスのIDを含むメッセージをrequestトピックに作成します。その後、バックエンドはメッセージを消費し、idに基づいて特定のunique-front-end-service-responseトピックへの応答メッセージを生成します。 フロントエンドサービスの数が一定の場合、これは良い解決策になります。新しいフロントエンドサービスを追加するたびに、新しいトピックが作成される可能性があります。ただし、手動でパーティションを割り当てるよりも保守がずっと簡単です。

もう1つの可能な解決策は、別のツールを使用することです。カフカが必須でない場合は、あなたの要件を再考し、研究をしてください。おそらくカフカよりもあなたのニーズに合ったツールがあります。

+0

ありがとうございます - フロントエンドごとに1つのトピックが実行可能なソリューションであるようです。私たちはバックエンドのためにKafkaを大いに利用していますが、バックエンドの処理が完了したときにカフカを経由するよりも、フロントエンドと直接通信する方法があると思います。 – David

0

は時々応答がが、それはウェブフック、WebSocketを、電子メールを介して直接外部の配信のためにカフカコネクタにカフカの応答メッセージを送信することにより、ユーザの要求に直接応答することができます場合は、元の要求元のアプリケーションに行くことを持っていません、またはSMSテキストメッセージを元のユーザーに返します。

SOAPまたはRESTスタイルのRPCを行う場合は、証明されたパターンのようにKafkaの代わりにHTTPを使用します。

+0

私たちの場合、フロントエンドはHTTPサービスなので、同じインスタンスはバックエンドから返されたもので応答する必要があります。 – David

+0

したがって、HTTPサービスのURLをキーとしてKafka要求メッセージを発行します。バックエンドのカフカ消費者が応答を送ろうとするとき、それはそのキーと同じURLを持つ応答トピックに公開するべきです。次に、HTTP/webhook用のKafkaコネクタが応答メッセージを取得し、元のHTTPサービスをHTTPポストバックします(おそらく、レスポンス用のわずかに変更されたURL上で)。したがって、元のWebサービスの視点からのカフカリクエスト/ httpレスポンスです。一度に複数のリクエストをサポートする場合は、URLにcorrelationIDを追加するだけです –

0

バックエンドプロデューサのパーティション機能を使用し、フロントエンドコンシューマに手動パーティション割り当てassignを使用して興味のあるパーティションのみをリッスンすることです。

より詳細:フロントエンドプロデューサー

、あなたが「要求」のトピックに「要求」メッセージを生成する前に、(それが必要なフロントエンドのクライアントIDへのメッセージキーを設定ユニークであるように)。バックエンドの消費者

、ちょうどrequestトピックをサブスクライブするsubscribeを使用して、手動でパーティションの割り当てを行う必要はありません。しかし、あなたが「要求」メッセージを受け取って処理するときに、メッセージキーを紛失しないように注意してください。要求がどこから来たのかを特定するためです。

バックエンドプロデューサでは、リクエスト処理が完了したら、返信するレスポンスメッセージを生成し、応答メッセージキーを上記のフロントエンドクライアントIDに設定します。また、パーティション関数(ハッシュ関数、クライアントIDをパーティション番号にマッピングする)を定義する必要もあります。パーティション機能を使用してsend()を実行します。

フロントエンドコンシューマでは、特定のパーティションをリスンするには、assgin()メソッドを使用する必要があります。しかしどのパーティションを聞くべきかを知る方法は? client-id(これは同じクライアントで同じになります)と上で定義した同じハッシュ関数を使用して、聞くべきパーティション番号を計算してください。

関連する問題