こんにちは、チーム LIGHT の坂井です。冬は寒いので嫌いなのですが、こうも「まあ確かに寒いけど……なんか言うほどではねえな……※福岡県福岡地方の話」ぐらいの微妙な冬っぷりを発揮されると憎むに憎みきれず、余計に嫌いにならざるをえません。夏も暑くなかったし、なんなんでしょうね。
さて、チーム LIGHT が不定期連載している Laravel 勉強会ログの第 9 回です。今回は CQRS(Command and Query Responsibility Segregation, コマンドクエリ責務分離)の話です。
👇過去記事はこちら👇
- Laravelのライフサイクル #Laravel輪読会 Vol.1 - Fusic Tech Blog
- Laravelのサービスコンテナ # Laravel輪読会Vol.2 - Fusic Tech Blog
- Laravelのサービスプロバイダとコントラクト #Laravel輪読会 Vol.3 - Fusic Tech Blog
- Laravelのアプリケーションアーキテクチャ #Laravel輪読会 Vol.4 - Fusic Tech Blog
- Laravelのリクエスト/バリデーション/レスポンス #Laravel輪読会 Vol.5 - Fusic Tech Blog
- Laravelのミドルウェア #Laravel輪読会 Vol.6 - Fusic Tech Blog
- Laravel の Eloquent #Laravel輪読会 Vol.7 - Fusic Tech Blog
- Laravelのリポジトリパターン #Laravel輪読会 Vol.8 - Fusic Tech Blog
チーム LIGHT の紹介
チーム LIGHT は現在エンジニア 6 名、デザイナー 2 名の合計 8 人のチームです。 雑記ブログもありますので、よかったらそちらもそうぞ! こちらは技術的な内容ではなく、メンバーの日常のことをつらつらと書いています。
また、不定期で LIGHT@NOON という配信イベントも開催しています。
Laravel輪読会の紹介
チーム LIGHT では、週に 1 回 1 時間、Laravel 輪読会を実施しています。
輪読会で読む本はこちらの本です!
PHPフレームワークLaravel Webアプリケーション開発 バージョン8.x対応
2021/6/1 発売の本で、Laravel8 にも対応しています。
ボリュームもたっぷりな上に、Laravel の設計やテストコードに関する内容も充実しているので、オススメです!
本題
今回読んだページはP.311 ~ P.332 の 「7-3 イベントとキューによるCQRS」 についてです。
7-3-1 CQRS(コマンドクエリ責務分離)
CQRS の概要について。
- データの書き込み(コマンド)
- 読み込み(クエリ)
をアーキテクチャレベルで切り離すのが CQRS。大規模なアプリケーションでも保守性・拡張性を保て、読み込みのスケールもしやすくなるなどのメリットがある。
切り離しの手段として、例えば書き込み先は RDBMS、読み込み先は全文検索エンジンというようにデータベースを分ける設計が挙げられている。
7-3-2 アプリケーション仕様
口コミ投稿サイトの構築を例にして CQRS の実装を紹介している。書き込み先 DB に MySQL、読み込み先 DB に Elasticsearch、Queue に Redis を採用。大まかには、MySQL に書き込むたびにイベントを発行し、Queue を介して Elasticsearch のデータを同期させるという設計としている。
※ コード例を挙げながら実装を紹介している部分(7-3-3〜7-3-6)は割愛
7-3-7 Command の実行・Query の実装
今回の実装の場合、DB 書き込みのイベント発火によって Elasticsearch のデータ作成を実行するため、実際の DB と検索結果の一貫性は必ずしも保障されない。データ作成のリアルタイム性が必要となる場合には相応の工夫が必要となってくる。
DB として DynamoDB を使用している場合には、DynamoDB ストリームなどを使用して Elasticsearch と 連携することで、一定水準の一貫性は保証できるなど、AWS のマネージドサービスを活用することで解決する場面も多く考えられる。
チームで話したこと
CQRS 自体について
-
CQRS で実装しないと問題が出るような案件をやってみたい!
- CQRS とまでいかずとも CQS な感じで作りたくはある(案件規模に関係なくできると思う)
- Fusic でも使うチャンスはありそう……
- ふつうの RDS と Elasticsearch ひとつずつ置いていい感じに同期しておく、は素直になるほど〜という気持ち
イベントを用いた実装について
- なんかイベント駆動も混じった内容だ
-
データ(トランザクション)整合性と結果整合性みたいなのを気にしなければいけない
- Event を入れるのはそういうことなのだろう
- Elasticsearch <=> MySQL 間での結果整合性の考慮
- データの一貫性とか、設計パターン以上に考えなきゃいけないこと多そう
- なるほど〜と思いつつ、何かがコケて不整合が起きたときのための仕組みもいるんだろうなと思うと、本腰入れないと取り組めなさそう
Elasticsearch について
- Elasticsearch 使ったことない
- Elacticsearch にデータを投入するときのコツを知りたい 考えて設計しないとクエリが複雑になったりしそう
その他
- P323
registerReview
メソッドが見当たらない(save()
だろうか) -
ここでserverlessだぁ〜〜〜〜〜
- AWS と相性よさそうな設計パターンだなぁという安易な感想
しばらくドキュメントを噛み砕いたような内容が続いていたので勉強会ログの投稿はおやすみしていたのですが、今回の内容は日常あまり触れないテーマだったため記事にしました。CQRS が Chapter7 最後の内容となり、次からは Chapter8 コンソールアプリケーション に入ります。
それでは!