楽水

人々の創造が自由に表現できる舞台づくり

未分類

イベントソーシングとは

投稿日:

ここでは、イベントソーシングについて次の観点で説明します。

イベントソーシングとは

イベントソーシング(Event Sourcing)とは、データの状態を直接保存するのではなく、システム内で発生した全てのイベントを記録する設計アプローチです。
通常のシステムの場合、ユーザーや他のシステムがシステムを操作することで、システムがデータを処理して、その状態をデータストアに記録します。
なので、状態管理のシステムの場合、データのある時点の状態を記録し管理します。
それに対して、イベントソーシング(Event Sourcing)の場合、ユーザーや他のシステムがシステム対して行った操作をイベントとして記録します。
なので、イベントを管理するシステム(イベントソーシング)の場合、データの状態遷移の過程を記録し管理するので、必要に応じて特定の時点の状態を再構築(再現)することができます。

イベントソーシングのメリットとデメリット

次に、イベントソーシングのメリットとデメリットを状態管理のシステムと比較しながら見ていきましょう。

イベントソーシングのメリット

  • 独立性の向上
    状態管理のシステムを参照するシステムは、特定の時点の状態に依存するのでリアルタイムに同期をとる必要があり、システム間を密結合にします。
    一方、イベント管理のシステムを参照するシステムは、特定の時点の状態に依存せず、イベントのリストさえ取得できれば、必要に応じて(非同期で)特定の時点の状態を再構築することができるので、システム間の依存度を下げ、システムの独立性を上げることができます。
    例えば、在庫管理システムがデータストアの場合、最新の時点の状態しか取得できません(特定の時点に依存)が、イベントストアの場合、イベントリストを取得できればいつの時点の状態でも取得することができます(特定の時点に非依存)。
  • 拡張性の向上
    イベントはログとして保存されるため、特定の状態を管理するノードが複数に分散されていても、イベントのリストさえあれば、どのノードでも状態を再現できます。これにより、トラフィックが増加した場合や、データ量が増えた場合でも、複数のサーバーにワークロードを分散してスケールアウトが可能です。
    一方、状態管理のシステムを拡張する場合、拡張したすべてのシステムで同一の状態を保つことは困難です。
    さらに、そのシステムを参照しているシステムがある場合、拡張したシステムのどれをアクセスしても一貫して同じ状態を返すようにすることも困難です。
  • 可用性の向上
    高可用性は、システムが障害時にもダウンタイムを最小限に抑えつつ動作を継続できる能力です。
    イベントストアは複数のノードにレプリケーション可能です。万が一、あるノードがダウンしても他のノードがイベントを保持しているため、すぐに別のノードにフェイルオーバーし、高可用性を保つことができます。
    一方、状態管理のシステムの場合、複数のシステムで同じ状態を保つことが困難なので、単一障害点になりやすくなります。
  • 追跡可能性の向上
    イベント管理のシステムは、状態遷移の過程を記録し管理するので、必要に応じて特定の時点の状態を再構築(再現)することができます。
    なので、過去の状態遷移の過程を追跡することができ、次のような効果を得ることができます。

    • 監査とコンプライアンス
      金融業界や医療業界など、厳格な規制が存在する分野では、データの変更履歴をすべて追跡・保存する必要があります。
      監査の際に、ある取引や医療記録がどのように変更され、誰がいつそれを行ったのかを正確に再現することができます。
      例えば、ある口座の残高が特定の日時にどのように変更されたのかを確認し、その正当性を証明するために過去の状態を再現できます。
    • デバッグとエラー解析
      ある問題が発生した時点のシステム状態を再現することで、どのイベントが原因でエラーが発生したのかを突き止めることができます。
      例えば、特定の顧客の注文がなぜ誤処理されたのかを再現し、エラーの原因を特定するために、当時のイベントシーケンスを確認します。
    • ビジネスプロセスの検証・分析
      ある注文がどの時点で承認され、どのタイミングで出荷指示が出され、その後どのように顧客に届いたか、という一連のプロセスをイベントを使って再現することで、業務フローを振り返り改善点を見つけることができます。
    • ユーザートラッキングと行動解析
      ユーザーがどのような操作を行った結果、特定の商品をカートに入れ、購入を完了したのかというユーザーの操作履歴を再現し行動を解析をすることができます。
    • 予測モデルの精度向上
      予測モデルを訓練するために、特定の時間範囲のデータが必要な場合があります。
      イベントソーシングではその期間内の状態遷移を正確に再現できるためより精度の高い予測モデルを構築することができます。

