10

基本的に、私の消費者は生産者でもあります。初期データセットを取得し、キューに送信します。消費者がアイテムを受け取り、それを処理します。その時点から、次の 3 つの可能性があります。

  1. データは良好で、ストレージ用に「良好な」キューを配置します
  2. データが不良で破棄されました
  3. データは良好 (まだ) または不良 (まだ) ではないため、データは小さな部分に分割され、さらに処理するためにキューに戻されます。

私の問題はステップ 3 にあります。最初はキューが非常に急速に大きくなり、データの一部がキューに複製された部分に分割され、消費者がそれを処理し続けて無限ループに陥る可能性があるためです。

これを防ぐ方法は、重複がキューに入らないようにすることだと思います。クライアント側でこれを行うことはできません.1時間の間に多くのコアが数十億のデータポイントを処理する可能性があるためです(送信する前に各クライアントにスキャンさせると、速度が大幅に低下します)。これはサーバー側で行う必要があると思いますが、前述したように、データは非常に大きく、重複を効率的に防ぐ方法がわかりません。

私は不可能なことを尋ねているかもしれませんが、試してみようと思いました。どんなアイデアでも大歓迎です。

4

3 に答える 3

11

重複をキューに送信しないという問題を修正できたとしても、遅かれ早かれこの問題にぶつかると思います。

RabbitMQ ドキュメントから: 「障害からの回復: クライアントが接続されていたノードの障害が原因でクライアントがブローカーから切断された場合、クライアントがパブリッシング クライアントであった場合、ブローカーが受け入れて、クライアントがメッセージの確認を受信せずにクライアントからメッセージを渡しました; また、消費側でも同様に、クライアントがメッセージの確認を発行し、それらの確認がブローカーに送信され、以前に処理されたかどうかわからない可能性があります。エラーが発生しました。要するに、消費するクライアントが重複したメッセージを識別して処理できることを確認する必要があります。」

基本的には、次のようになります。rabbitmq にリクエストを送信すると、rabbitmq は ACK で応答しますが、何らかの理由で、コンシューマーまたはプロデューサーがこの ACK を受信しません。Rabbitmq は ack が受信されなかったことを知る方法がなく、プロデューサーは ack を受信せずにメッセージを再送信することになります。

特にメッセージングが一種の RPC として使用されるアプリでは、重複したメッセージを処理するのは面倒ですが、この種のメッセージング アーキテクチャを使用する場合、これは避けられないようです。

于 2012-10-30T21:49:14.120 に答える
3

コアの問題は次のようです。

"...its possible that a piece of data is broken down into a part that's 
duplicated in the queue and the consumers continue to process it and 
end up in a infinite loop."

キューに入れられたアイテムの一意性に集中することができますが、上記の問題は、IMO. 無限ループを防ぐ方法の 1 つは、メッセージ ペイロードに「visited」ビットを含めることです。これは、消費者が分解されたアイテムを再度キューに入れる前に設定されます。

もう 1 つのオプションは、無限ループを防ぐために少し異なる方法で処理される特別なキューにコンシューマーを再キューイングさせることです。いずれにせよ、メッセージング システムの機能を使用して問題を回避するのではなく、アプリケーションの戦略の中核として問題に対処することで、問題に対処する必要があります。

于 2012-04-14T17:32:26.397 に答える