目次を表示する

Event Sourcing 深掘り ── 経緯・必須要素・デファクトツール・実践と落とし穴

Event Sourcing が生まれるまで ── 複式簿記・Fowler・Greg Young

Event Sourcing が生まれるまで ── 複式簿記・Fowler・Greg Young

「Event Sourcing は新しい技術なのか、古い技術なのか」という問いに、一言で答えるのは難しい。用語が定着したのは2005年だが、思想の根は500年以上前に遡る。系譜を辿ると、Event Sourcing が「アーキテクトが発明したパターン」というより「現実の業務処理が長年取ってきた形を、ソフトウェアの語彙に翻訳したもの」だと分かる。

この章では、その合流点を時代順に辿る。なぜ Event Sourcing がこういう形をしているのか、その答えは歴史にある。


1. 1494年:複式簿記という原型

Event Sourcing の最も古い祖先は、1494年にイタリアの数学者 Luca Pacioli(ルカ・パチョーリ)が著書 Summa de arithmetica で体系化した 複式簿記(double-entry bookkeeping) だ。

複式簿記の本質は、現代のソフトウェア用語で言うとこうなる。

1. 帳簿には「取引(transaction)」を時系列で追記していく
2. 過去の記帳は決して書き換えない(誤りは「逆仕訳」で訂正する)
3. 「現在の残高」は、帳簿を最初から累計することで導出される

これは Event Sourcing そのものだ。

graph LR
    subgraph dee["複式簿記(1494年〜)"]
        D1["取引<br/>(journal entry)"]
        D2["帳簿<br/>(journal)"]
        D3["残高<br/>(balance)"]
        D4["試算表<br/>(trial balance)"]
        D5["逆仕訳<br/>(reversing entry)"]
    end

    subgraph es["Event Sourcing(2005年〜)"]
        E1["ドメインイベント"]
        E2["イベントストリーム"]
        E3["集約の現在状態"]
        E4["プロジェクション"]
        E5["補償イベント"]
    end

    D1 -.同じ役割.-> E1
    D2 -.同じ役割.-> E2
    D3 -.同じ役割.-> E3
    D4 -.同じ役割.-> E4
    D5 -.同じ役割.-> E5

    style dee fill:#fff8e1,stroke:#f9a825
    style es fill:#e3f2fd,stroke:#1976d2

なぜ複式簿記は「現在の残高だけを更新する」設計を採らなかったのか。理由は明確だ。会計には監査要件があり、「いつ・誰が・なぜ・いくら動かしたか」を後から完全に検証できる必要があるからだ。残高を上書きすると、その検証性が失われる。

この問題は500年経っても変わらない。むしろ近年、SOX 法・GDPR・各種金融規制によってソフトウェアにも同等の要件が降ってきている。Event Sourcing が「新しいアプリケーション設計」というより「業務記録の伝統的な形へ立ち戻る設計」と言える理由がここにある。


2. 1970年代:障害許容システムでの「ログ」

ソフトウェアにおける Event Sourcing の直接の先祖は、1970年代のミッションクリティカルシステムにある。代表例が Tandem NonStop システムだ。Tandem 社が開発したこのシステムは、銀行・証券取引所など止められないシステムで使われ、「全ての状態変更をログに書き、ログを再生することで状態を復元する」設計を採っていた。

データベースの世界でも、同じ時代に Write-Ahead Logging(WAL、ログ先行書き込み) が確立した。トランザクションをコミットする前に、変更内容をログに書く。クラッシュしてもログから状態を復元できる。これは現代の PostgreSQL・MySQL・Oracle すべてに継承されている基盤技術だ。

Event Sourcing は、この 「ログを副産物ではなく、主データにする」 発想と表裏一体だ。

従来のRDB:
  メインデータ(テーブル)= 現在の状態
  ログ(WAL)            = 障害復旧用の副産物

Event Sourcing:
  メインデータ(イベントストリーム)= 全ての変更の記録
  プロジェクション                    = 派生する派生物

「副」と「主」がひっくり返っただけ、と言えばその通りだ。だがこのひっくり返しが、設計判断の重心を大きく変える。

graph LR
    subgraph rdb["従来の RDB"]
        R1[("メインデータ<br/>テーブル<br/>(現在の状態)")]
        R2[("WAL<br/>ログ<br/>(障害復旧用の副産物)")]
        R1 -.派生.-> R2
    end

    subgraph esa["Event Sourcing"]
        E1[("メインデータ<br/>イベントストリーム<br/>(全変更の記録)")]
        E2[("プロジェクション<br/>Read Model<br/>(派生する派生物)")]
        E1 -.投影.-> E2
    end

    rdb -->|主従が反転| esa

    style rdb fill:#fff3e0,stroke:#fb8c00
    style esa fill:#e8f5e9,stroke:#43a047