イベントソーシングのデメリット

  • 複雑性の増大
    すべての状態変化をイベントとして管理するため、システムの設計と実装が複雑になります。イベントストアの管理、イベントの再生、イベントバージョン管理など、従来のCRUDアプローチよりも多くの考慮事項が必要です。
  • データの整合性
    イベントが非同期に処理される場合、データの最終的な整合性(Eventual Consistency)を前提とすることが多くなり、即時整合性が求められる場合には適さないことがあります。
  • ストレージの膨張
    すべてのイベントを保存するため、ストレージが膨大になる可能性があります。データが長期間に渡る場合や頻繁に更新されるシステムでは、ストレージコストが増大します。
  • イベントの再生に時間がかかる
    特定の時点の状態を再現するには、イベントの再生が必要です。イベント数が増加すると、この再生プロセスに時間がかかる可能性があり、特に起動時やリカバリ時にパフォーマンスに影響を与えることがあります。
  • イベントスキーマの進化
    時間の経過とともにイベントスキーマが進化する必要がありますが、古いイベントと新しいイベントが混在する可能性があり、スキーマの互換性やマイグレーションが課題となります。
    例えば、顧客注文のイベントに新しいフィールド(例えば「割引情報」)が追加される場合があります。
    古いスキーマ: 割引情報がない注文イベント
    新しいスキーマ: 割引情報を含む注文イベント

CQRSとイベントソーシング

コマンド・クエリ責務分離(CQRS)パターン

のコマンド処理側にイベントソーシングを適用すると、そのメリットを活かすことができるので効果的です。

クエリ処理では、コマンド処理からイベントを非同期で受け取り、クエリに必要なある時点のスナップショットを作成するようにします。
イベントソーシングを介したシステム間連携は、CQRSだけでなく、バッチ処理にも適用することができます。
次の図は、サービスイベントを管理するイベントソーシングのシステムから、サービスイベントを受け取った料金計算システムが、料金計算に必要なワークデータを作成し、それに基づいて料金計算を行い結果をイベントストアに記録するという例です。

料金計算システムに記録された料金卦算結果イベントは、請求管理システムの請求書発行に利用されます。
なお、マイクロサービスアーキテクチャを適用すると、各システムがサービス管理サービス、料金計算サービスというマイクロサービスになります。


DDDとイベントソーシング

ヴォーン・ヴァーノンの実践ドメイン駆動設計という書籍では、ドメイン駆動設計(DDD)の構成要素である集約ごとにイベントストアを設け、イベントソーシングを実現することを推奨しています。
また、Sam Newmanのマイクロサービスアーキテクチャという書籍では、DDDの集約ごとにマイクロサービスを設けることにより、マイクロサービスの一貫性を保ちやすく、依存関係を最小限にできると説明しています。
集約は、ドメインオブジェクトのライフサイクルを管理する単位であるので、この単位にコマンド処理のマイクロサービスを設け、イベントソーシングによって集約のイベントを管理することで、イベントソーシングのメリットである独立性、拡張性、可用性などを高めることができます。

なお、集約の状態を変化させる操作など、特定のドメインにおける重要な出来事のことをドメインイベントといいます。
複数のマイクロサービスを跨いだ分散トランザクションは、Sagaによって管理することができます。

ハイブリッドアーキテクチャ

通常、イベントソーシングを採用すると、システムの状態はイベントの履歴を再生することで再構築できます。しかし、すべての状態をイベントのリプレイによって復元するのは、パフォーマンスの観点で非効率な場合があります。そのため、状態管理DBとイベントストアを併用することが考えられます。
これを、イベントソーシングと状態管理のハイブリッドアーキテクチャといいます。
ここでは、ハイブリッドアーキテクチャについて次の観点で説明します。

