CQRS Pattern
こちらは勉強のため翻訳したポストです。
元のページはこちらをクリック
アプリケーションで読み取りと書き込みを分離することをCQRSパターンという。
CQRSパターンは物理的、論理的に分けることができ、次のような長所を持つ。
・複雑度の管理
・パフォーマンスの向上
・拡張性
・柔軟性
・保安性
CQRSパターンが何か?
Command Query Responsibility Segregation。
直訳すると命令クエリ責任分離で、データを読み込みと書き込みをそれぞれのモデルを使用するという意味である。
標準とされてきた方式としては、同一のモデルを用いてデータを読み上げアップデートしていたが、この方式は簡単で、ほとんどのCRUD作業に適している。 しかし、複雑なアプリケーションでは維持管理が難しくなる。
データの書き込みのために複雑なビジネスロジックや有効性検査を行うこともあり
データを読み取るためには、さまざまなクエリを実行する必要がある場合がある。
また、どのようにデータモデルを作成するかを考慮する必要がある。 SQL データモデリングのベストプラクティスは正規化されたデータベースが提供されるが、これは一般的には問題ないが、データを書くことに最適化されている。
コマンドとクエリをそれぞれのモデルとして使用すると、個別に拡張することができる。 同じデータベースを使用するとしても論理的に分離できる。 コマンド(命令)およびクエリに対する下位システムをそれぞれのサービスに分割することができる。 また、データの書き込み、読み取りに最適化された複数のデータベースを使用することもできる。
CQSとはどう違うか?
CQS (Command Query Separtion) : 命令クエリ分離
基本前提はオブジェクトのメソッドをコマンドとクエリに分割したこと。
コマンド :システムのステータスを変更するが、値を返さない。
クエリ:値を返すが、システムの状態を変更しない。 (サイドエフェクトなし)
コマンドからは値を返せないという意味ではない。
一般的な例としては、値を返した後にシステムの状態を変更するスタックから値を引き出してくる場合がある。
CQRSはCQSが進化したもので、CQRSはアーキテクチャレベルで動作する。 同時に、CQS はメソッド(あるいはクラス)レベルで動作する。
CQRSの多様な選択
以下は、複数のデータベースを使用するCQRSシステムのハイレベル概要である。
コマンドは、「書き込み」データベースを更新し、「読み取り」データベースを同期する必要がある。これにより、CQRSシステムに最終一貫性が導入される。
最終的な一貫性により、アプリケーションの複雑さを大幅に増加させるが、同期プロセスが失敗するとどうなるかを考慮し、耐欠陥性戦略(fault tolerance strategy)を持たなければならない。
このようなアプローチには様々なものがある。
・書くためのSQLデータベースと読むためのNoSQLデータベース
・書くためのイベントソーシングと読むためのNoSQLデータベース
・読み取りのためのRedisの使用またはその他の分散キャッシュのキャッシュ
読み書きのためのデータを分離すると、要求事項に最適なデータベースを選択することができる。
論理的CQRSアーキテクチャ
CQRSパターンをシステムにどのように適用できるか?
書き込みの側面では、一般的にEF Core と rich ドメイン モデルを使用してビジネスロジックをカプセル化する。 命令の流れはEFを使ってメモリに読み込み、ドメインロジックを実行し、変更点をデータベースに保存する。
読み取りの側面では可能な限り間接的なものを追求するべきで、Dapperを使用して原始的なSQLクエリを使用することは良い選択であると言える。 データベースにviewを生成したり、クエリを作成することができる。 またはEF Coreを使ってプロジェクションでクエリを実行することもできる。
まとめ
コマンドとクエリを分離することで、長期的にはパフォーマンスとスケーラビリティを向上させることができる。また要求事項に応じて命令とクエリをそれぞれ最適化することができる。
コマンドは複雑なビジネス論理と検証をカプセル化することができる。 EF Core や rich ドメイン モデルを使用することは素晴らしいソリューションの一つである。
クエリは性能に関するものであるため、最もパフォーマンスの良いものを使用するためにDapperを使用する。 EF Core プロジェクションやRedis、原始的なSQLクエリを使用することができる。
コメント
コメントを投稿