イベント ソーシングについて考えていると、鶏が先か卵が先かという問題にたどり着くことがよくあります。これを回避する方法についてのいくつかのヒントに感謝します。
すべての I/O バウンド処理を非同期で実行する (つまり、イベント ログへの書き込み) 場合、どのように処理するか、場合によっては障害を検出するか?
私は Akka Actors を使用しているので、イベント/メッセージごとに処理が順次行われます。現時点ではデータベースはありません。代わりに、すべてのイベントをイベント ログに保持し、メモリに格納されたモデルにすべてのイベントの集約状態を保持します。クエリはすべてこのモデルに反しており、キャッシュと見なすことができます。
例
新しいユーザーの作成:
- ユーザーがモデルに存在しないことを検証する
- イベントをジャーナルに永続化する
- モデルの更新 (メモリ内)
ステップ 3 が中断された場合でも、イベントを保持しているので、後で再生できます。ステップ 2 が壊れた場合は、それも適切に処理できます。
これは問題ありませんが、ステップ 2 は I/O バウンドであるため、別のアクターで I/O を実行して、最初のアクターをクエリ用に解放する必要があると考えました。
クエリを許可しながらユーザーを更新する (A0 = フロント エンド/GUI アクター、A1 = プロセッサ アクター、A2 = IO アクター、E = イベント バス)。
- (A0->E->A1) ユーザー 'U1' を更新するイベントが発行されます。ユーザー「U1」がモデルに存在することを検証します
- (A1->A2) イベントをジャーナルに永続化 (別のアクター)
- (A0->E->A1->A0) ユーザー 'U1' プロファイルのクエリ
- (A2->A1) イベントが永続化され、モデルの更新を続行
- (A0->E->A1->A0) ユーザー 'U1' プロファイルのクエリ (新しいデータが返されるようになりました)
I/O が独自のペースで変化している間にクエリを処理できるため、これは魅力的です。
しかし、イベントを永続化する前に検証を行っているため、互換性のない 2 つのコマンド (削除してから更新) がイベント ログに永続化され、後で再生するとクラッシュする可能性があるという、あらゆる種類の問題を自分自身で引き起こす可能性があります。その後、モデルを更新します。
私の目的は、(アクターがメッセージをシングル スレッドで順次処理するため) モデルについて単純な推論を行うことですが、クエリ時に I/O バウンドの更新を待機しないようにすることです。データベースをモデリングしているように感じますが、それ自体が問題になる可能性があります。
不明な点がある場合は、コメントを書いてください。