2012-05-14 3 views
13

イベントソーシングは、多くのもののボーナスとして賞賛されます。イベント履歴/監査証跡、完全かつ一貫性のあるビュー再生成などが可能です。私はファンです。しかし、これらは読込み側の実装の詳細なので、別のサブスクライバとしてイベント・ストアを読込み側に完全に移動することによっても同じことを達成できます。イベントストアを書き込み側にする理由は何ですか?

は、ここではいくつかの考えです:

  1. ビュー/自身がイベント・ストアを気にしないでくださいdenormalizers。彼らはドメインからのイベントを処理するだけです。
  2. イベント・ストアを読み取り側に移動すると、イベント履歴/監査が提供されます。
  3. イベント・ストアからビューを再生成することはできます。これを除いて、書込みモデルのリークである必要はありません。モデルシチズンシップを読む

ここでは、書き込み側でそれを維持するための1つの技術的な議論のようです。これはGreg Youngのhttp://codebetter.com/gregyoung/2010/02/20/why-use-event-sourcing/

です。ただし、現在の状態のスナップショットを保存しているものを使用することにはいくつかの問題があります。最大の問題は、データに2つのモデルを導入したことです。イベントモデルと現在の状態を表すモデルがあります。

私が興味深いのは、「スナップショット」という用語です。このスナップショットは、最近ではイベントソーシングにおいても顕著な用語となっています。書き込み側にイベント・ストアを導入すると、集約のロードに若干のオーバーヘッドが加わります。どのくらいのオーバーヘッドを議論することができますが、スナップショットから集約をロードするという概念と、スナップショット以降のすべてのイベントが存在するので、それは明らかに認識されている、または予期された問題です。だから今私たちは2つのモデルを持っています。それだけでなく、私が見てきたスナップショットの提案は、インフラストラクチャのリークとして実装されることを意図しています。

スナップショットが作成された後、スナップショットの前のイベントは、書き出しの観点からは100%になりません。ただし、読み込み側を再構築する場合は例外です。それは間違っているようだ。

別のパフォーマンス関連トピック:ファイルストレージ。時にはエンティティに大きなバイナリファイルを添付する必要があります。概念的には、これらはエンティティに関連付けられていることもありますが、エンティティであることもあります。これらをイベント・ストアに入れると、エンティティーをロードするたびに、そのデータを物理的にロードする必要があることを意味します。それは十分に悪いですが、数百または数百を大きな集合体で想像してください。私がこれまで見てきた答えはすべて、基本的に弾を噛んで、ファイルにuriを渡すことです。それは暴走であり、分散システムを弱体化させます。

次にメンテナンスがあります。ビューを再構築するには、イベントストアを含むプロセスが必要です。これで、今作成したビューの保守タスクは、イベント・ストアを使用して書き込みモデルをさらにバインドします。永遠に。

読み込みモデルと書き込みモデルのユースケースが基本的に両立しないというCQRSの要点はありませんか?では、なぜ読み込みモデルのものを書き込み側に置き、柔軟性とパフォーマンスを犠牲にして、それらを再度バックアップするべきなのでしょうか。なぜ時間を費やすのですか?

私は混乱しています。私が座っている場所からのすべての点で、イベントストアは、モデルの詳細を読み込んだものとして意味があります。イベント・ストアを維持することで多くの利点が得られますが、書き込み側の永続性を過度に抽象化せず、柔軟性とパフォーマンスを低下させる可能性があります。漏れやすい抽象化とメンテナンスのタスクによって、読み取り/書き込み側をバックアップしないでください。

だから誰かが私に説明してください1つ以上の説得力のある理由は、書き込み側にそれを維持する?あるいは、なぜそれがメンテナンス/報告の懸念事項として読者側に行かないべきか?再び、私は店の有用性に疑問を呈していない。ちょうど行くべきであるところ:

+2

イベントでのスナップショットは、「新しい概念」ではありません。これは、2006年のイベントソーシングに関する私の最初の話です。 –

答えて

4

私はこれが本当にすばらしい質問だと思う。あなたの集合体を一連のイベントとして扱うことは、書き込み側でそれ自体で便利なので、コマンドの再試行などを簡単にすることができます。しかし、私はそれがあなたのイベントを作成するために動揺しているように見えることに同意し、このスナップショットパフォーマンスの改善が必要な場合は、永続性のためのオブジェクトのさらに別のモデルを作成する必要があります。

集計ではスナップショットしか保存されていませんが、読み取りモデルへのイベント送信が読み取りモデルに送られるシステムでは、「イベントソーシング」ではなく「CQRS」と呼ばれると思います。あなたが再投影のためにイベントを周りに残していたなら、私はあなたが非常に両方のシステムを持っていたと思います。

