web-dev-qa-db-ja.com

大量のオーバーフローデータのデザインパターン?

現在のキューは、レート制限付きのサードパーティサービスによって消費されるメッセージを公開しています。現在、メッセージは指数バックオフで再試行されています。ただし、データが非常に速く入ってくるため、再試行が追いつかない場合もあります。

ほとんどのサードパーティサービスは代替のバッチインポートを提供しており、私がこれまでに考え出したソリューションは、帯域外で処理されるファイルにデータを書き込むことです。

オーバーフローするデータを格納するための設計パターンはありますか?

4
kreek

説明されている主な問題は、プロデューサーがコンシューマーよりも速いことです。これは私に多くの http://ferd.ca/queues-don-t-fix-overload.html を思い出させます。 リアクティブストリームは、この種の設定に対する解決策を提供するために最近気付いたイニシアチブです。

次のようなキュー指向のソフトウェア製品を見ることができます。

  • Akka(letitcrash.comは彼らのブログで、いくつかの興味深い一般的な投稿があります)または
  • ZeroMQ(それらのガイドは、あらゆるキューシステムに適用できるいくつかの設定を提供しています)

プロデューサーの過剰達成に対処する方法を確認します。

しかし、主な質問は、ビジネスの観点からそれをどのように処理したいかです。コンシューマ(サードパーティ)は処理できるメッセージの量が限られているため、バッファリングされたメッセージをバッチインポートするアプローチは合理的であると思われます。シナリオによっては、メッセージを集約したりドロップしたりすることも可能です。

オーバーフローにどのように対応したいかに関係なく、キューはこの事実(つまり、バックプレッシャーの導入)を認識している必要があり、要件に応じた独自の戦略を適用できます。

私の最後のプロジェクトでは、キューシステムを介してコンシューマーからメッセージを取得することになりました。

  • プロデューサーは、既存のメッセージパイルを処理するために使用できるリソースを独占していませんでした。
  • メッセージを処理するワーカーは、準備が整ったときに、新しいメッセージをスケジュールでプッシュする必要なく、新しいメッセージをフェッチできます。
  • メッセージをドロップできなかったため、プロデューサーの特定の間隔でダウンタイムが保証されていて、追いつくことができました。

これがあなた自身の解決策を見つけることを可能にするいくつかのハンドルを提供することを願っています。

1
other_paul

理想的な状況は、キューにメッセージを無期限に保存し、メッセージを配信するときにメッセージの位置を提供し、(今からだけではなく)特定の位置からサブスクリプションを再開できるようにすることです。このようにして、サブスクライバーは正常に処理された最後のメッセージを追跡し、再開時にその位置から開始することができます。 EventStore がこれを行います。これは、サブスクライブ専用のデータベースであり、サブスクライブ可能なキューとしても機能します。

現在のキューがサブスクライバーに今後転送するメッセージのみを与えると仮定すると、メッセージが入ってくるときに(ファイルまたはデータベースなど)メッセージを格納する必要があります。サードパーティへのメッセージの送信に成功したら、最後に成功したものを(サードパーティごとに)記録する必要があります。これにより、遅延が大きくなったりクラッシュしたりした場合に、そこから再開できます。定期的に、すべてのサードパーティが処理した古いメッセージを削除したいと思います。

チェックポイント

メッセージの配信前または配信後に、チェックポイント(最後に正常に処理されたメッセージのID)を保存できます。

配信前にチェックポイントを保存することは、メッセージが配信されない可能性があるため、最大1回の配信と呼ばれます。たとえば、チェックポイントは保存されますが、配達前にコンピュータがクラッシュします。再起動時に、ロードされたチェックポイントはメッセージがすでに処理されており、次のメッセージをロードすることを示します。

メッセージを複数回配信することが可能であるため、配信後にチェックポイントを保存することは、少なくとも1回の配信と呼ばれます。例:メッセージは送信されますが、チェックポイントが保存される前にコンピューターがクラッシュします。再起動時に、チェックポイントは送信された同じメッセージを指しており、再送信されます。

少なくとも1回の配信(配信が成功した後にチェックポイントを保存する)は、メッセージが副作用を引き起こさない(つまり、べき等)限り安全です。たとえば、メッセージがCountIncreasedBy:5の場合、新しい値は古い値に依存するため、副作用があります。このメッセージを複数回処理すると、レシーバーの値が歪められます。ただし、メッセージにNewCountSetTo:37と表示されている場合は、その行を何回でも処理でき、常に同じ効果があります。

ただし、「少なくとも1回」では、有害メッセージを監視する必要もあります。これらは配信しようとすると常にクラッシュするメッセージであるため、これ以上先に進むことはできません。それらを監視するために何かを配置しない限り、それらは無限に再試行されます。

また、サードパーティが追いつくことができる状況がない場合(つまり、バーストトラフィックだけでなく、サードパーティを圧倒する平均トラフィックでもある場合)、ハードドライブで同じオーバーフローの問題が発生することにも注意してください。その時点で、オフラインの方法を使用するか、処理が大幅に遅れたらメッセージをスキップする必要があります。

1
Kasey Speakman

私が理解しているように、問題のシステムには3つのタイプの components があります。

                                         |
         ,----> [Message Translator] ----|---> [3rd Party Endpoint]
        /                                |
  [Queue] ----> [Message Translator] ----|---> [3rd Party Endpoint]
        \                                |
         `----> [Message Translator] ----|---> [3rd Party Endpoint]
                                         |

    [type] - component of type
    -----> - data flow
         | - internal/external component boundary
.

最初に頭に浮かぶのは、メッセージを保存してバッチで送信する メッセージトランスレータaggregators に置き換えることです。バッチデータは、高速(nosql)データベースに保存することも、要件で許可されている場合はフラットファイルに保存することもできます。サードパーティのエンドポイントで生データが必要な場合、それ以上のことはできません。一般的に、チェックアウト エンタープライズ統合パターン

Event Sourcing 手法(およびそれらに基づくすべてのデータベース)は、特にドメインオブジェクトとドメインイベント( ドメイン駆動設計 )の観点から問題を説明できる場合に役立ちます。

1