2020年11月30日月曜日

SimpleModel/アプリケーション・アーキテクチャ

クラウド・アプリケーションを構成する以下の各種要素技術に対して、SM2020のメタモデル設計の方針検討を行っています。

  • 関数
  • CQRS
  • Event Sourcing
  • Eventually Consistency
  • マイクロサービス
  • BigData
  • AI
  • IoT
  • DevOps

前回は関数について検討しました。

今回は、CQRS、Event Sourcing、Eventually Consistency、マイクロサービスについて検討します。

CQRS

CQRS(Command Query Responsibility Segregation)は、ざっくりいうとコマンド投入とその結果引き起こされるデータ更新の確認処理を分離するアーキテクチャです。

従来型のCRUD(CreateReadUpdate/Delete)がデータの作成更新が同期型であるのに対して、データの作成更新が非同期で行われる点が重要です。

CQRSのアーキテクチャを取ることによって、データ作成更新のボトルネックを分散させることができ、スケーラビリティを高めることができるメリットがあります。

ただし、利用者からのデータの見え方が参照系と更新系で非対称になるためUX上の見せ方が重要になってきます。

モデリングの検討

CQRSのアーキテクチャをモデリングで扱う場合の論点として以下のものを考えています。

  • ユースケース
  • イベント駆動処理
  • サービス設計
ユースケース

CQRSでは、UX上の見せ方が重要となるため、適切なUXをできるだけ上流で設計していくことが重要です。

この目的で使用することになるモデルはユースケースです。

イベント駆動処理

CQRSアーキテクチャに則ったアプリケーションを作成する場合、ESB(Enterprise Service Bus)を使用したイベント駆動アーキテクチャが有力な選択肢です。

ESBアプリケーションを通常のオブジェクト指向で都度モデリングしてもよいのですが、かなり複雑なモデルになってしまいます。一方、CQRS向けのESBアプリケーションはかなりの定型化ができそうなので、うまい抽象モデルを見つけることができれば、シンプルなモデルとこのモデルからの自動生成を組み合わせて効率的な開発ができそうです。

SM2020では、このような目的の抽象モデルの開発を行っていきたいと考えています。

サービス設計

CQRSでは、参照系、更新系でそれぞれオペレーションが定義されることになりますが、それぞれのオペレーションがCQRSのなかでどのような役割を担っているのか、それぞれのオペレーション間の関係がどうなっているのかという点のモデリングも必要となってきます。

たとえば、CQRSのイベント駆動処理部の振る舞いを変えたときに、どのオペレーションにどのような影響がでるのかといった点をモデル上で検査できるというような用途を想定しています。

Event Sourcing

Event Sourcingは、オブジェクトの状態をイベント列を使って表現、管理していく方式です。スケーラビリティやアベイラビリティを担保する上で非常に有力なアプローチです。

イベント列から状態を計算する方式などを実際の製品開発で試してみましたが、実装が複雑になる、性能的な要件が厳しいなどの問題もあり、なかなか一筋縄ではいかない感じです。

このため、状態に関しては従来どおりリソース側の属性で管理するのが現実解ではないかと思います。

ただし、イベントの発行・記録とリソースの状態遷移を連動させるという方式設計はアプリケーションの見通しをよくし、拡張性や保守性を高めるのに寄与するので積極的に採用したいところです。

モデリングの検討

実現方式は実行プラットフォームに依存する部分が多いと考えられます。ただし、どの実行プラットフォームでも有効な抽象モデルがあると考えられるので、これを探っていきたいと考えています。

SimpleModelでは、従来よりイベントエンティティを重要なモデル要素として扱ってきました。

イベントエンティティを発展させる形でEvent Sourcingとの接点を探っていきたいと考えています。

マイクロサービス

クラウド・アプリケーションでスケーラビリティやアベイラビリティを高めるための実現方式としてマイクロサービスが注目されています。

マイクロサービスといっても単なるSOA的なものから、メッセージ中心の分散プラットフォームまで色々な形態が考えられます。

一つの典型的な方式は、複数のサービス間をスケールアウト可能なRPCを使って接続するというものです。RPC層でスケーラビリティやアベイラビリティの透過性を担保できる場合は、モデリング的には通常のRPCとして扱うことで十分と思われます。

モデリングの検討

前述したとおり、RPC層でスケーラビリティやアベイラビリティの透過性を担保できる場合は、モデリング的には通常のRPCと同様の枠組みで扱うことになると思います。

具体的にはサービスとオペレーションとしてモデリングします。ただし、ステレオタイプを使って、マイクロサービス用のRPCであることを定義していく形を想定しています。

また、マイクロサービスはRPCなどを使った通信が発生するので、オブジェクト指向だけでなくコンポーネント指向の観点から疎結合・凝集、配備の問題をモデルの上で扱っていく必要があります。

Eventually Consistency

Eventually Consistencyは、オペレーション完了時にオペレーションによって変化したデータ更新が保証されず、オペレーション完了後のどこかの時点でデータ更新が最終的には行われることを指します。

従来型のCRUDのオペレーションではオペレーション完了時に、オペレーション内で作成・更新したデータベースのレコードがデータベース内に完全に反映され永続化されることが保証されます。

