3

私は現在システムを再設計しており、ちょっとした問題に遭遇しました。

要件

メッセージのキュー ( RabbitMQキュー) と、そのキューから消費する多数のサービスがあります。各メッセージには、グループの一部であることを示す ID と、順序を示すのに役立つタイムスタンプがあります。

キューから消費する各サービスは、少なくとも 1 つのグループの処理を担当しますが、多数のグループを処理することもできます。サービスは複数のサーバーで実行できます。

システムは、可変数の消費サービスと、サービスの初期化/破棄時に ID が自動的に再割り当てされることを許可する必要があります。

メッセージはリアルタイムで処理する必要があり、バッファリングは許可されていません。メッセージは、ID グループ内で順番に処理する必要があります。


問題点・制約事項

Rabbit では、フェッチする前にキューをトラバーサルしたり、パターンに基づいて単一のキューからフェッチしたりすることはできません。

メッセージでは順序が重要です。単純に上位のメッセージを取得して、ID と一致しない場合は拒否できますが、これにより問題が発生します。

順序どおりの処理を強制するには、プリフェッチ カウント値を 1 に設定する必要があります。ただし、これにより、サービスが常にキューの先頭を取得しているにもかかわらず、どのサービスもメッセージを取得できないというライブロックが発生する可能性があります。プロセス、またはパフォーマンスに大きな影響を与えることはめったにありません。

逆に、これを合理的に軽減するのに十分な数にプリフェッチ カウントを設定すると、順不同の処理が可能になります。

いずれの場合も、プリフェッチ カウントを低い値に設定すると、パフォーマンスに大きな影響を与えるようです。


可能な解決策

複数のラビット キュー

コンシューマーごとにウサギのキューを自動的に生成し、トピック交換を使用してメッセージを自動的にルーティングすることは、可能な解決策のようです。

ただし、そのサービスのキューを処理する前に、消費するサービスの数を減らす必要がある場合、メッセージが失われるという問題が発生します。また、サービスが停止し、代替サービスを再開できない場合、メッセージが失われます。

コーディネーター/ワーカー

私の現在の考えは、キューから読み取り、ID に基づいてワーカーにメッセージを配布するコーディネーター サービスを用意することです。

これにより単一障害点が発生しますが、複数のコーディネーター プロセスを作成して、指定された ID をどのワーカーが担当するかをZookeeper経由で伝えることができます。

これには、次のいずれかのパターンが必要です。

  • プッシュ:各コーディネーターは、すべてのワーカーのリストを維持し、メッセージが入ってくるとプッシュします。
  • グローバル プル:各ワーカーはメッセージのすべてのコーディネーターをポーリングし、それらをローカルで並べ替えて処理します。
  • ローカル プル:ワーカーは 1 つのコーディネーターへの接続を維持し、コーディネーターはコーディネーター間でメッセージをやり取りします。

質問

  1. マスター/ワーカー モデルは、この問題に対する実行可能な解決策ですか? そしてそうならば;
    • コーディネーターはサーバー間でワーカーとどのように通信できますか? (上記の複数のウサギのキューの問題を回避しながら)
    • 同様に、前述のローカル プル方式を使用する場合、コーディネーターは相互にメッセージをやり取りできます。
  2. 私が見落としている他の解決策はありますか?

どんな助けでも大歓迎です

4

1 に答える 1

2

これは、この質問に対する適切な Stack Exchange ではないかもしれませんが、いくつかの点を修正することで、問題を突き止めます。

順序どおりの処理を強制するには、プリフェッチ カウント値を 1 に設定する必要があります。ただし、これにより、サービスが常にキューの先頭を取得しているにもかかわらず、どのサービスもメッセージを取得できず、ライブロックが発生する可能性があります。プロセス、またはパフォーマンスに大きな影響を与えることはめったにありません。

この問題がわかりません...すべてのメッセージを処理できる場合にのみ、サービスをキューにサブスクライブさせます。また、キューが処理できるルーティング キーのみをバインドします。

いずれの場合も、プリフェッチ カウントを低い値に設定すると、パフォーマンスに大きな影響を与えるようです。

基本的に、プリフェッチ カウントはワーカーの数と同じにする必要があります。そうしないと、メリットがほとんど得られません。問題は、順序を失うことなく 2 つの複数のこと (つまり、複数の作業を並行して実行すること) を実行できないことです。

したがって、プリフェッチ カウントではなく、複数の並列ワーカーで順序が失われます。

また、サービスが停止し、代替サービスを再開できない場合、メッセージが失われます。

いいえ、これは起こるべきではありません。サービスがメッセージを送信しない場合ackでも、メッセージは失われません。キューを削除せず、永続化してください。ただし、キューとバインディングを動的に追加する場合、これはあなたが言おうとしていたことだと思いますが、バインディング (ルーティング キー) が時間内に宣言されていないと、メッセージが失われる可能性があります。この問題は、dead letter exchange で対処できます

あなたの一般的な問題は、ワーカーをキューに追加しても順序を維持できるようにしたいと思うことです。これは大規模に解決するのが非常に難しい問題です。Twitterがこれをどのように行っているかを調べる必要があります。

いくつかのアイデアは、何を「ハッシュ」できるか、何をキューにできるかを理解することです。たとえば、特定の地理的地域のすべてのユーザーのキューを作成して、それらの地域の人々の順序を維持できます。それは本当にあなたのビジネス上の問題に依存します。

于 2013-03-19T12:54:05.710 に答える