$30 off During Our Annual Pro Sale. View Details »

ざっくりCQRS/Event Sourcingを解説する

ざっくりCQRS/Event Sourcingを解説する

かとじゅん
PRO

October 27, 2020
Tweet

More Decks by かとじゅん

Other Decks in Programming

Transcript

  1. ざっくり
    CQRS/Event Sourcing
    を解説する
    かとじゅん(@j5ik2o)
    設計ナイト2020

    View Slide

  2. DDDに関係はしますが、
    ドメインモデルそのものではなく
    分散システムの設計パターンについて
    話します

    View Slide

  3. 誰?
    ● Chatworkで仕事してます。現在は分散システムの設計・実装を担当しています。
    ● 2016年からk8s+Akka+Kafka+HBaseを用いた、CQRS/Event Sourcingシステム
    を運用しています。
    ● 現在もAkka-Clusterへのマイグレーションを計画中

    View Slide

  4. DDDによるクエリサイドのペインについて
    これらのペインを飲み込めるの
    であれば、CQRSを採用する
    必要はない

    View Slide

  5. C/Qの独立した最適化ができないか?
    それがCQRSだ

    View Slide

  6. CQRSとは
    ● Command and Query Responsibility Segregation=コマンド・クエリ責務分離
    ○ (2010年 Greg Young氏)
    ● コマンドとクエリをスタックごと隔離すること。単なるモデルの分離ではない。Event
    Sourcingとセットで採用されることが多い。
    ● Greg Young氏の論文でも隔離のための境界があると明示されている
    ● コマンドはDDDのドメインモデルを内包することを想定している。というか、DDDの
    ために考えられたパターン。CQRSである=DDDを採用していることになる。
    ● モデルだけ分離して、隔離の境界がないものはCQRSと呼んではいけない(個人の
    解釈)
    とはいえ、CQRSですべてが解決されるわけではない

    View Slide

  7. CQRS/Event Sourcingのイメージ
    スナップショット
    ストレージ
    必要に応じてVOを使ってリード
    モデルを構築する

    View Slide

  8. イベントをどう使うのか
    ● 理解を促すための擬似コー
    ド。CRUDよりレイテンシが悪
    化する例なので真似しないよ
    うに…。
    ● エンティティのライフサイクル
    をリクエストスコープから分離
    する必要がある。そのために
    Actorを使う

    View Slide

  9. 「えっ、複雑やんけっ…」
    一旦落ち着こう

    View Slide

  10. なぜC/Qをわけるのか
    ● そもそもCとQで要件が異なるので、混ぜないで隔離するほうが望ましい。
    ● ただし、データ形式がクライアント要求に合わせる必要がなければC/Qを分けなくて
    もよい。そういう案件に巡り会えたことがないが…。
    コマンド クエリ
    一貫性/可用性 一貫性重視。最新の書き込みが反映され
    るなければならない。トランザクション整合
    性(強い整合性)を使う
    可用性重視。つまりちょっと古いデータ見
    えてもよい。結果整合性 (弱い整合性)を使

    データ形式 正規化されたデータを保存する (集約単位
    ≒概念単位)
    非正規化されたデータ形式取得する (クラ
    イアント要求に合わせる )
    スケーラビリティ 全体のリクエストに対して少ない比率。必
    ずしもスケーラビリティは重要ではない
    全体のかなりのリクエスト比率を占めるた
    め、スケーラビリティが必要

    View Slide

  11. CQRSの利点と欠点
    ● 利点
    ○ コマンドとクエリに分離されており独立しているため、耐障害性を確保しやす
    く、デプロイサイクルも別にできる
    ○ コマンドとクエリを必要に応じて個別に最適化できる。別々にスケールさせるこ
    とができる
    ● 欠点
    ○ コストがかかる。目的ごとにスタックを分離するので、構成要素が多くなる。
    ○ CQRSは従来と比べると複雑と揶揄されることが多いが、従来モデルではC/Q
    が混在することの複雑があったが、CQRSではある意味シンプルになってい
    る。が全体の構成要素は複雑なる。
    ■ つまり、単体のオブジェクトとしてはシンプルになるが、ネットワークとして
    は複雑になるということ

    View Slide

  12. ● CQRSでは、ドメインオブジェクトはドメインロジックを実行するためのシンプルなモデ
    ルとなる。ただし、全体の構造は複雑になる
    CQRSでモデルがどう変わるか
    メッセージの本文を持
    つのはつらい
    メッセージの本文を保
    持しなくてよい

    View Slide

  13. 非Event SourcingでのCQRSはいろいろ難しい
    ● ドメインオブジェクトが計算する値
    はそもそも永続化されていない。
    その値がリードモデルで必要な
    場合、DBトリガで更新を通知して
    SQLでリードモデルを構築できな

    ● リードモデル更新プロセスを採用
    する場合、DBとは別途キューを
    必要とする。結局Eventに頼るこ
    とになる。
    ● できるだけダブルコミットを避けて、障害でノードが消失しても再開できるようにイベント
    は永続化される必要がある。Event Sourcingではイベントを真のデータソースにす
    る。
    スケーラビリティの観点でポーリ
    ングが難しいので、 pub/subを利
    用する

    View Slide

  14. CQRS/ES対応分散システムフレームワーク
    ● Akka https://akka.io (Scala, Java)
    ● Akka.NET https://getakka.net/ , https://akkatecture.net/ (.NET)
    ● proto.actor https://proto.actor/ (Golang, .NET, Java/Kotlin)
    ○ リアクティブシステムが作れそうなのは Golangのみ
    11k starts, 2010~
    3.3k starts, 2016~
    3.7k starts, 2014~

    View Slide

  15. 完全にC/Qを分けるのは無理…
    クエリサイドのペインも
    許容できないんだけど…

    View Slide

  16. 境界を引かない=非CQRSにする(現実解)
    ● クエリでは一切リポジトリを利用しない。ただしVOに依存することがある
    ● リポジトリはドメインロジックのために使う(findById, store, deleteのみ)

    View Slide

  17. FYI: Scala/Akkaを学ぶための薄い本を売ってます
    ● Scala 2.13とAkka 2.6(Akka-Typed)で解説しています。
    10冊売れた
    29冊売れた

    View Slide