5

サーバー ソフトウェア内部の信頼できるキューイング メカニズムとしてEventStoreを評価しようとしています。

MSMQ は、メッセージの「会話」内の部分的な順序付け、順序付けられたメッセージをサポートできないため、代替として失敗します。また、メッセージ サイズの制限が 4MB であるため (これは部分的な順序付けで克服できます)。SQL Service Broker は部分的な順序付けをサポートしていますが、プログラムでセットアップして管理するのは面倒です。

EventStore に関するドキュメントは確かにまばらなので、EventStore の経験のある人は次のことを手伝ってくれますか?

  • EventStore はイベントのトランザクション処理をサポートしていますか? つまり、処理が失敗した場合、デキューをロールバックできますか?
  • さまざまなスレッド、プロセス、またはマシンに複数のリーダーがある場合、EventStore は、各イベントが (一度に、おそらくトランザクション中に) 1 つのリーダーにのみディスパッチ (?) されるように強制します。
  • 上記が可能であると仮定すると、異なる「会話」のイベントを任意の順序で同時に読み取ることができますが、同じ会話のメッセージは個別に順番に読むことができますか?
  • EventStore は基本的に「少なくとも 1 回」の配信であると読みました。特定のストレージ プロバイダーを使用して、「1 回だけ」の配信を保証することは可能ですか?
  • 「毒」イベントはどのように処理されますか? 処理中にエラーになるイベント。おそらく、エラーは本質的に一時的なものであり、再試行できます。おそらく、それは本質的に永続的であり、管理者の介入が必要です。
  • 必要に応じて EventStore ストレージを手動で操作できますか? 他の読者が読み続けている間にそれを行うことはできますか?

(ストレージ エンジンでのトランザクションは必須ではないことを読みましたが、私はまだトランザクションの言語を使用して、EventStore レベルでのトランザクションを置き換えるものを意味します。トランザクションからあらゆるものへの切り替えで重大な機能上の結果がある場合は、それらについてコメントしてください。 . すぐにすべての側面を理解する必要はありません. 実験するためにより多くの時間を稼ぐための希望が必要です.)

4

2 に答える 2

4

EventStoreは、本格的なキューを構築するために使用される可能性がありますが、それを念頭に置いて設計されたことはありません。これは、あなたの質問によって課せられたまさにその要件に反する、ライブラリの構築に向けられた多くの意見のある決定があることを意味します。

たとえば、1回限りの配信の概念は、メッセージングシステムが実際にはサポートしていないものです。毒メッセージのような上記の他のものは、EventStoreがそのようにメッセージパイプラインにフックされていないため、実際には問題ではありません。

あなたが解決しようとしている問題は、EventStoreがあなたを助けることができる問題ではないようです。したがって、RabbitMQなどの本格的なメッセージキューを評価することをお勧めします。

また、メッセージを4MBより大きくするものは何ですか?ファイルや大きなバイナリストリームをプッシュしている場合は、それらをある種の高可用性「グローバル」ストレージ(Amazon S3など)にプッシュしてから、メッセージにそれらへのポインターを設定してみませんか?

于 2011-11-22T04:06:02.160 に答える
4

最初の答えに満足しているように見えますが、いくつかの考えがあります。

  • メッセージの因果関係を追跡すると、部分的な順序付けが発生します。これを行う方法があります。それを行う単純な方法は、特定のメッセージが見た分散ネットワーク内のすべてのノードのリストを保持し、メッセージを押し込むときにそのリストに追加することです。私はメッセージと言いましたが、実際にはその会話のメッセージを参照しています。

    これは単純なシステムではうまく機能するかもしれませんが、より複雑なシステムを使用し始めると、どのメッセージが何を意味するかを正確に追跡するために Saga が必要になる場合があります。

    それでも、単一の受信者ノードで部分的な順序付けが必要な場合があります。その場合、サガ、メッセージ フローに関してハブ アンド スポーク パターンでは役に立ちません。次に、使用しているトランスポートにロジックを実際に追加する必要があるかもしれません。

    1 つのアルゴリズムはベクトル クロックと呼ばれ、別の同様のものはバージョン ベクトルと呼ばれます。Goでのベクトル クロックの実装例を次に示します。ペアリングに数時間を費やしたい場合は、F# 用の小さなベクトル クロック ライブラリに取り組んでいます。なぜなら、アルゴは実際には非常に単純だからです。これについて意味のあるものを実際に読みたい場合は、この本をお勧めします - Elements of Distributed Systems。チャプター2-3、5がいいです。

    次に、分散システムで会話の部分的な順序を取得します。キューでこれを取得できない理由は、キューとノードの間にネットワークの湾があり、キューと同じノード上のノードまたはプロセスのいずれかがメッセージを持っているためにダウンした場合です。転送中、このメッセージは再度キューに入れられ、並べ替えられます。メッセージを NACK した場合も同じです。この並べ替えの問題は、キューと消費クライアントで 2PC を使用することで回避できます。または、メッセージをベクター クロックで並べ替えるか、発行/送信アプリケーションで指定されたシーケンス ID で並べ替えることができます。消費者の観点から意味的に意味があるため、一部のデータでそれらを並べ替えることができます。選択はあなた次第です。

  • 有害なメッセージなど、その他の要件については、サービス バスが提供するものを確認する必要があります。私は個人的に MassTransit を使用しており、有害なメッセージを適切に処理します。これらは、メッセージを消費する際のいくつかの失敗モードです。

    • シリアル化エラー - プログラミングに誤りがあります。これらは発生してはならないため、開発プロセスを修正してください。それでも発生する場合は、それらをポイズン キューに移動してください。これらのメッセージは破損している可能性があります。
    • コードからの未処理の例外 - プログラミングに誤りがあります。繰り返しますが、開発プロセスは検査の対象です。サービス バス ランタイムがメッセージをポイズン キューに移動できるようにするためにスローしない限り。
    • ローカル コンシューマーの DB への書き込みで問題が発生する場合があります。これは操作上の問題であり、コードでは発生しないはずです。現在、コードから実際に何もできないため、プロセスを強制終了します。Naigos やその他のプロセス モニターは、何かがダウンしており、緊急に修正する必要があることを運用担当者に通知する必要があります。読み取りモデルに書き込むことができない場合、おそらく読み取りモデルはそのための要求を処理できないためです。Puppet またはその他のプロセス モニターは、おそらくしばらくしてからプロセスを再起動し、すべて問題ないと仮定して同じ手順を実行できますが、今回は、データベースに接続するまでキューから消費を開始しないでください。 (これは、NHibernate が開始時に静的初期化で行うことです。
  • 大規模なイベント - キュー API のチャンクが長すぎるバイト配列であることを確認してください。ZeroMQ にはマルチパート メッセージがあります。AMQP/RabbitMQ はそうではないので、もちろん、それらを自分でチャンクする必要があり、それらを再注文する必要があります。または、私たちと同じように、ビットのバイナリ ブロブのハンドルをどこかから読み取れるようにすることもできます。

于 2012-01-20T09:19:20.100 に答える