3. 2003-2004年:DDD とドメインイベントの登場

2003年、Eric Evans が Domain-Driven Design を出版した。この時点では「ドメインイベント」という章はまだない。Evans が集中して扱ったのは、ドメインモデルそのものの設計(エンティティ・値オブジェクト・集約・リポジトリ)だった。

しかし2003〜2004年頃、「ドメインで起きた重要な事実をオブジェクトとして扱う」 というアイデアが、DDD コミュニティの周辺で形になり始めていた。Martin Fowler は2005年2月の “Domain Event” という短い記事で、このパターンを次のように整理している。

「ドメインイベントは、ドメインで起きた何かを捉えたもの。エンティティのように同一性を持ち、いつ起きたかを表すタイムスタンプを持つ」

ドメインイベントが「過去に起きた事実を、不変のオブジェクトとして扱う」と定義されたことで、次の問いが自然に生まれる。

「不変のイベントを扱うのなら、それを永続化したらどうなるか?」
「そのイベント列を再生したら、現在の状態は導出できるのではないか?」

この問いに答えたのが、同じ Fowler の別の記事だった。


4. 2005年12月:Martin Fowler “Event Sourcing”

2005年12月12日、Martin Fowler は “Event Sourcing” という記事を公開する。これが「Event Sourcing」という用語を確立した記事だ。Fowler はこの中で、Event Sourcing の本質をこう定義している。

「アプリケーション状態への全ての変更を、イベントの系列として記録する。イベントをクエリできるだけでなく、イベントログを使って過去の状態を再構築でき、遡及的な変更にも自動的に対応できる」

この定義の中に、後に重要になる3つの能力が既に含まれている。

1. クエリ性(Query)
    起きたイベントそのものを問い合わせ対象にできる

2. 過去状態の再構築(Reconstruct)
    任意の時点までイベントを再生すれば、当時の状態が復元できる

3. 遡及的調整(Retroactive Change)
    過去のイベントの修正を反映して、以降の状態を再計算できる

特に3つ目は強力だ。例えば「3ヶ月前の取引にミスがあったので、当時から計算をやり直したい」という業務要件に、設計上の余地が生まれる。Fowler はこの記事で、Event Sourcing が「監査ログ・履歴・遡及修正・並列モデル」という4つの応用に同時に応えることを示した。

ただし、Fowler の2005年の記事は概念整理にとどまっていた。「実際のアプリケーションでこれをどう設計するか」という具体的な方法論は、まだ誰も体系化していなかった。


5. 2008-2010年:Greg Young と CQRS との合流

そこへ現れたのが Greg Young だ。Young は2006-2010年頃、ニューヨークの金融系プロジェクトで Event Sourcing と DDD を組み合わせた実践を積み重ね、その経験をカンファレンスや講演で発信していた。

決定打となったのは2010年だった。Young は「CQRS Documents」(2010年11月、PDF)で、CQRS(Command Query Responsibility Segregation)と Event Sourcing をセットで体系化 した。

Young の貢献は、Event Sourcing 単独では見えなかった構造を可視化したことにある。

graph TB
    Cmd[Command] --> Agg["Aggregate<br/>(書き込みモデル)"]
    Agg -->|発行| Store[("Event Store<br/>追記専用ログ")]
    Store -->|Projection| RM[("Read Model<br/>(読み取りモデル)")]
    Query[Query] --> RM

    Store -. 整合性の責務 .- Agg
    RM -. パフォーマンスの責務 .- Query

    style Cmd fill:#e3f2fd
    style Query fill:#e8f5e9
    style Store fill:#fff3e0
    style Agg fill:#f3e5f5
    style RM fill:#fce4ec

「書き込み側はイベントを追記するだけ。読み取り側はイベントから派生したビューに直接アクセスする」── これが現代の Event Sourcing アーキテクチャの基本構造だ。Young はさらに次の論点を整理した。

- Aggregate の状態は、イベント列の累積関数 (fold) として定義される
- Event Store は append-only。UPDATE / DELETE は存在しない
- 楽観的並行性制御は「期待されるシーケンス番号」で実現する
- Projection は読み取り側のニーズに最適化されたビューを別途構築する
- Snapshot は Replay コストを下げるための最適化であり、本質ではない

これらは現在の Event Sourcing 実装すべてに共通する語彙だ。Young が CQRS とのセットで提示したことで、「読み書き分離」と「変化の記録」という2つの直交する関心事が、相互補完的に組み合わさることが明確になった。


6. 2011年:LMAX が示した「規模で動くこと」

理論があっても「巨大なトランザクション量で本当に動くのか」という疑問は残っていた。それに答えたのが2011年7月、Martin Fowler が公開した LMAX Architecture の記事だ。

