2020年9月30日水曜日

クラウド・アプリケーションの特性

前回よりSimpleModel 2020(SM2020)の検討を進めています。

SM2020のターゲットはクラウド上に構築するクラウド・アプリケーションとなります。

そこで、まずクラウド・アプリケーションの以下の特性に対してアプリケーション・アーキテクチャとモデリングの観点から考えます。

  • 並列
  • 分散
  • スケーラビリティ
  • アベイラビリティ
  • リアルタイム
  • UI

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

並列

伝統的にプログラムを実行するマシンは1台、プロセッサは1CPU/1コアの時代が長く続いていたわけですが、クラウド・アプリケーションでは複数CPU/複数コアのマシンを複数台使用したシステム構成が普通となっています。

このため、この環境ではプログラムさえ書ければ容易に並列実行が可能です。

しかし、伝統的なプログラムの手法では逐次的に処理を進めるプログラミングが主で、並列処理は難易度の高いプログラミングが必要でした。

しかし、このままではクラウドによって潤沢に使用することが可能となったハードウェアの能力を活かすことができません。

積極的にクラウドの持つ並列処理能力を活かしたいところですが、アプリケーション開発で高度な並列プログラミング技法を使用することは避けたいところです。

つまりクラウド・アプリケーション開発における並列処理に求められるのは、通常のプログラミング・モデルの範囲内で無理をせず並列性能を得られる方式を整備することといえるでしょう。

アプリケーション・アーキテクチャの考慮点

アプリケーションで並列を扱う必要があるケースとして以下のものが挙げられます。

  • 並列に発生する物理事象に対する処理を高レスポンス実行
  • 大規模計算を並列で高スループット実行

CPUリソースをふんだんに使うことで高レスポンスや高スループットを実現します。

「並列に発生する物理事象に対する処理を高レスポンス実行」に対してはメッセージングベースのオブジェクト指向アーキテクチャであるアクターが有力です。

「大規模計算を並列で高スループット実行」に対しては関数のアプローチが有力です。HadoopやSparkのような大規模データ処理基盤では関数のアプローチによって並列処理のベースとしています。

また大規模データ処理基盤を使わない場合でも、関数型プログラミングによって関数を使った実装を行うことで並列処理と親和性の高いプログラムの構造になります。

アクターによる実装はやや難易度が高いので、可能であればプログラミングが容易な手法が望ましいところです。この目的に合致する技術がリアクティブストリームです。リアクティブストリームを使えば、関数型プログラミングよって関数を合成した作成したパイプラインを、バックグラウンドのアクター上で並列分散実行することが可能になります。つまり、このアプローチが使える状況の場合、通常の関数型プログラミングで安全に並列分散処理を記述することができるわけです。

このため、リアクティブストリームが使える応用ではリアクティブストリームを、そうでない場合は直接アクターを使った実装方式が有力です。

分散

本稿では「分散処理」は複数のマシン上で並行動作するエージェントが協調動作して1つの仕事を行うことを指すこととします。

概ね以下の2つのパターンがあります。

  • 複数の物理事象に対する対応をまとめあげて1つの仕事を行う
  • 1つの大きな仕事を複数のエージェントで分担して行う

いずれの場合も、エージェント間の分散合意の技術がキーポイントとなってきます。最重要な分散合意技術がデータベースに対する分散トランザクションです。

現時点では分散トランザクションは一応の標準プロトコルは存在するものの気軽に使える日用品の技術というわけではありません。

また、分散合意アルゴリズムのPaxosも実用化されていますが、こちらも気軽に使えるという感じではないと思います。

分散については、並列と同様にアプリケーション側では分散を直接意識したプログラミングは避け、プラットフォームやフレームワークが提供する機能を使用して、通常のプログラミング・モデルの範囲内で無理をせず分散の効用を得られる方式を整備することが求められます。

アプリケーション・アーキテクチャの考慮点

分散処理を行うためにはマシンをまたいだエージェント間の通信が必要です。この目的でプラットフォームが提供する以下の機能を使うことになります。

  • RPC
  • メッセージング

RPC(Remote Procedure Call)はプログラミング言語内の手続き呼び出しのセマンティクスでリモートサービスの手続きを呼び出す機能です。本稿ではWeb系で使用されるRESTもRPCの一種として扱います。基本的に、通常の手続き呼び出しと同様に使うことができますが、以下の点で注意が必要です。

  • 性能が遅い
  • 通信層、サービス側でのエラーが発生する可能性がある

特にネットワーク分断などのエラーが発生した場合は、分散処理に参加する各エージェントが独自に動作してシステム全体として誤動作するケースもあるので注意が必要です。

メッセージングは分散処理を構成するエージェント間で非同期メッセージを送受信して処理を進める方式です。RPCとは以下の点で異なります。

  • 非同期
  • キューイング
  • 同報(ブロードキャスト、マルチキャスト)が可能

