21日目、22日目の記事が途切れている件につきましては大変申し訳ございません。
初めましての方は初めまして。そうじゃない方はお久しぶりです。
どうも、クマさんです。このアドベントカレンダーを執筆するのも今年で3年目ということで
時間の流れがとても早く感じる今日この頃です。
さて、今年は4年に一回行われるビックイベント、サッカーのワールドカップが開催されましたね。
私自身はそこまで興味は無かったのですが、本会でも話題になっていましたね。
そういうわけで今回はそんなビックなイベントにちなんで「イベントソーシング」
という概念についてお話ししようかと思います。
イベントソーシングとは何か
下記の画像のようにイベントソーシングとは簡単に言うと情報を状態としてではなく
イベントとして保持しようという考え方になります。
具体的な例としては、ユーザがパスワードを変更するというケースにおいて一般的なCRUDでは
エンティティ内のパスワードカラムの値を上書きしますが、イベントソーシングではパスワードを更新したというイベント(例えばPasswordUpadated)をEventStoreという何らかのイベントを保存するためのストレージに書き込んでいくという形になります。
CRUDとの違いは上でお話しした例のように状態を書き換えるのではなくイベントを追記していくということが主な違いであり、基本的に情報を書き換えるという副作用はありません。
メリット
- パフォーマンスやスケーラビリティが向上する
- よりシンプルな実装になる
- 特定のタイミングのイベントからReadModelを生成できる
- 仕様変更に対応しやすくなる
- ユーザの行動履歴を活用できる
- 監査ログを作成しやすくなる
デメリット
- ReadModelへの反映に時間がかかる
- データ容量が膨れ上がる
CQRSとは何か
CQRSとはCommand Query Responsibility Segregation(コマンドクエリ責務分離)の略であり、
ReadとWriteの責務を分離して考えようというデザインパターンです。
イベントソーシングとの相性がよく、イベントソーシングを実現したい場合は
このパターンが使われていることがほとんどです。
CQRSのメリットとして柔軟性が高いという点が挙げられます。
これはバックエンドはドメインモデルに沿った実装をしたいがフロントエンドは
画面に最適化されたデータ(ReadModel)が欲しいといった場合に威力を発揮します。
また、ReadとWriteが分離されているため、高負荷になりがちなRead側を
スケールしやすいといった点があります。
一方でコマンドレポジトリとクエリリポジトリの間で何らかの方法でデータを連携する必要があり
システムが複雑になりやすいという点もあります。
イベントソーシングとCQRS
CQRSを用いてイベントソーシングを実現する際には多くの場合、コマンドリポジトリにイベントを保存し、データ連携の際にReadModelに変換するといった方針をとることが多いと思います。
これらの組み合わせによりデータ連携の際にはQueueやPub/Subを用いることでイベントを
他のサービスに伝えるといったことも容易に行うことができます。コマンドリポジトリには
イベントを保持しているのでコマンドサービスにイベントの履歴を用いた処理を実装すること
も可能です。
まとめ
ここまでイベントソーシングとCQRSを組み合わせることについてお話してきましたが、
この二つを組み合わせることで柔軟性とパフォーマンス、スケーラビリティを意識した
アプリケーションを実現することができるかと思います。ただ、この二つは銀の弾丸では
なく、最適な場面で使用しなければただ複雑でコストの高いアプリケーションになる可能性も
あります。
今回はイベントソーシングとCQRSというデザインパターンについてお話ししましたが、
これを機に皆さんがデザインパターンやアーキテクチャについて少しでも興味を抱いていただけると幸いです。
それでは今年も残すところ僅かですがよいお年をお過ごしください。
参考文献・画像引用元