イベントストアと状態管理DBの併用の目的

イベントストアと状態管理DBの併用の目的は以下です。

  1. 状態のクエリを高速化するため
    問題点
    イベントストアは、すべてのイベントを時系列で保持するため、ある時点の最新状態を取得するには、すべてのイベントをリプレイしなければなりません。これには時間がかかるため、リアルタイム性が求められるクエリには向いていません。
    解決策
    最新の状態をキャッシュまたはデータベース(状態管理DB)に保存し、クエリを高速化する。
  2. システムのリカバリーを高速化するため
    問題点
    システムが再起動した際、イベントストアの全履歴をリプレイして最新の状態を再構築するのは時間がかかります。
    解決策
    スナップショット(状態のスナップショット)を定期的に状態管理DBに保存し、システム復旧時にはそこから再開できるようにする。
  3. 他のシステムとの統合を簡単にするため
    問題点
    他のシステムが状態を取得したい場合、イベントストアからイベントをリプレイして現在の状態を復元するのは手間がかかる。
    解決策
    状態管理DBを用意し、そこから最新のデータを取得できるようにすることで、外部システムとの統合を容易にする。

ハイブリッドアーキテクチャの実現方法

このような運用を行う場合、イベントストアと状態管理DBの両方を管理するアーキテクチャを設計することになります。一般的には、以下のような流れになります。

  1. イベントの発生
    コマンドを受け取ると、状態を変更するのではなく、イベントを生成し、イベントストアに記録する。
  2. 状態の更新
    イベントが記録されたら、そのイベントに基づいて状態管理DBを更新する。
    例えば、「注文作成イベント」が発生したら、そのイベントに基づいて「注文の最新状態」を状態管理DBに書き込む。
  3. クエリの処理
    最新の状態を取得する場合は、状態管理DBを参照する。
    高頻度なクエリ処理は状態管理DBにオフロードし、イベントストアの負荷を減らす。
  4. 状態の再構築
    必要に応じて、状態管理DBのデータが壊れた場合やリプレイが必要な場合は、イベントストアのイベントをリプレイして最新の状態を復元する。

ハイブリッドアーキテクチャのメリットとデメリット

メリット

  • パフォーマンスの向上
    クエリを状態管理DBから取得することで、イベントストアのリプレイを毎回実行する必要がなくなり、レスポンスが高速化する。
  • システムのリカバリーが高速
    スナップショットを保存しておけば、障害発生時にイベントをリプレイせずに復旧できる。
  • 外部システムとの統合が容易
    状態管理DBを提供することで、外部システムがイベントソーシングの仕組みを理解しなくても簡単にデータを取得できる。
  • イベント履歴を利用した分析が可能
    状態管理DBとは別にイベントストアを保持することで、過去の状態の再現やビジネス分析に活用できる。

デメリット

  • システムが複雑になる
    2つのDB(イベントストア + 状態管理DB)を管理する必要があり、データの一貫性を保つ仕組みが必要になる。
  • 状態管理DBがイベントとズレる可能性
    イベントストアと状態管理DBのデータが同期されないと、イベント履歴と状態が一致しなくなる可能性があるため、整合性を維持する仕組み(例: イベントを適用するワーカーやジョブ管理)が必要。
  • ストレージコストが増える
    イベントストア + 状態管理DB の両方を保持するため、データの保存コストが増加する可能性がある。

ハイブリッドアーキテクチャの採用例

次のようなハイブリッド運用は、イベントソーシングとCQRS(Command Query Responsibility Segregation)を組み合わせるケースでよく使われます。

  1. eコマース(注文管理)
    注文の変更履歴をイベントストアに保存し、各注文の最新の状態をRDBにキャッシュする。
    ユーザーの画面や外部APIはRDBから最新のデータを取得し、過去の履歴やリプレイはイベントストアを使う。
  2. 銀行や金融システム
    取引の履歴をイベントストアに保存し、現在の口座残高をRDBにキャッシュすることで、最新の残高を素早く取得しつつ、過去の取引を追跡できるようにする。
  3. IoT(センサーデータ管理)
    IoTデバイスから送られてくるデータをすべてイベントストアに保存し、最新の状態だけを別のDBに保存して、ダッシュボードなどでリアルタイムデータを高速に取得できるようにする。