基本が非同期の処理となるため、エラー時のリカバリ処理が複雑になります。

メッセージングの同報機能はサービスバスの土台となります。

サービスバスを使うことで、複数の疎結合のモジュールを組み合わえてアプリケーションを構築することが可能になります。

エージェント間の通信にメッセージングを使う場合、並列の項でも述べたとおりエージェントの実現方式としてアクターが有力です。「複数の物理事象に対する対応をまとめあげて1つの仕事を行う」場合、アクターを使うと???

また並列の後で述べたように「1つの大きな仕事を複数のエージェントで分担して行う」応用では関数がキーとなる技術です。

スケーラビリティ

クラウド・アプリケーションの重要な特性の一つはスケーラビリティ(scalability)です。

本稿ではサービスを同時に使用できるユーザー数が増えた時に、ハードウェアリソースを追加してシステムを拡張していく能力とします。また、スケーラビリティを達成する手段としては、CPUなどのハードウェア増強によるスケールアップとマシン数の追加によるスケールアウトの2種類がありますが、モデリングに影響があるスケールアウトを対象にします。

アプリケーション・アーキテクチャの考慮点

サービスの実行時に、サービスを実行するエージェント間で共有するリソースがなければサービス実行は完全に並列実行でき、マシン数の追加に対する特別な考慮も要りません。

しかし、通常のアプリケーションはデータベースに格納したデータを共用するので、データベースアクセスが最大のボトルネックになります。特に更新処理が発生するは排他制御が大きなボトルネックとなります。

スケーラビリティを高めるためには、サービスを実行するエージェント間でのデータベースの競合を以下に減らすかが論点の一つとなります。

一つのアプローチとしてはアプリケーションロジックを可能な限り関数化することで並列実行を阻害する要因を減らすことです。

また、更新処理に関してはデータベースの競合を避けることは難しいですが、冪等性を活用することでクライアントからの再実行が可能となり、楽観的手法など競合を緩和するアプローチが選択可能になります。

アベイラビリティ

アベイラビリティ(availablity)は、システムを止めずに処理を続行する能力です。マシンが1台の場合、そのマシンが落ちてしまえば処理を続行することができませんが、マシンを二重化しておけば1台のマシンが落ちても、もう一方のマシンで処理を続行することができます。

さらに、スケールアウトなどの目的で複数マシン構成になっている場合には、1台のマシンが落ちても残りのマシン群で処理を継続することができるはずです。

複数のマシンを並列動作するクラウド・アプリケーションの性質上、ハードウェア的には要件を満たしているのでできれば実現しておきたい特性の一つです。

アプリケーション・アーキテクチャの考慮点

アベイラビリティを達成するための有力な方式がクラッシュした場合の処理の再実行です。

クライアントはサービス実行を依頼するマシンが落ちた場合、別のマシンに同じサービス実行を依頼することでサービスを提供するマシンが落ちても処理を継続することができます。

このような仕組みでアベイラビリティを高めることを柔軟性(resillient)のキーワードで表すこともあります。

アプリケーション・アーキテクチャ上は以下のような考慮が必要になります。

  • 処理の再実行機能を組み込んだRPC(Remote Procedure Call)
  • メッセージング
  • 関数型
  • 冪等性

処理の再実行自体はプラットフォーム側で提供する機能を利用することになるでしょう。このため、必要なのは再実行可能なアプリケーションロジックです。この目的には関数と冪等性が有効です。

リアルタイム

リアルタイムというと、制御系システムで所定の時間内で処理が完了する性質を表すことが多いと思いますが、ここでは外部の事象に即時に反応して処理を行う機能を指すことにします。

たとえば、事前に登録した商品の在庫がある店舗近くに来た時に通知で知らせる、といった応用を想定しています。

アプリケーション・アーキテクチャの考慮点

リアルタイムを実現するためには、並列で述べた「並列に発生する物理事象に対する処理を高レスポンス実行」や分散で述べた「複数の物理事象に対する対応をまとめあげて1つの仕事を行う」を実現するメカニズムが必要です。

手続き呼び出しベースではなく、非同期性を内包したメッセージングをベースにしたアプリケーション・アーキテクチャにしていくことが重要です。

このメカニズムとして有力なのがアクターです。

UI

UIはシステムが提供するサービスを利用する接点となる機能です。

本稿でのUIはWebブラウザ上やスマートフォン上のネイティブアプリとして実装するフロント側のUIアプリケーションを指しています。ここでの検討では、UIそのものの機能はスコープ外としUI機能とサーバー側で実行されるサービスとのコミュニケーションを中心にみていきます。

アプリケーション・アーキテクチャの考慮点

UIそのものの実現方式はいろいろな議論があると思いますが、サーバー側のサービスとの通信方式は以下の2つに集約されます。

  • RPC
  • メッセージング

