CQRSはESであるべき?SSでも可能?

ESとSSがどういう場合に適用するとよいかみたいな話をした。CQRS/ESを知らない方は1)を資料を、発端の話題は2)の資料をみてください。 1) CQRS+ES(再)入門: https://speakerdeck.com/j5ik2o/cqrs-plus-es-zai-ru-men 2) CQRSはEvent Sourcingなしで実現できるのか?: https://speakerdeck.com/j5ik2o/cqrshaevent-sourcingnasideshi-xian-dekirufalseka?slide=7
2
がくぞ @gakuzzzz

@j5ik2o ふむふむ。基本的にRMUはQ側のモデルの契約に従う必要があるから、契約を強制するためにRDBの機能を直接使わないで一度プログラミング言語上で表現した方がいい、みたいな話ですかね?

2020-06-14 12:38:48
加藤潤一(かとじゅん) @j5ik2o

@cero_t ですねー。SSだと最新状態しかわからないのでQ側の全部の情報を更新しないといけないですねー。

2020-06-14 12:39:53
加藤潤一(かとじゅん) @j5ik2o

@gakuzzzz ですね。C側のドメインから何かしらの値を得たいなら、エンコードされた値を直接読めなくて、一度VOを通さないとQ側として得られないと思います。CとQを独立したモジュールにするにはこういう考え方になると思います。もちろん妥協はつきものですが。

2020-06-14 12:43:51
Shin Tanimoto / CERO-METAL @cero_t

@j5ik2o C側のうちlastUpdateが2分以内のメッセージだけを取ってきて、それをQ側に反映させるだけなので、全件更新ではなく部分更新にできないですか? (C側のlastUpdateを使うという発想が、そもそもES寄りであることはもちろん認めますけどねw)

2020-06-14 12:44:41
がくぞ @gakuzzzz

@j5ik2o なるほどなるほど。契約を守らせる強制力にどこまで重点を置くか、というのが判断基準になりそうですね。逆に言うと強制力に妥協ができるならESではないCQRSも成り立つ可能性がありそうという理解をしました。ESでは無い時点でそもそもQ側のモデルとRMが近しい可能性ありますし。ありがとうございます

2020-06-14 12:53:19
加藤潤一(かとじゅん) @j5ik2o

@gakuzzzz そうですね。CとQのモジュールとしての分離レベル次第でしょうねー。こちらもよい思考実験になりました。ありがとうございます。あとでまとめるかも

2020-06-14 13:01:56
加藤潤一(かとじゅん) @j5ik2o

@cero_t レコード複数件の話をしてそうです。レコード1件の中のカラム別の部分更新ができないという話ですね。

2020-06-14 13:03:59
加藤潤一(かとじゅん) @j5ik2o

@cero_t あ、件数の話はおかしいなw C側の一つのTx境界内で更新する対象のカラムだけに絞りたいけど、差分イベントがないとつらいという話ですね。 CのステートだけでだとQ側のリードモデルとの差分をとって更新するカラムを決めてもいいですが、これもできないことが多い。C/Qでモデル形式が違うから。

2020-06-14 13:29:23
加藤潤一(かとじゅん) @j5ik2o

@cero_t 時間があったらモデル図にしてみようかな。図みたほうがわかりやすいかも。

2020-06-14 13:29:43
Shin Tanimoto / CERO-METAL @cero_t

@j5ik2o あぁ、カラムについては確かに全カラム更新になりますね。CとQの差分を取ると、全カラム更新よりも逆にコスト高くなりそうですし。 ただ、カラム数そこまで膨大ではない想定でした。C側がRDBである限りは、適切にテーブル分割されて正規化されるはずなので。C側がドキュメントDBだと厳しいですが。

2020-06-14 13:48:40
Shin Tanimoto / CERO-METAL @cero_t

@j5ik2o C側がドキュメントDBで、親子構造(子がわりと多い)を持っているような場合には、ESではないCQRSは厳しいと思います。 C側がRDBであれば、1レコードを「緩く集約されたイベント」と捉えることもできると思うんですよね。複数のイベントを集約した状態で、タイムスタンプがついたもの、っていう。

2020-06-14 13:54:43
Shin Tanimoto / CERO-METAL @cero_t

@j5ik2o ↑この発想は既にSSじゃなくてESじゃないか、って言われたらそれはそうw あくまでCQRS/ESを経験して一周したあとで、CQRS/SSもできるのでは、って思ってる感じです。 (昔ながらのRDBMSが好きな開発者が多いチームならアリかなって)

2020-06-14 13:56:25
加藤潤一(かとじゅん) @j5ik2o

@cero_t チームメンバのスキルも変数になりますね。まぁ純粋にCQRS/ESをみると、CはWriteに強いDB(AWSだとDynamoDB)、Qは柔軟なクエリに対応できるDB(AWS Auroraなど)とすることが多いですね。線形でスケールするし従来比でサーバコストもかなり少ない印象になります。SREも含めて体制とかも必要ですね。

2020-06-14 14:04:30
Shin Tanimoto / CERO-METAL @cero_t

@j5ik2o ですね、僕もよく見るのはDynamo(あるいはRDB)で一次受けして、その後にRDBに保存という形ですね。 CQRS/SSの場合は、トランザクションスクリプトでRDBに書いたあと、検索用にElasticsearchに転送したり、非正規化してRedis/Mongoに入れたり、みたいな感じですね。

2020-06-14 14:12:14
加藤潤一(かとじゅん) @j5ik2o

@cero_t そもそもモチベーションとしてDDDを現実的に実装可能になるためにCQRS(ES)が考えられた背景がありますね。Cのコマンドは別名ドメインとも呼ばれるので。考案者のGregさんの論文を読むとそうなってますね。そういう意味ではトランザクションスクリプトの事例はあまり聴かない気がしますね。

2020-06-14 14:24:02
がくぞ @gakuzzzz

もしかしてCQSとCQRSの違いって背景にDDDが有るか無しかみたいな所なんですかね? twitter.com/j5ik2o/status/…

2020-06-14 14:35:54
加藤潤一(かとじゅん) @j5ik2o

@gakuzzzz 端的に言えば、そんな気はしますね。直接的な関係はCQRS(/ES)にはありますね。ステートソーシングのDTOアップダウンアーキテクチャだと、ドメイン駆動設計を実装に反映することなんてできないよ!と論文に書いてありますからねw

2020-06-14 14:38:16