イベントソーシングを理解する
🎄Merry Christmas🎄 WWWAVE アドベントカレンダー 12/10の記事です
はじめに
現在ウェイブでは、「決済分離プロジェクト」に取り組んでいます。
このプロジェクトの目的は、バックエンドのモノリスに長年つぎ足しで実装されてきた決済ロジックを、決済ドメインをモジュール化したモジュラーモノリスに切り出すことで、抱えている技術的負債を抜本的に解消することです。
実装方針としては DDD(ドメイン駆動設計)を採用しており、集約の永続化には『ドメイン駆動設計をはじめよう』に登場するイベントソーシングを用いた「イベント履歴式ドメインモデル」を使っています。
とはいえ、着手した当初の自分は DDD もイベントソーシングも初体験でイベントソーシングという概念も中途半端に理解したまま進めていました。そこで一度立ち止まり、自分なりに整理した内容をこの記事としてまとめておきたいと思います。
特に、イベントソーシングをステートソーシングと対比させて眺めてみると、概念がぐっと掴みやすくなりました。
今回は、この2つを比較しながら、イベントソーシングのイメージについて紹介しようと思います。
ステートソーシングとは
- よくあるやつ
- CRUD処理
- 最新のデータの状態を持つ
イベントソーシングとは
- DDDの文脈でよく出てくる
- 変化をイベントとして記録する
- 過去のイベントから状態を復元する
どちらを使うか
ステートソーシングのメリット・デメリット
メリット
- 学習コストが低い
- 現在、ウェブの開発ではRuby on RailsなどのCRUDに適したフレームワークがほとんど。それほど、開発経験者が多い。
- SQLがシンプル
- データ構造とデータベースのマッピングをカプセル化しやすい
* =>アクティブレコードパターンとの相性がいい - 初期の実装コストが低い
- すぐに動くものが作れる
デメリット
- 変更の履歴が分からない
- 履歴が必要な場合、別のテーブルや監査テーブルを用意する必要がある
イベントソーシングのメリット・デメリット
メリット
- 変更の履歴が分かる
- 変更を追跡しやすい
- テストデータなどの設計が楽
- 参照の実装が変更しやすい
- データベースの構造を変更せずに、アプリケーションレイヤーの変更のみで動的に状態を導出できるため
- 参照の実装がシンプルになる(参照のモデリングが楽)
- 同期・非同期へ拡張がしやすい(イベント駆動アーキテクチャを用いたマイクロサービス化など)
デメリット
- 学習コストが高い
- イベントソーシングの開発経験者が少ない
- SQLが複雑になる
イベントソーシングの気になるところ
なんだかイベントソーシング良さそうだけど、暗黙知になりやすい設計観点もあると思います。
たくさんあると思いますが、よくあるやつについて。
性能面
イベントが溜まりすぎると、性能の問題やお金の問題が気になるかもしれません。
対策はあると思います。
- 最新のスナップショットをとる
- 不要なレコードのアーカイブする・削除するなど
- 集約のインスタンス単位にシャーディングする
実際にやってみて性能を計測することが大事です。
ログとの違い
ログに出すことは問題ないですが、複数の記録方法を前提とすると、一貫性が保てなくなるなどの可能性があります。
イベントを「真実を語る唯一の情報源」とすることで一貫性が保ちやすい。
決済分離プロジェクトでどちらを使うか
『ドメイン駆動設計をはじめよう』の10章を読めば同じような整理がされていますが、改めて。
以下の決済ドメインには以下の要件があります
- 決済の状態を追跡できること
- 与信、売上確定などの状態遷移
- 正確な実装、運用
- 複雑なドメインに対してモデルを柔軟に変えやすいこと
- 失敗した決済に対するリトライ対象の抽出や、送金、不正検知など
うん、イベントソーシングだ!
今回のプロジェクトではイベントソーシングが適していると、改めて今回の記事で整理できました。
パチパチパチンコナスビ
最後に
現在はモジュラーモノリスで開発していますが、将来マイクロサービス化も視野に入れて出来るだけ疎結合な設計を意識して実装しています。
非同期でイベントを扱うなどの次なる課題に進めると、よりイベントソーシングの達人になれる予感しています。
最近気に入った「伽藍とバザール」の一文で締めます。
賢いデータ構造と間抜けなコードのほうが、その逆よりずっとまし
読んでいただきありがとうございました。
株式会社ウェイブのエンジニアによるテックブログです。 弊社では、電子コミック、アニメ配信などのエンタメコンテンツを自社開発で運営しております! wwwave.jp/service/
Discussion