LMAX は英国の金融取引プラットフォームで、1スレッドで秒間600万件のオーダーを処理する Business Logic Processor を、Event Sourcing と Disruptor(独自開発のロックフリーキュー)で構築 していた。状態は全てインメモリ、入力イベントは全てログに書かれ、再起動時にはログを再生して状態を復元する。

LMAX が Event Sourcing コミュニティに与えたインパクトは大きい。次の3点が「実証された」のだ。

1. Event Sourcing は性能の足枷ではなく、むしろ性能を引き出せる
   (メモリ常駐+追記オンリーで、ロックも分散トランザクションも不要)

2. 障害復旧は「ログ再生」で自然に得られる
   (別途のフェイルオーバー機構を組まなくていい)

3. テスト容易性が高い
   (イベント列がそのままテストの入力になる)

LMAX は Event Sourcing が「ニッチで遅い設計」というイメージを完全に覆した。ただし LMAX のような「単スレッド全インメモリ」設計は誰もが採用すべきものではない。重要なのは、Event Sourcing がスループット要求の厳しい領域でも実用的だと示したこと だ。


7. 2012年以降:エコシステムの形成

2010年以降、Event Sourcing 専用のツール/フレームワークが次々と登場する。

2012年  EventStoreDB(現 KurrentDB)の最初のリリース
        (Greg Young 自身が CTO として関与)
2010s   Axon Framework(JVM)、Marten(.NET/PostgreSQL)の発展
2014年  Akka Persistence(JVM/Scala)が Event Sourcing をサポート
2010s後半 AWS が DynamoDB Streams / EventBridge でイベント駆動を後押し
2017年  Vaughn Vernon が Reactive Messaging Patterns を出版、
        Event Sourcing の運用パターンを更に整理
2023年  Sara Pellegrini が DCB(Dynamic Consistency Boundary)を提唱、
        Event Sourcing 上での集約の限界を超える試みが始まる

ツールが整い、書籍が増え、各社の事例が公開されることで、Event Sourcing は「先進的な人だけが使う設計」から「監査・履歴要件のあるドメインでは選択肢として検討する設計」へ位置づけが変わった。


系譜のまとめ:Event Sourcing は「合流点」である

ここまでの流れを1つの図にまとめる。

timeline
    title Event Sourcing の系譜
    1494 : 複式簿記(Pacioli)<br/>取引を時系列で追記し、残高は累計から導出
    1970s : Tandem NonStop / WAL<br/>ログによる状態復元
    2003 : Evans "Domain-Driven Design"<br/>ドメインモデルの設計
    2005 : Fowler "Event Sourcing"<br/>用語の確立
    2010 : Greg Young "CQRS Documents"<br/>CQRSとセットで体系化
    2011 : LMAX Architecture<br/>規模で動くことを実証
    2012 : EventStoreDB リリース<br/>専用基盤の登場
    2013 : Vernon "実装するDDD"<br/>DDDの実践書として普及
    2023 : Pellegrini "DCB"<br/>集約の限界を超える次の世代

歴史を辿ると、Event Sourcing が「新しい派手なパターン」ではなく、昔から人類が業務記録に対してとってきた形を、ソフトウェアの語彙で言い直した設計 だと分かる。

Event Sourcing の思想を一言で:
  「現在の状態は、起きた事実の累積結果である」
  「事実を残し、結果は導出する」

複式簿記から500年、Tandem から50年、Fowler の命名から20年、Greg Young の体系化から15年。思想は古く、ツールは新しい。これが2026年時点の Event Sourcing の立ち位置だ。


なぜこの系譜を知っておくべきか

ツール選定や設計判断の場面で、「なぜこのパターンはこの形なのか」を知っているかどうかは、実務に直接効いてくる。

よくある現場の問い:
  Q: なぜイベントは不変なのか?
  A: 複式簿記の伝統。書き換えると監査性が失われる。

  Q: なぜ Append-only にするのか?
  A: WAL の伝統+並行性制御の単純化。書き込みが一方向だと
     ロックが要らない(後の章で詳説)。

  Q: なぜ Read Model を別に持つのか?
  A: Greg Young が CQRS で示した分離。書き込みは整合性、
     読み取りはパフォーマンスに最適化する。

  Q: なぜ Snapshot は「最適化」と呼ばれるのか?
  A: Snapshot がなくても理論上は動く。長いストリームの再生コストを
     下げる工夫であって、Event Sourcing の本質ではない。

これらの「なぜ」が分かっていると、ツールの仕様を読むときに「設計者が何を考えてこういう API にしたか」が透けて見えるようになる。次章では、この設計が 応える具体的な課題 を見ていく。

参考文献