先行読み出し導出
2009年2月10日
QConサンフランシスコで参加した興味深い講演の一つに、グレッグ・ヤング氏が最近彼が手がけたシステムで使用した特定のアーキテクチャについての講演がありました。グレッグ氏はドメイン駆動設計の熱心な支持者であり、今回のケースでは、高トランザクションレートを処理し、多くのユーザーにデータを提供する必要があるシステムで使用される必要がありました。彼の設計には、イベントソーシングの活用など、興味深い点がいくつかありましたが、この記事では、私が先行読み出し導出と呼ぶ一つの側面に焦点を当てたいと思います。
ドメインモデルを使用する場合、それは複雑なドメインロジックを含んでいるためです。このドメインロジックを以下のように分類すると便利です。
- 検証:入力が理にかなっているか、オブジェクトがそれ以降のアクションに適切であるかを確認します。
- 結果:世界の状態を変える何らかのアクションを開始します。
- 導出:既に持っている情報に基づいて、何らかの情報を導き出します。
これらの種類のドメインロジックは、更新と読み出しで異なる適用方法になります。系図システムがあるとしましょう。出生記録という更新を受け取ります。
name: Bilbo Baggins father: Bungo Baggins mother: Belladonna Took
このデータを送信すると、ドメインモデルはいくつかの検証を行います(父親と母親が同じではないなど)。いくつかの結果をもたらすかもしれません(ブンゴにはビルボが権利を持つ未払いの遺産があるなど)。また、いくつかの導出を行う場合もありますが、通常は検証または結果をサポートするためだけに行います(家系図に循環がないことを検証するために、ビルボの祖先のリストが必要になります)。
データを読み出す場合、通常は導出ロジックのみが関係します。ビルボの父方の祖父を表示するリクエストがあるとします。これには、父方の祖父が父親の父親であるという知識という、ドメインロジックが必要です。ほとんどのシステムでは、読み出しリクエストを受け取ったときに、この読み出し導出ロジックを実行します。基本的に、読み出しリクエストを受け取り、データベースを呼び出して生データを取得し、必要な導出ロジックを実行して、結果を返します(ただし、キャッシュを使用してこれを削減する場合があります)。
先行読み出し導出は全く異なることを行います。ここでは、読み出しはメインデータベースに全く触れません。代わりに、読み出しリクエストと同じ方法で構造化された1つ以上のレポートデータベースがあります。読み出しリクエストはすべてレポートデータベースに直接送られ、レポートデータベースはデータを直接読み取って、ドメインロジックを介在させることなくプッシュアウトします。
出生記録の例とこの図を使って、もう一度説明しましょう。

- UIから出生記録が入力されます。
- ドメインモデルはすべての検証と結果のロジックを実行します。
- ドメインモデルは、レコードのデータベースにコア情報を更新します。
- ドメインモデルは、すべての読み出し(各UI表示を含む)に必要な導出ロジックを実行し、レポートデータベースにデータを入力するための更新メッセージをメッセージキューに配置します。各レポートデータベースは、これらのメッセージから必要なデータを選択して、データを更新します。
- 父方の祖父UIから読み出しリクエストが送信され、レポートデータベースの父方の祖父テーブルからの直接読み出しによって満たされます。
グレッグ氏のケースでは、これらはすべて非同期メッセージで行われ、すべての入力はイベントとしてキャプチャされ(イベントソーシング)、ドメインモデルは入力キューからメッセージを処理し、出力イベントを出力キューにポストしてレポートデータベースを読み込みました。これらをすべて非同期で行うことで、全体的なパフォーマンスとスケーラビリティが向上します。更新を実行し、すぐに読み出しを実行しても、メッセージが処理されるよりも速くクリックしたために、更新の結果が表示されない不整合ウィンドウが存在することを意味します。この非同期スキームは、最終的には一貫性がありますが、強固な一貫性はありません。しかし、これは避けられないことです。分散システムでは、一貫性または可用性を得ることができますが、両方を得ることはできません。
分散型ではない、強固に一貫性のある方法で先行読み出し導出を行うことができます。私がそれを見たケースはすぐに思い浮かびません。先行読み出し導出は、高需要の分散ケースを扱う際に魅力的になると思います。
先行評価を行うことは、それほど新しいことではありません。この手法は私よりも古く(おそらくロン・ジェフリーズよりも古く)、ほとんどの大規模Webサイトは常に導出データでデータベースにデータを入力しています。しかし、これは私が考えるべきほど頻繁に検討されている手法ではなく、グレッグ氏が彼の設計で積極的に使用していた方法が好きでした。