一方、Eventually Consistencyの性質を持つオペレーションの場合は、オペレーション完了時にこれを保証しません。つまり、オペレーション完了直後に更新したデータを参照した場合に、古いデータを取得してしまう、ということを許容します。

アプリケーション開発的には扱いづらい性質であり、できれば避けたいところですがクラウド・アプリケーションでは以下のような理由により必要なケースが多々発生します。

  • スケーラビリティ
  • イベント駆動処理
  • バッチ処理
スケーラビリティ

クラウド・アプリケーションでは、多数のクライアントを同時接続できることが重要です。

ここでボトルネックになるのはデータベースの更新処理です。

同一レコードに対する書き込み処理が重なると、排他制御によってレスポンス性能、スループット性能のどちらも大幅に低減します。排他制御そのものは避けることはできないので、その他の部分で何らかの対策を取る必要があります。

その有力な対策の一つが Eventually Consistency です。

Eventually Consistency の性質を取ることによって、処理本体とオペレーション呼び出しの完了を分離することができます。オペレーション呼び出しは処理本体をバックグラウンドでの実行スケジュールするだけで完了できるので、レスポンス性能は大幅に更新します。

システム全体のスループット性能も、バックグランド処理をキューイングするなどして平準化したり、複数の処理を一つにまとめたりすることで向上させることが可能になります。

イベント駆動

アプリケーション・ロジックがESBを使用したイベント駆動で実現されている場合には、処理の実行が非同期となるためオペレーションの完了に同期させることが困難です。

この場合はEventually Consistencyを前提にオペレーションの性質を定義する必要があります。

バッチ処理

Webのレスポンスタイムの上限は3秒程度とするケースも多いと思いますが、アクションの実行時間がこれを超える場合にはアクションをバックグラウンドで実行することになります。この場合、当然ながらEventually Consistencyを前提としたオペレーションになります。

モデリングの検討

スケーラビリティ、イベント駆動、バッチ処理の観点からEventually Consistencyについて見てきました。

共通しているのは、メインの処理はバックグラウンドで行われ、オペレーションの返却値では処理の結果を返すことができないということです。

また、処理はバックグラウンド処理で行われますが、必ずしも成功するとは限りません。

上記の点からアプリケーションの設計においては以下の2つの機能が必要になります。

  • バックグラウンド処理の結果確認
  • バックグラウンド処理リカバリ

いずれも、通常のアプリケーション処理として都度モデリングを行ってもよいのですが、かなりの定型化が可能という予感もあります。

実行時のクラウドプラットフォーム側のフレームワーク次第という面も大きいので、フレームワークとの連携を想定した上でモデリングの定型化を図っていきたいと考えています。

ユースケース

ユースケース・モデルの段階で以下のようなEventually Consistencyの影響を取り込んでいく必要があります。

  • リカバリ方式
  • オペレーションの特性情報

SM2020のユースケースモデル設計で上記の性質の定義方法を検討する予定です。

オペレーションの特性情報

サービスのオペレーションによる更新処理に対してステレオタイプなどを用いてEventually Consistencyであることの明示することが有効と思われます。

SM2020のユースケースモデル設計で上記の性質の定義方法を検討する予定です。

モデリングの検討

CQRS、Event Sourcing、Eventually Consistency、マイクロサービスといったクラウド・アプリケーションのアプリケーション・アーキテクチャの整理とモデリングでの対応について検討しました。

検討の結果、以下の項目がSM2020で検討していく候補として抽出できました。

ユースケース

以下の場合にユースケース段階で考慮が必要であることが分かりました。

CQRS
利用者のUX
Eventually Consistency
データが反映されるタイミング

上記の項目をユースケースモデルに取り込んでいく予定です。

イベント・エンティティ

CQRSでのESB利用やEvent Sourcingでイベントが重要なモデル要素になっています。

SimpleModelでは元々イベント・エンティティを軸に静的モデルと動的モデルを連携させるモデル体系になっています。

このイベント・エンティティを拡張してESBやEvent sourcingでの利用をアシストする方法について検討したいと思います。

ESB

CQRSやEventually Consistencyなどの実現方式としてESBが有力であることが分かりました。

ESBアプリケーションを都度スクラッチでモデリングしてもよいですが、可能であればCQRSやEventually Consistencyの観点からのESBの使い方にフォーカスした抽象モデルを定義し、この抽象モデルを使用してモデリングと実装を連携させていくというアプローチを考えていきたいと思います。

オペレーション

オペレーションの特性情報として以下の項目が候補になります。

  • CQRS上の特性
  • Eventually Consistency上の特性
  • マイクロサービス上の特性
コンポーネント指向

ESBやマイクロサービスを用いたアプリケーションでは、疎結合/凝集、配備の問題が重要になってくるので、オブジェクト指向に加えてコンポーネント指向でのモデリングも必要になってきます。

SM2020ではESB、マイクロサービスを視野に入れたコンポーネント指向のモデリングの枠組みを整備したいと考えています。

まとめ

今回は9つ挙げた要素技術の中でCQRS、Event Sourcing、Eventually Consistency、マイクロサービスを取り上げました。

次回はBigData, AI, IoT, DevOpsについて検討を行う予定です。