履歴管理の必要性

ここでは、DBの現在の状態に至る過程(イベント)の履歴を持たせる必要がある業務の特徴について説明します。
DBの現在の状態だけではなく、その状態に至るまでの過程(イベント履歴)を保持する必要がある業務には、以下のような特徴があります。

監査証跡(Audit Trail)が必要な業務

監査証跡を確保することで、不正防止・法令遵守(コンプライアンス)・データ改ざん防止を実現することができます。
特徴

  • 過去にどのような変更が行われたのかを正確に再現できる必要がある。
  • 誰が・いつ・何を・どのように変更したのかを記録する必要がある。
  • 法規制・コンプライアンスの要件を満たす必要がある。

業務例

  • 金融・銀行業務
    口座の取引履歴(入出金、送金、手数料の発生など)
    投資商品の売買履歴
    ローンの支払いや残高の変動
  • 医療・ヘルスケア業務
    患者の診療記録の変更履歴(診断内容、投薬変更など)
    医療機器の使用履歴(いつ・どの患者に使用されたか)
  • 政府・法務・公共機関
    許認可の申請と審査プロセスの履歴
    裁判記録や判決の履歴
    税務申告・修正履歴
  • ERP(企業資源計画)
    発注、支払い、在庫の変更履歴
    予算管理や会計データの変更履歴

長期間の履歴を活用した分析が必要な業務

過去のデータを分析することで、将来のトレンド予測・改善施策の立案・異常検知が可能になります。
特徴

  • 過去のデータの変化を分析する必要がある(単なる最新の状態では不十分)。
  • 業務の改善や予測モデルに、過去の変更データが役立つ。

業務例

  • マーケティング・顧客行動分析
    ECサイトのカート履歴や購入履歴の変化
    ユーザーのアクセス履歴、ページ滞在時間、クリック履歴
  • IoT・センサー管理
    温度や湿度の変動履歴(工場や物流の品質管理)
    スマートメーターの電力使用履歴
  • SCM(サプライチェーン・マネジメント)
    商品の物流・在庫の変動履歴
    需要予測のための販売データの変化

状態が頻繁に変化し、過去の状態が業務の意思決定に影響を与える業務

契約変更や給与計算では、「ある時点の状態」が業務の判断基準となるため、変更履歴が必須です。
特徴

  • データの状態が頻繁に変わるため、過去の状態を再現する必要がある。
  • 過去の状態に基づいて意思決定を行う必要がある。

業務例

  • 契約管理(長期間有効な契約の変更履歴)
    保険契約の内容変更(補償範囲の変更、契約者の変更)
    通信プランの契約変更(料金プランの変更、オプション追加)
  • 人事・給与管理
    従業員の給与履歴(昇給・降給・手当の追加)
    人事評価の履歴(過去の評価データ)
  • 価格変動の履歴を追う業務
    株式・仮想通貨の価格変動履歴
    不動産の価格変動履歴

イベントの順序や影響関係が重要な業務

イベントの順序が不明確だと、データの整合性や一貫性が保てなくなるため必要です。
特徴

  • あるイベントの発生順序が重要であり、それによって処理の結果が変わる。
  • イベントの順序を正しく保持しないと、一貫性が失われる。

業務例

  • 注文処理・在庫管理
    どのタイミングで注文が確定し、出荷されたのか
    返品が発生した場合、いつの注文に紐づくのか
  • 製造業・プロジェクト管理
    生産プロセスの履歴(いつ・どの工程で作業が行われたか)
    プロジェクトの変更履歴(仕様変更、納期変更)
  • トランザクション管理(分散システム)
    分散データベースの整合性管理(例えば、分散トランザクションが失敗した場合のロールバック処理)

