分散トランザクションを回避するアーキテクチャ
スケールアウトの分散システムにおいての鉄則は分散トランザクションを使わないことです。しかし、現在のプログラミングモデルでは.NETもJavaでもトランザクション伝搬がプログラミングの位置の透過性から防止することができません。つまり、システム設計上トランザクションを利用するとき、開発プロセスの後半の配置の決定の段階で分散配置を選択すると、プログラムはそのまま分散トランザクションを実行してしまいます。この機能は位置の透過性という点では優れているのですが、アーキテクチャのスケラビリティの要求からは、このプログラミングモデルは不都合なのです。
業務プロセスの実行単位のサービス化、DOAなどによるマスターデータの論理的な一元管理、マスターデータに付随したトランザクションデータの業務プロセスにローカルな配置、あるいは、マスターデータ自身のパーティショニングやレプリケーションなど。これらはそれぞれ、アプリケーションポートフォリオの自律的管理、データの保守性の改善やデータの冗長性を減らすことによるアプリケーションの保守性の改善、マスターデータアクセスの性能や可用性の改善を目的にしています。
しかし、これらはいずれもトランザクションの分散化を招くという点では、スケーラビリティとはトレードオフの関係にあるのです。両者をいかに両立してアーキテクチャを構築するかが意思決定のポイントです。
Martin Fowler氏はeBayのアーキテクチャを論じています。
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?Transactionless
ここでは、スケーラビリティをとるアーキテクチャを選択しています。つまり、分散トランザクションを捨てているわけです。
さて、両者をどのように両立するでしょうか?
両立には大きくわけて2つの考慮点があります。1つは設計モデルの決定、もう1つは分散に対するプロトコル上の考慮です。
設計モデルに関しては、責務の配置が決定した概念モデルと、サービスやオブジェクトのようなパラダイムに依存する設計モデルとの間に、トランザクションスコープを定義する設計モデルを新たに考えます。この設計モデルは、概念モデルと同じ概念に関するキーで識別されるモデルであって、DDDで導入されたaggregateに近い、ドメインモデルの部分構造を持っています。概念モデル全体に対して動的スコープで切り取られる部分構造といってもいいかもしれません。この設計モデルは、トランザクションを分散させない、ローカルなサーバないし密結合のクラスタに配置されるものです。また、概念が設計上パーティショニングされるのであれば、パーティションされた部分となります。
この設計モデルに対して、次に、サービスやオブジェクト指向などの実装パラダイムが選択され、それらの論理レベルの設計モデルにマップされます。
もう1つのプロトコル上の考慮ですが、疎結合が前提となる上記の設計モデル間の連携では、メッセージパッシングが有効です。メッセージは通常はat-least-onceのセマンティックスを持っているので、それを処理してローカルトランザクションを起動するstatelsssプログラムは、idempotentでなければなりません。そうでなければ、2重送りのメッセージに対して同一結果の応答ができなくなっています。このidempotent処理では、連携する相手の概念モデルをベースとした上記のキーを用いた状態管理が必要です。これは従来カンバセーション管理を概念レベルまで引き上げたものです。そうプロトコルレベルでも、ADO.NET Entity Frameworkで見られた概念レベルのデータモデルの導入が行われるわけです。その他、仮予約や確認応答のようなロングトランザクションのためのプロトコルが必要となります。
このような設計モデルとプロトコルの導入により、レイヤー化に伴うスケーラビリティの課題を改善しながら、SOAやDDDとの両立を果たすことが可能となります。
アーキテクチャのもう少し詳細な説明はTechEd 2007 Yokohama でお話ししたいと思っています。
http://www.event-registration.jp/events/te07/SessionDetail.aspx?sessionid=T1-501