web-dev-qa-db-ja.com

イベントソーシングは、書き込みがまれな場合のみですか?

私はイベントソーシングについて読んでいて、書き込みが非常にまれであるか、軍事レベルの監査が必要なエキゾチックな状況でのみ意味があるかどうかを自問するのを止めることはできません。

重要な使用法がある例外的なシステムでは、1日あたり数百から数千の書き込みが発生する可能性があり、たとえば、1年間の操作で100万回または2回の書き込み(イベント)に変換されます。現在の状態を取得するためだけに数百万のオブジェクト(イベント)をマージすることは、従来のストレージからのまっすぐな読み取りと比較すると、ばかげた命題のように聞こえます。それでも、イベントソーシングは最もパフォーマンスの高いシステムの一部です(LMAXと考えてください)。

それで、私は何が欠けていますか?イベントストリームからの状態の復元は一般的に行われていますか?または、これを行う必要はほとんどなく、代わりにnormal操作(つまり、CQRSからのクエリストレージを使用)に別のストレージを使用し、exceptionalでのみイベントから復元するという考えです=ケース(レプリケーション、監査など)?

9
kaqqao

それで、私は何が欠けていますか?

推測してください。

不足している可能性がある最初のことは、再構築している状態のイベントをリロードするだけでよいということです。トランザクション境界を明確にモデル化できる場合、各オブジェクトは独自のIDでタグ付けされたイベントを書き出し、それらのイベントのみを読み戻すことができます。イベントの保存にリレーショナルデータベースを使用すると、クエリを高速化するためのインデックス付きID列が存在します。 EventStoreを使用すると、各オブジェクトに独自のストリームがあります。

各トランザクションで単一のオブジェクトのみを変更していることを確認したいので、モデルでこれをきれいに行うにはいくつかの注意が必要です。したがって、試行している各不変条件を正しく分離していることに注意する必要があります。実施する。

それでも十分に速くない場合でも、状態のスナップショット(メモ)を作成し、それを「従来のストレージ」に保持する可能性があります。各スナップショットには、スナップショットの作成に使用された最後のイベントのシーケンス番号がタグ付けされます。リロード時に、リポジトリは最初にそのスナップショットを取得してから、新しいイベントを適用します。 (これは、最新のスナップショットを取得するための妥当な方法を意味します。イベントにもシーケンス番号のタグが付けられているか、開始点に到達するまでイベントストリームを逆方向に読み取る効率的な方法があります。)

スナップショットは、マージするのではなく、書き込みと並行して構築できるという点で、ここで通常のアプローチよりもまだ利点があります。イベントリスナーを他のスレッド/プロセスに配置し、書き込みに合わせて楽しませるだけです。妥当なスケジュールでスナップショットストアに移動します。結局のところ、スナップショットは特にタイムリーである必要はありません-新しいイベントを再適用する作業がSLAに影響を与えないほど頻繁に。

(スナップショットは移行を複雑にします。モデルのシリアル化に変更を加えると、スナップショットキャッシュが無効になります。もちろん、移行の一部として新しいシリアル化を使用してスナップショットを再構築し、変更が有効になったときに「追いつく」ことができます。)

イベントストリームからの状態の復元は一般的に行われていますか?

はい、そうです。 CQRSの例で通常表示されるのは、アプリケーションレイヤーが、送信されたコマンドが適切に形成されていることを確認した後、リポジトリからドメインオブジェクトをロードします。ロードはデフォルトコンストラクターで、その後にイベントストリームが再生されます。 (または同等に、イベントのリストを持つファクトリーへの呼び出し)。

他の2つの矛盾した考え。

  1. リポジトリインターフェースの背後にキャッシュがある可能性があります
  2. キャッシュの無効化は、2つの難しい問題の1つです。
6
VoiceOfUnreason