過去の状態を再現する必要がある業務

過去の状態を特定できないと、不正行為の特定、バグの修正、障害対応が困難になるため必要です。
特徴

  • 過去の状態を特定の時点で再現できる必要がある。
  • 障害発生時に、過去の状態を復元して問題を調査できる必要がある。

業務例

  • 金融取引のリカバリー
    特定の時点の株価や取引状態を復元し、不正取引や障害の影響を分析
  • ソフトウェア開発・バージョン管理
    変更履歴を元に、過去のコードの状態を復元できるようにする(GitやCI/CDのデプロイ履歴)
  • ゲームのセーブデータ管理
    プレイヤーの過去の状態を復元し、ゲーム進行の問題を解決

イベントソーシングのアプリケーションアーキテクチャ

以上を鑑みて、イベントソーシングの設計思想を次のように考えるとよいかと思います。

  • フロー系データ(注文・発注・契約)をイベントストアに記録し、CQRSで最新データを管理
    • イベントストアのメリット
      • 行動分析に役立つ
        例: 「契約交渉にどのくらいの時間がかかっているか」「注文のどのステップでキャンセルが多いか」などを分析できる。
        フローの各ステップをイベントとして記録することで、顧客の行動パターンを可視化できる。
      • 内部統制の強化
        例: 契約の変更履歴(誰が、いつ、どんな変更をしたか)が保証される。
        イベントの記録を通じて、契約の実在性や、注文・発注の正当性を証明できる。
    • CQRSで最新データを別途管理
      フロー系データは、通常の業務ロジックでは「最新の状態」だけを参照することが多い(例: 現在の契約内容、注文状況)。
      クエリ側に最新データを保持することで、パフォーマンスの最適化が可能。
      イベントストアから直接データを集計すると負荷がかかるため、CQRSのアプローチは非常に適切。
  • ストック系データ(在庫・売掛金)もイベントストアに記録し、CQRSで最新データを管理
    • イベントストアを使う理由
      • データの改ざん防止・内部統制の強化
        例: 在庫の不正な調整が発生した場合に、すべての変更履歴が残るため、問題の追跡が可能。
        売掛金の変更(請求→入金→消込)の履歴がすべて記録され、監査対応が容易。
      • 過去の時点のデータ復元が容易
        例: 「1か月前の在庫状態を再現する」などの要求に対応しやすい。
        もし「最新のデータだけ」しか保持しないと、過去の状況を知ることが困難になる。
    • CQRSの適用で、最新データをクエリ側に保存
      ストックデータは「現在の在庫数」「現在の売掛金」など最新の値を頻繁に参照する。
      イベントストアだけでは最新のデータ取得に手間がかかるため、クエリ側で「現在の状態」を保存することでパフォーマンスを向上。
  • マスタデータ(顧客・商品)は、履歴が必要な場合のみイベントストアを利用
    • イベントストアが必要なケース
      • 過去の名義や住所を保持する必要がある場合
        例: 「契約締結時点の顧客の住所」「過去にどの名義で取引していたか」などを参照する必要がある場合。
      • 商品価格の変更履歴が重要な場合
        例: 過去の請求や売上分析において「当時の価格での取引履歴」が必要な場合。
    • 最新データのみ保持するケース
      過去情報が不要な場合
      例: 「顧客の最新の住所だけ分かればいい」「商品マスタは最新価格だけを参照すればいい」という場合は、通常のデータストアで管理すれば十分。

-未分類

執筆者:


  1. […] ;マンド処理のマイクロサービスにイベントソーシングを適用します。 […]

関連記事

アプリケーション品質を上げるための開発方法

ここでは、次のソリューシ&#12 …

変化に強いシステムを創る

ここでは、環境の変化に柔&#36 …

アプリケーションアーキテクチャの設計方法

今回は、アプリケーション&#12 …

DevOpsとは

今回は、DevOpsについて次の観&#2885 …

テクノロジーアーキテクチャの設計方法

今回は、テクノロジーアー&#12 …