20章 分散アプリケーションの設計(担当:kando@nerimadors.or.jp)
Design of Distributed Applications
この章の内容: CODARTS設計手法を並行(LAN/WANを介して地理的に離れたノードにまたがって動作する)分散アプリケーションの設計に用いるためにどのように拡張するかについて。
典型的なアプリケーション: 遠隔実時間データ収集、遠隔実時間制御
手法の名称: CODARTS/DA(CODARTS for Distributed Applications)
CODRTS/DAの概要:
l 分散アプリケーションは複数のサブシステムから構成される。
l サブシステムは1つのノードで実行される並行タスクの集まりとして定義される。
l 特に、メッセージで通信し合うサブシステムへ分散アプリケーションを分割する規準を提供する
l 数個のノードがLANで相互に結合されている。
l 各ノードはメモリを共有する1つ以上のプロセッサよりなる。
l サブシステムと論理ノードは1対1に対応。
l 各サブシステムは1つの論理ノード上で実行される並行タスク群として定義される。
l 複数の論理ノードが1つの実ノード上で実行されうる。
l 同じアプリケーションでも論理ノードを実ノードに割り当てる仕方、構成の仕方は色々ありうる。
l 以下、この章での用語:
「サブシステム」は論理ノードをあらわす。
「ノード」は物理ノードをあらわす。
l サブシステムを物理ノードにマッピングする決定を設計時からシステム構成の時点まで遅らせる。
l 個々のサブシステムは非分散並行システムの設計手法(DARTS、ADARTS、基本的なCODARTS)で設計(同一ノード内でのタスク間通信には共有メモリが利用可)。
l 相対的に独立した自立的サブシステム(必要に応じてローカルにデータベースを利用する)で分散アプリケーションを構成する。(分散データベースの利用を前提としない。)
以下の節は分散処理環境と分散OSが提供する支援について述べている。
l タスクがメッセージを送信する際、送信先のタスクがどのノードにあるかを知る必要はないようにすべき。
l いくつかの商用システム(例: VAX/ELN)では透過性を支援する分散カーネルが提供されている。
l 利用できない場合は、タスクの名前リスト(タスク名とノード番号を関連付ける)を管理して通信をルーティングする分散タスクマネージャ(DTM)が必要。
l 各ノードにはカーネルのインスタンス
l タスクがメッセージを送信するとそのタスクと同じノード上のローカルなカーネルが名前の表を参照して送信先のタスクのあるノードを見つける。
l 同一ノード内にあるタスクBからタスクCへのメッセージはノード内で直接配送
l ノード1にあるタスクAからノード2内にあるタスクDへのメッセージはノード1のカーネルからノード2のカーネルに送られ、ノード2のカーネルがタスクDに配送
l ネットワークが利用可能である限りメッセージは遠隔ノードに必ず到達する(例:パリティ・エラーが発生すると通信ソフトウェア(分散OSの一部)はメッセージを再送)
l しかし(ネットワーク上の遠隔ノードへの接続か遠隔ノード自身がダウンしているなどのため)与えられた時間制限内に遠隔ノードが応答しなければタイムアウトする。
l タイムアウトは送信の失敗として通信ソフトウェアからローカルなカーネルに(否定的な受信確認として)通知される。
l ローカルなカーネルは送信元タスクに送信失敗を(否定的な受信確認として)通知する。
l タスクは送信失敗をどう取り扱うかを決定する。(適切な取り扱いはアプリケーションにより異なる。)
分散OSに関する詳細は[Nutt91,Tanenbaum92]を参照。
l 遠隔手続き呼び出しをサポートする分散処理環境もある。
l 同一ノード内にある手続きの呼び出しと同様に遠隔ノードの手続きを呼び出せるようにする。
→利用する側からは遠隔ノードであるかどうかが隠蔽される。
l <呼び出し元>(局所的な)手続き呼び出し
l →<クライアント側のスタブ>引数をパックして適切なサーバー・ノードへメッセージとして送信
l →<サーバー側のスタブ>受信した引数群をメッセージをアンパックして(局所的に)手続き呼び出し
l →<呼び出される手続き>処理を行って値を返す。
l →<サーバー側のスタブ>返り値を呼び出し元ノードにメッセージとして送信
l →<クライアント側のスタブ>受信したメッセージから取り出した返り値を呼び出し元に返り値として局所的に返す。
l →<呼び出し元>
l 名前でタスクを指定して具体的にメッセージを送信する代わりに、メッセージを送信する代わりに、抽象的なポートに対してメッセージの入出力が可能な分散処理環境もある。
l ポートの結びつけはサブシステム設計の段階からサブシステムの構成の段階まで遅延できるので柔軟性が増し、潜在的に再利用性が高まる(同型のタスクを異なった環境、異なったアプリケーションで利用する可能性)。
構成可能なサブシステムから構成されるアプリケーションの設計は以下のような主だった3つの手順から設計されうる。
l アプリケーションを別々のノードで実行可能なサブシステムへと分解する。
l サブシステム間の通信は疎結合に制限される。
l サブシステム間のインターフェースを定義する。
l サブシステムへの分解規準が利用される。
l サブシステムを同一ノードで動作する並行タスクと情報隠蔽モジュールへと分解する。
l 非分散並行システムの設計手法が利用できる。
l 一旦サブシステムの設計が終わればサブシステムのインスタンスを定義して構成できる。
l 実際の物理ノードへサブシステムのインスタンスを割り当てる。
l サブシステムの構成規準が利用される。
大規模分散システム開発特有の複雑さを管理するには:
l アプリケーションを別ノードで実行されうるサブシステムに分解する必要がある。
l 分解後にサブシステム間のインターフェースを慎重に定義する。
分散化エレベータ制御(Fig. 20.3)
分散工場自動化システム(Fig. 20.4)
l 基本的には13章で述べたサブシステムへの分解基準(アプリケーションの特徴に基づく。問題領域に関する。)に基づく。
l 分散ノードへ割り当て可能なサブシステムを設計するには追加の規準(問題解決領域に関する)が必要。
構成可能なように設計する訳:
物理ノードへサブシステムを効率的に割り当てられるよう、実際の対象システムが特定されて構成される際まで割り当てを遅延できるようにするため。
実時間分散処理環境では、あるサブシステムの提供するサービスが特定のノードに関連付けることができるし、与えられたハードウェアの資源の制約を受ける。
分散さうシステム構成規準は構成可能なサブシステムの設計に役立つ。
1. 物理データ源への近接(Proximity to the source of physical data): 複数のデータ源が物理的に離れている場合がある。この規準は物理データの源となるようなサブシステムを供する。データのアクセスを高速にするので、データへのアクセス頻度が高い場合に重要。
2. 局所的な自律性(Localized autonomy): この規準によってサブシステムはシステムのある面を制御する。ノードは、よそのノードから低レベルの制御を方向付ける高レベルのコマンドを(進捗に応じて、あるいは要求に応じて)受け取って状態情報を返す。
3. 効率(Performance): 時間制約の厳しい機能専用のノードを用意するとサブシステムの効率が予測しやすく、また改善できる。実時間サブシステムが時間制約の厳しいサービスを提供し、その他のサービスは他のノードで実行する。(例: 3つのエレベーター・サブシステム(Fig. 20.3)、ライン作業台制御(Line Workstation Controller)サブシステム(Fig. 20.4))
4. 特殊なハードウェア(Specialized Hardware): 特殊目的のハードウェア(例: ベクトル・プロセッサ)、周辺機器、センサーやアクチュエータをサポートするために特定のノードにサブシステムを用意する必要がありうる。(例: 各エレベーター・サブシステム及び各階サブシステムがセンサーとアクチュエータへのインターフェースになっている(Fig. 20.3))
5. ユーザー・インターフェース(User Interface): グラフィカルな表示が可能なワークステーションとパーソナル・コンピューターの普及に伴い、ユーザー・インターフェースを提供するノードを分離して他のノードと相互作用させるようになってきた。この種のサブシステムは専用のI/Oデバイスを備え、簡単な要求は単体で素早く完遂でき、他のノードと協働する場合は相対的にゆっくり応答する。(例: オペレーター・サービスと生産管理サブシステム(Fig. 20.4))
6. サーバー(Server): サーバー・サブシステムは他のサブシステムにサービスを提供する。クライアント・サブシステムの要求に応答するが、自発的に他のサブシステムに要求を出すことはない。あるデータ・ストアやI/Oデバイスに関連したサービスを提供することがしばしばある。集中化されたデータベースやI/Oデバイスへの遠隔アクセスを支援するため、その物理資源を擁する特定のノードに割り当てられることがある。(例: プロセス計画サーバー(Fig. 20.4)、ラインプリンタ・サーバー)
l 1と2の規準によるサブシステムは通常特定のサイトに特化したサービスを実行する。
l 他のノードからの独立性が強いサブシステムならば、他のノードが一時的に利用できなくなっても稼動できる。
l 各サブシステムは別々の物理ノードにおかれる可能性があり、サブシステム間の通信はメッセージ通信に限られる。
l タスク間のメッセージ通信は同一ノード間でも異なるノード間でも同じ一般化された方法で利用でき、相違点は遠隔タスクへの送信は失敗するかもしれないことだけ。
l この節では、サブシステム間のメッセージ通信について述べる。
l 返信を待たない型のメッセージ送信。
l 非同期的なタスク間ではキューが必要。
l 分散処理環境ではメッセージが遠隔ノードに到達したかどうか(送り先タスクに到達したかどうかではない)の確認が必要。(このため、タスクにメッセージが届くまでに無視できない時間が余計にかかりうる。)
l 前項のようなわけで、メッセージの送信で時間切れがおこると送信の失敗を示す確認が送り主に返る。送り主はこれを適切に処理する必要がある。
(例: エレベーター・サブシステムからエレベーター及び各階サブシステムへのエレベーター状態メッセージの送信)
l 返信を待つ型のメッセージ通信。
l 失敗を示す確認は遠隔ノードへメッセージが到達できなかったことを示す。
l この形式の通信は典型的にはクライアント−サーバー間で利用され、前述の遠隔手続き呼び出しと同等。
l クライアントとサーバーが1対1ならば返信つきの通信を示す記号を用いる。
l クライアントとサーバーが多対1ならば、複数クライアント/サーバー間のメッセージ通信を引き起こす。
l <分散的な場合の留意点>可能な限り疎結合なメッセージ通信を用い、密結合メッセージは応答が必要な場合に限る。(応答のない密結合メッセージをサポートする必要はない。)
l 典型的なクライアント/サーバー環境では、複数のクライアントからのメッセージ送信を介してサーバーにサービスを要求する。
l この場合、サーバーにはメッセージキューを作成できる。
l クライアントは密結合メッセージを利用してサーバーの応答を待てる。
l 同時に、クライアントは疎結合メッセージを利用してサーバーの応答以外のメッセージを待てる。
l クライアントはアプリケーションに応じて密結合メッセージ通信でも疎結合メッセージ通信でも利用するが、サーバーの設計には影響を及ぼさない。
l 特に密結合メッセージ通信でクライアントとやり取りしながら、他と疎結合メッセージ通信できる。
メッセージキューを備え、複数のクライアントの要求(応答を待つ密結合メッセージによる)に応えるプロセス計画サーバー。サーバーはFIFOの順でメッセージを処理して応答する。図中のようにOperation Request / Information個々のクライアントとサーバーの間の密結合なやり取りにラベルをつけることがしばしばある。
l 分散アプリケーションではグループ向けの(1対多)通信が有用なことがある。
ブロードキャスト(broadcast): すべての受信者に送信され、受け手は処理するか無視するかを決める。
マルチキャスト(multicast): メッセージを受け取りたいタスクはグループに登録し、登録されたグループ内の全ての受け手に送信される。送信側はグループの個々のメンバーのことは関知しない。
アラーム処理サブシステムはアラームを受け取りたいと思っているオペレーター・サービス・サブシステムのインスタンス全てに同じアラーム・メッセージを送る。
l 分散アプリケーションのサブシステムが決定し、サブシステム間のインターフェースが決定したら、各サブシステムの設計に移れる。
l 各サブシステムは同一ノード上で実行される1つ以上の並行タスクからなる。
l 実時間サブシステムの設計時には(前述した非分散サブシステム用の)DARTS、ADARTSや基本的なCODARTSなどによって各タスクに分解できる。
l 同一サブシステム内のタスク間ではメッセージ通信に加えてイベント同期や情報隠蔽モジュールといった共有メモリに基づく通信が利用可。
l サーバー・サブシステムは分散システムで情報隠蔽モジュール(データ抽象モジュールで隠蔽されたデータストア)に代わる役割を果たす。
l サーバーの提供するさまざまなサービスの一環としてデータストアも取り扱える。
l サーバーはメッセージを介したクライアントの要求に応じてデータストアを読み出し(応答メッセージを返す)たり更新したりしてデータストアを管理する。
l サーバー・サブシステムは関連する複数のデータストアを隠蔽してサービスを提供できる。
l サーバー・サブシステムは自発的に他のサブシステムにサービスを要求することはない。
l 逐次サーバー・サブシステムと並行サーバー・サブシステムの2つを考えることができる。
l 逐次サーバー・サブシステムは、データストアを管理しクライアントからの読み出し/更新要求に応える1個のタスクとして設計される。
l データストアはデータ抽象モジュールによって抽象化される。
l タスクはクライアントからのメッセージを受け取ると、適宜データ抽象モジュールの操作を呼び出す。
l 典型的なサーバー・サブシステムは要求メッセージを受け取るキューを持つ。
l サーバーが提供する各操作に対して各メッセージ・タイプがある。
l サーバー・タスクのメイン手続きは、メッセージタイプに応じて適切な操作を呼び、メッセージをアンパックして得られた引数を渡す。
l 操作はクライアントの要求を処理して適当な応答をサーバー・タスクに返す。
l サーバー・タスクは応答をパックしてクライアントに送り返す。
l サーバー・タスクは遠隔手続き呼び出しにおけるサーバー側スタブと同等。
l クライアントのサービス要求が多いならば、サーバー・サブシステムがボトルネックになる。
→並行タスクで作業を分担する並行サーバー・サブシステム
←並行タスクが効率よくデータ・ストア(例: 2次記憶上のデータ)にアクセスできることを仮定(1つがディスクI/O中に他はCPUを利用しているなど)。
l 並行サーバー内でデータ・ストアへの同時アクセスが発生しうるので同期が必要。最適な同期アルゴリズムはアプリケーションによる。
利用可能なアルゴリズムの例: 相互排他(Mutual Exclusion)、複数読み取り複数書き込み(リーダー/ライターMultiple Readers/Multiple Writers)
l データ・ストアに対する各サービスはそれぞれ別のタスクで実行。
l 各タスクはデータ・ストア(情報隠蔽モジュール)へのアクセスに際してリーダー/ライター方式で同期される。
l Server Supervisorタスクは現在処理中及び処理待ちのサービス要求を管理する。
l Server Supervisorタスクはクライアントからの要求を受信して、処理を読み/書きを行う各タスクへ適当に割り振る。
l 読み出しの手順:
1. サーバー監督タスクがクライアントから読み出し要求を受信。
2. 読み出しタスクに要求を割り振って読者数を示すカウントを+1して読み出しタスクにクライアントのidを渡す。
3. 読み出しが完了すると読み出しタスクが直接応答メッセージをidで示されるクライアントに送り、監督タスクにも通知。
4. 監督タスクは読者数を示すカウントを‐1する。
l 書き込みの手順:
1. 監督タスクがクライアントから書き込み要求を受信。
2. 全ての読み出しタスクが作業を終えている(読者数を示すカウントが0)時にだけ書き込みタスクに要求を割り当てる。
3. 書き込みタスクは相互排他的にデータにアクセスする(完了後は監督タスクに通知)。
4. 書き込みタスクが完了するまで監督タスクは読み出しタスクに要求を割り振らない。
サーバー・サブシステムがデータ隠蔽を行うとデータの集中が起こる。→サーバーがボトルネックになるかもしれない。→解決する方法はデータ分散(分散サーバー、データ複製)。
複数の場所でそれぞれデータを収集し、それぞれで蓄え、そこでのデータに対するクライアントの要求はそこのサーバーが応える。
例: 分散工場自動化システム(Fig. 20.4)のローカルな作業台状態サーバー(Workstation Status Server)は各作業台に対するオペレーターの問い合わせに応える。
データへのアクセスを高速化するために同じデータの複数のコピーを複数の場所で保管・提供する。
局所的な更新が各コピーに反映するように注意する必要がある。
例: 分散化エレベーター制御システム(Fig. 20.3)において、各エレベーター毎にあるエレベーター・サブシステムは局所的に状態と計画データ・ストア(status and plan data store、各エレベーターの状態と停止予定の階)を管理していて、スケジューラー・サブシステムは新たな停止要求が各階のサブシステムから届くとそれらにアクセスして要求に応えるエレベーターを選ぶ。
これを高速化するには、各エレベーター・サブシステムが全てのエレベーターに関する状態と計画データ・ストアを持ち、自身のエレベーターの状態変化と各エレベーター・サブシステム間の変更依頼メッセージによってデータを更新する。
分散アプリケーションが設計されたらインスタンスを定義して構成できる。
システムの構成では、対象システムに応じたインスタンスを作成し、ネットワークで結合され各地に配置された物理ノードへ割り付ける。
システムの構成は以下の3つの手順で行われる。
l 各サブシステム(タイプ)は複数のインスタンスを持ちうるので、必要とされる数のインスタンスを定義せねばならない。
l これらのサブシステムは(インスタンス名、センサー名、センサー限界、警報の種類等で)パラメータ化しておく。
分散化エレベーター制御システム(Fig. 20.3)の例: 各エレベーター・サブシステム(エレベーター数、エレベーターid)と各階サブシステム(階数、階id)
対象システムのアーキテクチャがサブシステム間の通信方法を定める。
この段階で各サブシステム・インスタンスは相互に結合される。
分散化エレベーター制御システム(Fig. 20.3)の例: 階サブシステムは停止要求をスケジューラー・サブシステムに送る。同様にエレベーター・サブシステムはエレベーター状態メッセージを階サブシステムに送る。
2つのサブシステムが別の物理ノードで稼動することも、同一のノードで稼動することもある。
分散化エレベーター制御システムについて考える。
l エレベーター毎のエレベーター・サブシステム・インスタンス: 自律性(あるエレベーター・ノードの故障が他のエレベーター・ノードに深刻な影響を与えない)と適当な効率のため。
l 階毎の階サブシステム・インスタンス: 物理データへの近接のため。階のノードが停止してもその階に停止しなくなるだけで他の階には深刻な影響を及ぼさない。
l スケジューラー・サブシステムは単独のノード: 効率よくエレベータ停止要求に応えるため。スケジューラーが停止(一時的であって欲しいが)しても、既にエレベーターに乗っている乗客は目的階に到着する。
分散処理環境についてもある種の決断が必要。
l 理想: タスク間の透過的なメッセージ通信を提供する分散カーネルを備えた分散オペレーティング・システム
l 理想的環境がない: 分散タスク・マネージャーの開発
l 上のどちらでもない: 設計とコード化の際に具体的な詳細(ノードidや遠隔タスクの指定、ネットワーク通信ソフトウェアの直接利用)を記述する必要がある。