RPCはUIからのサービス呼び出しを同期型で行うもので、従来からあるものです。

一方メッセージングはUIからサービスまたはサービスからUIへの呼び出しを非同期で行うものです。

クラウド・アプリケーション的に考慮が必要なのはサービスからUIへの呼び出しです。この使い方では、分散処理を構成するエージェントの一つにUI機能が入るというような構成になります。

モデリングの検討

アプリケーション・アーキテクチャでの考察で以下の要因を抽出しました。これらの要因に対するモデリングの手法を確立することが重要です。

  • 関数
  • 冪等性
  • RPC
  • メッセージング
  • サービスバス
  • アクター
  • リアクティブストリーム

今後SM2020の開発を進めていくにあたって、現時点でのアイデアをまとめました。

関数

クラウド・アプリケーションは並列・分散ネイティブを指向することになるため、関数がキーテクノロジーとなります。つまりアプリケーションの分析・設計時には手続きと関数を明確に峻別し、関数化できるところを最大化するアプローチを取る必要があります。

SM2020では以下のようなアプローチが有力と考えています。

  • ルールを第一級モデル要素とする
  • データフロー図

SimpleModelではリソース、アクター、イベントなどのエンティティは特別な分類子としてステレオタイプで記述可能になっています。従前からルールもこの特別な分類子として用意していましたが、関数の集まりという観点で並列や分散に親和性の高いモデルとして積極的に活用していく予定です。

また、関数の計算過程をデータストアとの関係で記述したデータフロー図も有力です。

冪等性

スケーラビリティやアベイラビリティを最大化するためには、サービスが提供する手続きの冪等性が重要な要因になります。

サービス設計時に冪等性を意識的に取り扱っていく必要があります。

SM2020では以下のようなアプローチが有力と考えています。

  • サービスの手続きの特性として冪等性を記述可能にする
RPC

モデリング的にはRPCは通常の手続き呼び出しと同等に考えることができます。ただし、性能問題とエラーのリカバリの2つの問題は考慮に入れる必要があります。

SM2020では以下のようなアプローチが有力と考えています。

  • サービスの提供する関数や手続きの特性として
メッセージング

メッセージングは従来のUMLではシーケンス図を用いて記述する方法はありますが、コンポーネント図などでの記述方法などは今ひとつ明確化されていないと思います。

SM2020では以下のようなアプローチが有力と考えています。

  • サービスの分析・設計にメッセージング記述用の記法を追加
  • メッセージングの流れを記述するメッセージ図を整備

個人的にはUMLのシーケンス図やコラボレーション図でもメッセージングの記述に曖昧な点が残ると考えています。この問題に対応するためにメッセージ図を開発しました。

SM2020ではこのメッセージ図を整備していく予定です。

サービスバス

サービスバスを使うことで、非同期事象やイベント駆動をうまく扱えるようになります。

SM2020では以下のようなアプローチが有力と考えています。

  • イベントの整備
  • アクター

サービスバスの機能をアプリケーションで活用する場合には、イベントという抽象化を用いるのが有力です。

SM2020ではエンティティとしてイベント・エンティティを用意しているので、これとサービスバスの連携を行うような方向性を考えています。

またサービスバスからの受信するメッセージの処理にはアクターが有力だと思うので、アクターでの記述方式を検討予定です。

アクター

メッセージングやサービスバスで受信したメッセージの処理の実装にはアクターが有力です。

SM2020では以下のようなアプローチが有力と考えています。

  • アクター記述用の記法を追加
  • メッセージ図でアクターの振る舞いを記述可能にする
リアクティブストリーム

前述したように並列分散の処理を実装する場合、リアクティブストリームが使える応用ではリアクティブストリームを、そうでない場合は直接アクターを使った実装方式が有力です。

このためSM2020でもリアクティブストリーム向けのモデリングの枠組みを検討予定です。

SM2020では以下のようなアプローチが有力と考えています。

  • データフロー図
  • メッセージ図

データストアとの関係を重視したい場合はデータフロー図、パイプライン処理の側面を重視したい場合はメッセージ図という使い分けを想定しています。

まとめ

SM2020のモデル検討の前提情報としてクラウド・アプリケーションの性質から、必要と思われるモデル要素の抽出を行いました。

アイデアレベルですが、簡単な検討を行いました。

クラウド以前は並列分散処理は特殊な分野でしたが、クラウド時代に入ってコモディティ化しており、従来型のComand-Controlモデル向けのモデリング手法では対応しきれなくなっています。

とはいえ並列分散向けのモデリングの拡張を安易に入れてしまうと、モデリングの難易度が高くなってしまい実用性に問題が出てしまいます。

通常のアプリケーション開発で使用できる範囲内の難易度で、並列分散についても実用的に取り扱えるモデリング体系のバランスを取っていく必要がありそうです。