しかし、の3つのの定義はありませんか? 1つは集約を維持するため、もう1つは状態の変更を伝えるためのものです。

このようなシステムでは、集計をロードして質問を直接行うことで、クエリに答えることが魅力的です。これは決して禁止されていませんが、スレッドやトランザクションを複雑にすることは言うまでもなく、そうでなければ必要のない機能を集約させる傾向があります。

+0

ありがとうございます。それは定義の数を増加させていない。 Event Sourcing + Snapshottingでは、実際には2つが1に組み込まれていることを覚えておいてください。集合体のEventStore + Snapshot、読み取りモデルのイベント、読み取り再開のためのEventStoreがあります。もう1つの方法は、集計のスナップショット、読取りモデルのイベント、および読込み再開のためのEventStoreです。 EventStore + Snapshotスプリットと同じです。 –

+0

「コマンドの再試行などを簡単にする」コメントを拡張できますか?つまり、書き込み側がイベントを維持している場合とそうでない場合の方が簡単です。 –

+0

また、最後の点として、依然として設計によって集約を照会できないと仮定しましょう。 IMOでは、イベントストアの選択はこの設計上の決定に影響しません。ご返信ありがとうございます。 –

0

イベントストアが書き込み側にある理由の1つは、イベントが「ファクト」になり、分散/ディスパッチされる前の並行性の問題を解決するためです。イベント・ストリームにコミットする際のオプティミスティック・ロックを使用します。こうすることで、書き込み側では、同じイベントストリーム(集約)への同時「コミット」が解決され、そのうちの1つが処理され、もう1つはイベントの比較や伝播によるスマートな方法で競合を解決する必要がありますクライアントと競合し、コマンドを拒否します。

+0

例を挙げてください。並行処理は、イベントストアなしでも処理できます。しかし、私はあなたが "イベントを比較する"という意味を正確に興味があります。なぜなら、それはイベントを格納せずには処理できないように思えるからです。実際にイベントで簡単に実装できるスマートな解決策がありますか? –

+0

@JeremyRosenberg私は、ここでローマンが何を得ているのかというと、各イベントは一般的に、その集約の現在のバージョンを示す「バージョン」プロパティを維持するべきです。したがって、書き込み側では、イベントが実際にコミットされる前に、* actual *集約バージョン(ストリームの最後のイベントバージョン)と予想される集約バージョンに基づいて、楽観的同時実行性チェックを実行できます。このアプローチでは、分散システムの問題が解決され、集約が古くなる、つまりイベントが中間でコミットされる可能性があります。 – James

10

これは誰かが私に指摘した長い死んだ質問です。書き込み面にイベントを格納する方が良い理由はいくつかあります。

私が理解していることは、あなたが話しているアーキテクチャは、私が見ている非常に一般的なものです...失敗します。リレーショナルデータベースにドメインモデルを格納し、イベントを出力します。イベントストアにある読み取り側にイベントを保存しているものを追加します。これはおそらく混乱につながるでしょう。

最初に実行する問題は、イベントを公開することです。データベースに保存してMSMQと言うために公開するとどうなりますか(私は途中で死ぬ)。だからDTCはそれらの間に導入されます。これは巨大なもので、分散トランザクションは疫病のように避けるべきです。私はおそらくデータを2回(データベースに1回キューイングするために)2回データにするので、非常に非効率的です。これにより、システムのスループットが大幅に制限されます(200〜300メッセージ/秒のDTCベンチマークが一般的です。イベントは20〜30k /秒しかありません)。

DTCの必要性を回避するには、データベースにイベントを持ち、キューとして動作するテーブルを配置する方法があります。これはDTCの必要性を回避しますが、これは引き続き次の問題になります。

バグがあるとどうなりますか?私はあなたがバグのコードを書くことは決してないだろうが、Jrs /メンテナンスの開発者の一人がプロジェクトで後で作業することを知っている。例として、ドメインオブジェクトが変更され、発生したイベントが一致しない場合はどうなりますか?ドメインオブジェクトのStateを "LA"(ハードコード)に設定したが、イベントのStateをcmd.State( "CT")に正しく設定したとします。

このようなエラーはどのように検出されますか?今話題にされている最大の問題は、書き込み側のデータベースと出てくるイベントストリームの2つの "真実"のソースがあることです。それらが同等であることを証明する方法はありません。これにより、あらゆる種類の奇妙なバグが発生します。

+2

**真実の**単一のソース**を持つ引数は、イベントソース(IMO)の主要ポイントであり、イベントストアを書き込み側に維持する必要があります。 –

関連する問題