IBM®
本文へジャンプ
    Japan [変更]    ご利用条件
 
 
検索範囲検索:    
    ホーム    製品    サービス & ソリューション    サポート & ダウンロード    マイアカウント    
skip to main content

developerWorks Japan  >  Grid computing  >

アプリケーションのグリッド化に関する 6 つの戦略 第3回:戦略3,4

developerWorks
ページオプション

JavaScript を要するドキュメントオプションは表示されません

原文はこちら

原文はこちら


レベル: 初級

David Kra (dakra@us.ibm.com), Executive IT Architect, IBM

2004年 5月 18日

シリーズのパート 3 にあたるこの記事では、アプリケーションのグリッド化に関する 6 つの戦略のうち、3 番目と 4 番目について説明します。3番目の戦略では、バッチ・プログラムの作業が分割され、複数の独立したプログラム・インスタンスがジョブの一部を個別に並列処理できるようになります。4 番目の戦略では、プログラムは、グリッド・ミドルウェア経由でクライアントから呼び出せる、サービス・サブルーチンとして設定されます。主な目的は、アプリケーションができるだけミドルウェアを意識せずに済むようにすることです。

はじめに

テクニカル・シリーズの最初の記事『アプリケーションのグリッド化に関する 6 つの戦略、パート 1: 概要』では、6 つの戦略に関するシリーズの概要を述べ、各戦略の特性と利点をまとめています。2 番目の記事『アプリケーションのグリッド化に関する 6 つの戦略、パート 2: 「戦略 1: ノード非依存バッチ」と「戦略 2: 独立並行バッチ」』では、この 2 つの戦略を使用してアプリケーションをグリッド化するための方法について説明しています。最初の戦略では、アプリケーションをグリッド内の任意のコンピューター上で単一ジョブとして実行できるようにします。2 番目の戦略では、アプリケーションの複数の独立インスタンスを並行して実行できるようにします。シリーズの 3 番目に該当するこの記事は、「戦略 3: 並列バッチ」と「戦略 4: サービス」によるグリッド化について説明しています。特に注意すべきなのは、この 2 つの戦略は相互に排他的であり、どちらかを選択しなければならないという点です。戦略 5 によるグリッド化については後続のシリーズで説明しますが、戦略 3 と戦略 4 のどちらを使用しても、目標は達成できます。このシリーズのパート 4 では、アプリケーションがサービスを並列使用するときに活用できる、新しいパラダイムについて説明します。

6 つの戦略の関係については、図 1 を参照してください。


図1. 6 つの戦略
6 つの戦略



上に戻る


戦略 3: 並列バッチ

既に説明したように、「戦略 2: 独立並行バッチ」では、ユーザーごとに複数のインスタンスが実行されます。

「戦略 3: 並列」では、バッチ・ジョブは分割されます。並行して実行される独立した複数のサブジョブは、ユーザーが実行したジョブの集合に相当します。

戦略 3 には、次のような特性があります。

  • プログラム機能を、1 台のクライアントと複数のサーバーのジョブに分割できる。
  • クライアントは、ジョブの集合をより小さい単位のサブジョブに分割してサーバーに分散できる。
  • グリッドによって、処理をノードに分散できる。
  • サーバー・ジョブは、複数の独立インスタンスとして動作する。
  • クライアントは、結果を収集した後で、最終的な結果を取りまとめることができる。

図 2 は、ノード間でのサブジョブの分割を示しています。


図2. サブジョブの分割
サブジョブの分割

戦略 3 の基本ケース・スタディーで取り上げるプログラムは、コマンド行パラメーターを取得して、コマンド行パラメーターで指定されたファイルとデータベースを使用するプログラムです。戦略 1 と戦略 2 にはグリッド化のための属性が必要ですが、このプログラムには、これらの属性は既に設定されています。「クライアント」と「サーバー」という用語を使用する場合、このプログラムは、実行時にクライアントによって分割されたサーバー・サブジョブ・プログラムを指します。次の図 3 を参照してください。対象がライセンス・プログラムに該当する場合についても考慮しています。


図3. グリッド環境におけるクライアントとサーバー
グリッド環境におけるクライアントとサーバー

サーバー処理、クライアント、および集約

戦略 3 におけるグリッド化の対象となるのは、次の 3 つの領域です。

  • ビジネス・アプリケーション機能を実行するサーバー・プログラム。
  • 処理をサブジョブに分割するクライアント・プログラム。
  • 結果を集約するクライアント・プログラム。

この戦略を使用すると、サーバー・サイドのビジネス・プログラムは実行用の特定のグリッド・ミドルウェアに伴う制約から解放されます。

「戦略 3: 並列バッチ」を使用したグリッド化の利点

戦略 3 の目標は、次のような処理を可能にすることです。

  • より小さな作業単位に分割し、複数のマシンに分散させる。
  • 作業全体をより迅速に完了する。
  • 作業のサブユニットや実行マシンの障害に対する回復力を高める。再実行が必要な対象を、ジョブ全体ではなく、障害の発生したサブユニットに限定する。

分割、処理、および作業の集約

明白な場合を除いては、作業を分割するクライアント・プログラムの例を提供し、別の要素が後続の分散処理を実行できるようにする必要があります。別の要素とは、運用や開発を担当するチームによって選択されるグリッド・ミドルウェアを指しています。統合や展開を担当するチームは、選択したランタイム環境にこの例を適合させます。

個々の実行ごとにジョブの一部が処理されるように、サーバーのビジネス機能プログラムとそのパラメーターを調整する必要があります。アルゴリズムは、グリッド内での使用方法に応じて最適化することができます。例えば、単一のマシンのみを使用する場合は、処理に時間のかかるアルゴリズムは変更したほうがよいかもしれません。一方、複数のマシンを使用する場合は、アルゴリズムをスケールアップしたほうがよい結果が得られることもあります。

処理結果は、集約しない限り、出力ファイルを任意の順序で結合しただけのものです。したがって、結果を集約するサンプル・クライアント・プログラムを別に用意する必要があります。




上に戻る


クライアント

次のような処理に対応するクライアント・プログラムや、プログラムとシェル・スクリプトのセットを、サンプルとして用意する必要があります。

  • 実行する作業全体を複数のサブユニットに分割し、グリッド・ミドルウェアで処理ノードに分散できるようにする。サブユニットの数は、グリッド処理ノードの数よりも多くなります (10 倍程度まで)。
  • サブユニットの種類と、サブユニットごとに 1 回メイン・サーバー・アプリケーションを実行する必要があるという点を、グリッド・ミドルウェアに通知する。

集約が必要な場合、クライアントを実行するシェル・スクリプトは次のような処理も行います。

  • グリッド・ミドルウェアを起動し、結果を収集する。
  • サブユニットの結果を集約するサンプル・プログラムを起動する。

アプリケーションを配置するユーザーは、ターゲット環境に応じてサンプルのクライアント・プログラムとシェル・スクリプトを調整する必要があります。




上に戻る


グリッド・ミドルウェア

グリッド・ミドルウェアは、次のような処理を行います。

  • 作業のサブユニットを処理ノードに分散させる。
  • すべてのサブユニットが正常に実行されていることを検証する。
  • 結果の集約を支援する。結果を集約の中心的スポットに返すか、少なくともアクセス可能にします。



上に戻る


特定のグリッド・ミドルウェアの独立性維持

グリッド・ミドルウェアをサーバー・サイド・アプリケーションで使用することは、できるだけ避けてください。通常、グリッド・ミドルウェアはサーバー・アプリケーションの実行に十分な機能を備えています。グリッド・ミドルウェアは、セキュリティー、権限、リソースのアクセス可能度、環境変数などを処理します。これらの処理が終了した時点で、アプリケーション・プログラムが実行されます。

以下のサブセクションは、クライアントと、なんらかの理由でグリッド環境を利用する必要があるサーバー・アプリケーションにのみ適用されます。

グリッド対応アプリケーションの構築用および実行用として、複数の製品、ツールキット、プログラミング・インターフェースが用意されています。その中から、サーバー・アプリケーションの構築に適したものを選択する必要があります。

運用チームが選択した環境に応じて、アプリケーションの配備と実行に最適なものを使用してください。アプリケーションは、可能な限り、特定のミドルウェアに依存しないように設計してください。

クライアントとサーバーは、ミドルウェアの動作範囲で、ミドルウェア固有の用途を置き換え可能なコンポーネントに分離する必要があります。該当するコンポーネントを適切に分離しておけば、ターゲット環境へのアプリケーションの統合と配備を担当するチームは、コンポーネントを作成して置き換えることができるようになります。このようなモジュール性により、配備を担当するチームはソース・コードにアクセスする必要がなくなります。これらの中間コンポーネントは、コードとミドルウェアの間に挿入された詰め木 (パターン用語では「ラッパー・ファサード」) の役割を果たします。

アプリケーション A とグリッド・ミドルウェア M1、M2、および M3 があると仮定します。グリッド・ミドルウェア固有のコードを持つプログラム・パーツは、置き換え可能なインターフェース・ライブラリー Ln に分離する必要があります。すべての Ln は、アプリケーション A に対するインターフェースと同じものを公開できます。Ln ライブラリーは、次の要領でミドルウェア固有の Mn API を呼び出します。

  • A が L を呼び出します。グリッド・ミドルウェア M1 を使用する場合、L1 がその呼び出しを捕捉して M1 を呼び出します。
  • A が L を呼び出します。グリッド・ミドルウェア M2 を使用する場合、L2 がその呼び出しを捕捉して M2 を呼び出します。
  • A が L を呼び出します。グリッド・ミドルウェア M3 を使用する場合、L3 がその呼び出しを捕捉して M3 を呼び出します。

ライブラリー L1、L2、および L3 内で公開されている関数は、すべて同じ名前です。ただし、各ライブラリー内では、ミドルウェアの呼び出しに使用されるコードは、対象ミドルウェア固有のアプリケーション・プログラミング・インターフェースに応じて異なります。

アプリケーション A に対する変更はありません。アプリケーション A は特定のグリッド・ミドルウェア、つまりアプリケーション A で使用する L については認識しません。アプリケーション A は再コンパイルの対象にはなりません。インテグレーターおよびデプロイヤーは、グリッド・ミドルウェア M を選択して、適切な置き換え可能ライブラリー L を作成します。ミドルウェア・インスタンスについては、コンパイル済みの状態とソース形式の状態でそれぞれテストを実施した L1 を用意する必要があります。これに基づいて、デプロイヤーは L2、L3、および以降のライブラリーを作成することができます。




上に戻る


サーバー

「戦略 3: 並列バッチ」を実装するには、バリアブル・ミッドグレーン、非干渉性と独立性、およびライセンス交付という、アプリケーションおよび使用方法に関連する 3 つのトピックを考慮する必要があります。

バリアブル・ミッドグレーン

サーバー・プログラムを調整する際には、各実行で処理される作業項目の数について、クライアントによる指定を許可することをおすすめします。このミッドグレーン型のアプローチでは、設定の余地を残すことによって、ベスト・プラクティスを実現できます。稼働サーバー 1 基につき 1 つの作業単位という緻密なアプローチは、次に示すように非効率です。

  • クライアントが処理を個別項目に分割しなければなりません。
  • ミドルウェアは、項目ごとに、サーバー・プログラムの優先順位付け、スケジューリング、および起動を行う必要があります。
  • サーバー・プログラムは、項目ごとに、プログラムの開始と終了のハウスキーピング処理を行う必要があります。

このような非効率性は大きなデメリットです。

各サブユニットに含める項目数をクライアントが指定できるようにすれば、運用チームは、サブユニットの数やサイズを最適化することができます。また、ジョブ特性、グリッド・ミドルウェア、グリッド内のシステム、および作業項目のサイズを調整することもできます (作業項目はアカウント別の処理に該当する場合があります。その場合、アカウントによっては月次単位で他のアカウントよりも多くのアクティビティーが発生する可能性があります)。例えば、処理能力に差のあるノードで構成されたグリッドでは、平均的でサイズ変更可能な実行によってサイズの差異による影響は軽減され、処理の実行中にほぼすべてのノードを活用することができます。

非干渉性と独立性

戦略 2 によって、ユーザー別の処理実行に伴う干渉の問題は解決されました。シングル・ユーザーで複数のサブジョブを同時に実行する場合を考慮すると、同様の問題は戦略 3 でも発生します。サブジョブが相互に干渉する状況は避けなければなりません。

既に述べたように、トランザクションの資源を使用するときは、デッドロック・パターンの発生を防ぐ必要があります。

また、データベース・ホット・スポットなどのミドルウェア・ホット・スポットが発生しないようにする必要もあります。共用されている行はできるだけ更新を避けてください。更新しなければならない場合は、短時間であっても保留ロックを使用しないようにします。

独立性が特に適用されるのは、Monte Carlo シミュレーションです。Monte Carlo シミュレーションでは、各サブジョブの乱数シードは、アプリケーションごとにまったく異なるか、または正確に一致する必要があります。「まったく異なる」という表現に該当するのは、n = {2, 3, 4, 5, ...} シードのセットを事前に計算するような場合です。作業が n 個のサブユニットに分割されていれば、n のシードはジェネレーターのシーケンスに沿って均等に分散されます。ほとんどの事例では、ランタイム・パラメーターではない場合、乱数シードをパラメーターとして受け付けるようにアプリケーションを変更する必要があります。

ライセンス交付

ライセンス交付の観点から、並行性の問題は戦略 2 で考慮されています。詳細は、前回の記事のパート 2 (『参考文献』のリンク参照) をご覧ください。ただし、並列バッチでは、新たな状況に対処するために、ライセンス管理ソフトウェアが必要になる場合があります。例えば、アプリケーションのライセンスがマシン・ユーザー単位ではなく、ユーザー単位で交付されている場合について考えます。あるユーザーが 3 台のマシンを利用し、別のユーザーが 4 台のマシンを利用している場合、ユーザー単位で必要なライセンス数は 2 であり、7 ではありません。




上に戻る


統合サービス

処理結果は、集約しない限り、出力ファイルを任意の順序で結合しただけのものです。したがって、結果を集約するプログラムを別に用意する必要があります。ただし、結果を 1 つの場所に集めるのは、集約プログラムのジョブではありません。結果を集めたり、リモート・アクセスを可能にしたりするのは、グリッド・ミドルウェアの役割です。

集約プログラムから直接アクセスできる場所 (例えば、ファイル・システムや URL) に集約対象コンテンツが配置されている場合、プログラムがグリッド・ミドルウェアと連携する必要はありません。この場所は、統合サービスに対する入力パラメーターとして指定されます。統合サービスによってグリッド・ミドルウェアを起動しなければならない場合、プログラマーは、前述の「特定のグリッド・ミドルウェアの独立性維持」で説明されている方法に従って、ミドルウェア固有のコードを分離する必要があります。




上に戻る


戦略 3 の要約

サーバー・アプリケーション・コードのグリッド化は、わずかな追加設定で実現できます。

次のポイントに留意してください。

  • 分割。クライアント・プログラムは、実行する作業を分割して、処理用のグリッド・ミドルウェアに送信する必要があります。
  • 部分処理。サーバー・プログラムの各インスタンスは、別のインスタンスが他の部分を処理している間に、担当部分の処理を行う必要があります。
  • 非干渉性と独立性。サブジョブは独立している必要があり、相互に干渉する状況は避けなければなりません。
  • 集約。プログラムまたはユーティリティーは、すべてのサブジョブの結果を集約できる必要があります。
  • ライセンス交付。対応は不要です。ライセンス交付をユーザー単位で行う場合にのみ、アプリケーションがライセンス数の超過をチェックしていないことを検証してください。



上に戻る


戦略 4: サービス

「戦略 4: サービス」では、「サービス」という用語は「Web サービス」および「グリッド・サービス」の代わりに使用されます。この 2 つの用語には、オープン・スタンダード固有の意味があるからです。戦略 4 にはこの 2 種類のサービスが含まれますが、他のサービス指向アーキテクチャーをグリッド環境に実装する際にも、これらのサービスが適用されます。

「戦略 4: サービス」には、次のような特性があります。

  • クライアントは、グリッド・ミドルウェアを使用してサービスを呼び出す。
  • クライアントの代わりに、グリッド・ミドルウェアがサービスを呼び出す (必要に応じて、サービスを呼び出す前にメモリーにロードする)。
  • サービスは呼び出し可能で、通常はクラス、サブルーチン・ライブラリー、DLL として構造化される。
  • クライアントとサーバーの間は疎結合である。
  • サービスは独立したクライアント間で共有されることがある。
  • サービスはその状態を呼び出し間で維持できる。
  • サービスの実行時間が長く、1 回の実行で何度も使用され、かつ初回使用の前に開始される場合は、サービス開始に要する時間の長さは問題にならない。

図4. 「戦略 4: サービス」でサービスを呼び出すクライアント
「戦略 4: サービス」でサービスを呼び出すクライアント

「戦略 4: サービス」は、グリッド化のための「戦略 2: 独立並行バッチ」から発展したものですが、並列処理だけではなく、「戦略 3: 並列バッチ」の属性もほとんど備えています。ただし、戦略 3 および戦略 4 の両方を逐次実装するよりも、どちらかの戦略を選択したほうがよいという点にあらためて注意してください。

戦略 4 の基本ケース・スタディーで取り上げるプログラムは、コマンド行パラメーターを取得して、コマンド行パラメーターで指定されたファイルとデータベースを使用するプログラムです。このプログラムには、戦略 1 と戦略 2 でグリッド化のために必要とされる属性と、戦略 3 の属性の大部分が既に設定されています。「クライアント」と「サーバー」という用語を使用する場合 (図 1 を参照)、このプログラムは、グリッド・テクノロジーを使用するリモート・クライアントによって呼び出すことのできるサーバー・サブルーチンを指します。

「戦略 4: サービス」を使用したグリッド化の利点

戦略 4 の目標は、サーバー・アプリケーションを、なんらかの形式のリモート・プロシージャー・コールのターゲットとして設定できるようにすることです。クライアントは、ミドルウェアを使用してサービスを呼び出します。次に、ミドルウェアがサービスを呼び出します (必要に応じて、サービスを呼び出す前にメモリーにロードします)。

このグリッド化が可能なのは、グリッド・ミドルウェアによる選択に基づいて、サービスが前段階のグリッド対応化レベルの特性 (例えばグリッド内の複数のマシン上で実行可能であるなど) を達成している場合です。望ましいのは、バッチ処理のスケジューリングや、プログラムの開始と終了に伴うハウスキーピング処理を繰り返し実行しなくても、何度もサービスを呼び出せるようにすることです。

例えば、数秒間隔でライセンス・チェックを実行し、外部参照データから数ギガバイト規模のデータ構造をメモリーに構築して入力情報を処理する必要があるような、サーバー・アプリケーションについて考えます。入力情報の処理は、1 秒未満で終了するという前提です。サービスとして設定しておけば、さらに独立性の高い要求であっても、単一のサービス・インスタンスを分単位で処理できるようになります。

「戦略 4: サーバー」におけるサーバーのフォーカス

現在のサービスに加えて他のサービスも活用して、クライアントが新しいビジネス機能を構成できることもあります。戦略 4 は、グリッド・ミドルウェア経由でビジネス機能を要求するクライアントではなく、ビジネス機能を実行するサービス・プログラムに焦点を当てています。機能分割のベスト・プラクティスを達成するには、クライアント・アプリケーションとグリッド・ミドルウェアの書き込み、実装、および配置を、別のユーザーのジョブとして行います。

ただし、サブルーチン・ライブラリーを提供するときは、サービスの適切な使用方法を示すサンプル・プログラムを提供する必要があります。




上に戻る


サービスの設定

サービスとして設定するには、外部呼び出し可能な関数やサブルーチンを設定できる機能がプログラムに必要です。機能は単一でも複数でもかまいません。入出力は、パラメーターとして指定する必要があります。

グリッド拡張による WSDL のサービス定義

将来的な標準規格適合性を考慮して、Web サービス記述言語 (WSDL) に対応したグリッド拡張を定義可能にしてください。パラメーターは XML データ型で指定してください。実績を積むまでは、基本的なデータ型を使用することをおすすめします。

WSDL 形式で定義可能であるということは、サービス用に WSDL コードを作成するということではなく、単に WSDL コードの作成を容易に行えるという意味です。専用スキーマの作成や文書化は必須ではありません。Web サービスや OGSA 環境で配備する際、クライアントがサービスを要求し、グリッド・ミドルウェアがそのサービスを呼び出せるようになります。

可能であれば、サービスのソース・コードから WSDL を生成できるツールを使用して、サービス用の WSDL コードを作成することをおすすめします。開発、テスト、配備、ディレクトリー、クライアント・サイド、およびサーバー・サイドを担当する多くのユーザーや対応ツールが、さまざまな目的に応じた WSDL を使用できるようになります。

再使用性

いったんロードされたパブリック機能は、実際に再使用可能である必要があります。再使用が不可能な場合、グリッド・ミドルウェアは、プログラムを使用するたびにアンロードとロードを行わなければならず、そのたびに初期化と終了に伴うハウスキーピング処理が発生します。少なくとも、サービスは逐次再使用可能でなければなりません。逐次再使用は、グリッド・ミドルウェアがクライアントの要求に応じて後続の機能の受け渡しに対応できることを意味します。要求元のグリッド・ミドルウェアで機能を実行する場合は、対象となる機能を再使用可能にして、スレッド・セーフな設計にする必要があります。例えば、Globus Toolkit 3 は逐次再使用可能でなければなりません。

アレイ・サービス

サービスを作成する際には、個別サービスとアレイ・サービスの両方を用意する必要があります。個別サービスは単一の項目を処理し、アレイ・サービスは複数の項目に対応するサービスを実行します。この両サービスにより、クライアントは、複数の項目に関する要求を作成する際のオーバーヘッドを償却できます。

再使用可能サービスと個別プログラム実行の相違点

環境変数はサービスの開始前に設定されますが、サービス要求ごとに変化することはありません。元のプログラムが実際の要求ごとに環境からパラメーターを取得して利用している場合は、そのパラメーターを関数パラメーターに変換する必要があります。要求ごとに変化しない環境変数は、そのまま維持する必要があります。

ストリーム、標準入力、標準出力、および標準エラー出力は、サービスがクライアントから入力を受信して出力やエラー情報を返信する場合の一般的な方法ではありません。このようなメカニズムを使用してユーザー・プログラム情報を交換する場合は、ストリング・パラメーターなどの代替手段に置き換えることを強くおすすめします。エラー情報の一部をクライアントに返さなければならない場合もありますが、多くは、サービスやグリッド・アドミニストレーターによるエラー分析用として保持されます。ただし、Data Synapse 社が提供するグリッド・ミドルウェアのように、クライアントから標準入力を送って、サービスから標準出力と標準エラー出力を返す、という前提があるものもあります。

言語およびオペレーティング環境によって規定される名前と動作

プログラミング言語によっては、main という名前はメイン・プログラムにのみ指定可能で、サブルーチンには指定できません。必要に応じて、main という名前を main_function など他の名前に変更してください。また、次のような関数を追加しなければならない場合もあります。

  • MS Windows では、DLL に DllMain 関数が必要です。この関数は、処理の開始時と終了時、すなわち最初のサービス要求を受け付ける前と最後のサービス要求が完了した後に呼び出されます。
  • Globus Toolkit 3 (GT3) では、プログラムに initialize 関数と getOperations 関数が必要です。

前述の関数の標準バージョンをプログラムに貼り付けて、必要に応じて拡張することができます。環境に依存しない関数を記述して、必須の環境固有の関数から呼び出すこともできます。例えば、次のコードでは、DllMain in Windows の DllMain と GT3 の initialize によって anyway_loaded が呼び出されます。

プラットフォームとグリッド・ミドルウェアの独立性

コードをプログラムに直接挿入するだけで、環境固有の機能を利用できます。これにより、プラットフォームやミドルウェアに左右されることはなくなりました。ただし、特定の環境においてのみ呼び出すことのできる関数を追加で設定することも、一般的な手法です。

複数ある環境のそれぞれに関数を提供することは、環境に依存しないプログラムというよりは、マルチプラットフォーム対応のプログラムの実現につながります。従来の非グリッド対応の事例では、アプレットであると同時にアプリケーションでもある、 マルチスレッドのクライアント・サイド Java プログラムが採用されてきました。

これに代わる手段としては、プラットフォーム固有のコードを別のソース・モジュールに分離して、システム・インテグレーターやデプロイヤー側で修正可能にすることをおすすめします。アプリケーション固有コードのソース・コードを用意する必要はありませんが、プラットフォーム固有コードのサンプルは用意しなければなりません。C 言語では、前述のような関数は個別のモジュールとして設定され、アプリケーションのオブジェクト・コードにリンクされて、DLL またはライブラリーを形成します。Java コードでは、フレームワーク固有の関数はコードが継承するスーパークラスによって提供されます。一般的な非グリッドの事例では、 javax.servlet.http.HttpServletではなく org.apache.struts.action.ActionServletを拡張するサーブレットが採用されています。

初期化と終了

初期化の際に 1 回実行するだけでよい処理は、サービス要求ごとに繰り返し実行するべきではありません。これに該当する処理としては、参照メモリー構造のロード、他システムを対象とする検出および接続などが挙げられます。後でプログラムがこれらの結果を使用するとき、接続が切断されている場合には、資源の再割り当てと再接続で対処できます。さらに、サービス・プログラムは、オペレーティング・システムまたはグリッド・ミドルウェアから終了通知を受信した時点で、資源を解放する必要があります。リスト 1 は、モデルとして使用可能なサンプル・コードを示しています。


リスト1. 多用途の初期化および終了コード
                

// Treat this as pseudocode.  C and Java code are intermixed 
// C
int main_function (int argc, char *argv[ ]) 
{ anyway_loaded ( );
  do_job_function (int argc, char *argv[ ]);
  anyway_terminated ( );
 }

void anyway_loaded ( ) { /* do one time initialization housekeeping */ }

do_job_function (int argc, char *argv[ ]) { /* do job's work */ }

/* recommended new function */
do_item_function (int argc, char *argv[ ]) { /* do one item's work */ } 

/* recommended new function */
do_item_array_function (int argc, char *argv[ ]) { /* do several item's work */ } 

void anyway_terminated ( ) {  /* do one time termination housekeeping */  }

/* begin: for Windows DLL */
int DllMain (hModule, fwdreason, ipReserverd)
{/* Runs at process/thread  attach/detach. Does DLL specific housekeeping */:
if (fwdreason==PROCESSATTACH)  
 {anyway_loaded ( )}
else
 {anyway_terminated ( );  return completion_code;  }
}
/* end:  for Windows DLL */

/* begin: for GT3 OGSA 
see http://gdp.globus.org/
                
                
and http://wiki.nesc.ac.uk/read/pa9?UsingOGSA
*/
// Java
public void initialize(GridServiceBase base) throws GridServiceException 
{ this.base = base; anyway_loaded ( ) }

public void preDestroy(GridContext context) throws GridServiceException 
{ anyway_terminated ( ) }
/* end:  for GT3 OGSA */
}


複数インスタンス

「戦略 2: 独立並行バッチ」と同様に、同一のサーバーや別のサーバーにロードされたときに、サービス・ルーチンに複数の独立インスタンスが存在する場合があります。

サービス自体やサービスの使用方法に特殊な要素がない限り、グリッド・ミドルウェアが複数のサービス・インスタンスを呼び出す可能性を考慮する必要があります。戦略 2 におけるグリッド化の要件はすべて、戦略 4 にも適用されます。

また、サービス呼び出しとサービス呼び出しの間、ユーザー情報やその他の状態情報がサービス側で保持されるようにする場合は、次のいずれかの処置を行う必要があります。

  • 実行環境を OGSA などに限定して、クライアントからの各サービス要求が同じインスタンスに送信されるようにする。
  • 他のインスタンスから取得できる場所に情報を保持する。前回のサービス要求が別のインスタンスによって処理された場合は、その場所から状態情報を取得するように各インスタンスを設定する必要があります。

サービスの 1 つのインスタンスが 3 つのノードのそれぞれで実行され、3 つのインスタンスを構成しているように見える事例について考えてみます。各クライアントは、関連する一連のサービス要求を行います。サービスがステートレスである場合や、いずれかのリポジトリーから状態を取得できる場合は、着信したサービス要求を任意のノードに割り当てることができるロード・バランサーが存在する限り、クライアントからは、単一のサービス・インスタンスのみが存在するように見えます。これは、サービスに単一の公開アドレスが設定されているからです。したがって、可用性やスループットが改善される点を除き、複数のアドレスを設定することに特に意味はありません。

複数ユーザー

サービス・インスタンスへの複数クライアントの設定は、グリッド・ミドルウェアのランタイム環境に応じて、サポートされない場合、オプションの場合、および必須の場合があります。サポートされない場合は、設定の有無にかかわらず、単一のユーザーのみがサービスの各インスタンスを使用します。必須の場合は、複数のユーザーを処理できるように各プログラム・インスタンスを設定する必要があります。

プログラムが複数のユーザーを処理するときは、セキュリティーの処理を変更しなければならない場合もあります。サービスは、前回処理したユーザーに関する情報を消去するか、保存しておく必要があります。前回処理したユーザーが別の要求を依頼した場合についても同様です。環境内のセキュリティーはクライアントによるサービスの呼び出しの可否を制御します。ただし、ユーザー X のクライアント・プログラムが、ユーザー Y のアカウント番号に関するサービス要求を出す権限を持っているかどうかは、判定することができません。このように細分化された権限に関しては、サービス自体が適宜対応する必要があります。プログラムが使用する資源に応じて、汎用的なサーバー・ユーザー ID (griduser4 など) を使用する代わりに、ユーザー間のセキュリティー・コンテキスト (例えば、クライアント・ユーザー ID) をプログラム側で変更する必要があります。

複数のユーザーをサポートする単一インスタンスについて考慮すべきもう 1 つの点は、並行性の問題です。グリッド・ミドルウェアまたはプログラム環境では、各サービス・インスタンスで同時に有効なサービス要求が常に 1 つだけの場合、逐次再使用が可能です。その他の場合は、プログラムは十分にスレッド・セーフな状態である必要があります。その他の多くのマルチユーザー・サービス環境、例えば Web アプリケーション・サーバーやトランザクション処理システムなどの場合と同様に、スレッド・セーフな状態であるということは、「コードが明示的に新しいスレッドを開始しない場合であっても、ランタイム環境でこの開始処理が実行される可能性が考慮されている」ということです。

ライセンス交付

プログラムがライセンス交付の対象である場合は、状況に応じて、使用単位などの新しいライセンス交付モデルを検討して採用する必要があります。その場合、サービス要求の呼び出しやクライアントからの関連サービス要求一式など、利用の構成要素を決定することができます。

クライアント定義とインターフェース定義の提供

サーバー・サービスを呼び出すクライアント・プログラムのサンプルを提供する必要があります。この例では、1 回だけ使用されるサービスを示すだけでなく、サービスの適切な使用順序、ループ、および配列も示す必要があります。統合や展開を担当するチームは、選択したランタイム環境にこのサンプル・クライアントを適合させます。ソリューション・アセンブラーのクライアント・プログラムがサービスを使用するとき、ソリューション・アセンブラーは、この適合済みクライアントを開始点として使用します。

クライアントとサーバーのプログラムの疎結合

クライアントは、グリッド・ミドルウェアを使用して、サーバー・アプリケーション・サービスの検索、起動、接続を安全に行える必要があります。また、ミドルウェア経由で個別のサービス要求を送信できることも必要です。ただし、グリッド・ミドルウェアが意図するのは、クライアントとサーバー・プログラムの疎結合です。通常、クライアントからグリッド・ミドルウェアを経由するサービス要求は毎秒 1 つ未満です。

Web サービスと同様に、グリッド・ミドルウェアを経由したサービス呼び出しは、ソケットや名前付きパイプのプログラミング・インターフェースを介した独自形式のメッセージ送信と比較すると、コストがかかります。クライアントとサーバーとの間で大量の対話処理が往復する状況は、回避する必要があります。なんらかの理由で回避できない場合は、CORBA や IIOP 上での Java リモート・プロシージャー・コールなど、(Web サービスと比較して) 効率的なメカニズムを介して処理します。サーバー・アプリケーション・サービスの検索、起動、および接続は、グリッド・ミドルウェアを使用して安全に行ってください。他の手段を使用するのは、フロント側とサーバーとの間で高レートな相互通信が必要な場合に限定することをおすすめします。

ネットワーク上のサービス要求の量を抑える方法として、複数の要求をまとめてから、同時に着信した要求を一括処理する配列サービスを呼び出すという方法があります。これについては、「サービスの設定」で説明しています。

ツール

多くのグリッド環境では、開発ツールと配置ツールが、サービス・ソース・コード、WSDL、インターフェース定義、ヘッダー・ファイルなどから、クライアント・スタブ・プログラムやその他の要素を直接作成します。例えば、The Globus Toolkit 3 Programmer's Tutorial には、ツールを使用して柔軟なサービス・オペレーション・プロバイダーを作成する方法について説明されています。この技法をオープン・ソースの SWIG ツールと組み合わせると、C 関数からの GT3 OGSA サービスの作成を支援することができます。リスト 2 は、SWIG 制御ファイルにアプリケーション固有の要素がないことを示しています。SWIG制御ファイルは、生成された Java ラッパーに追加する要素を指定するファイルです。IBMServer Allocation for WebSphere&reg: Application Server の ParallelProgramming Environment 対応ツールにも、同様の機能が備わっています。


リスト2. C 言語サブルーチン・ライブラリーを T3 OGSA に適合させるための汎用 SWIG 制御ファイル
                
/* 
See the resources section of this article for links to source material for this listing:
	OGSA Service Provider tutorial
	Wiki tips on using OGSA
	GT3 reference material about OperationProvider and
		GridServiceCallback
	Simplified Wrapper and Interface Generator (SWIG)
*/ 

%pragma(java) jniclassimports=%{
import org.globus.ogsa.GridServiceBase;
import org.globus.ogsa.GridServiceCallback;
import org.globus.ogsa.GridServiceException;
import org.globus.ogsa.OperationProvider;
import org.globus.ogsa.GridContext;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
%}

%pragma(java) jniclassinterfaces="OperationProvider, GridServiceCallback"

%pragma(java) jniclasscode=%{
private static final QName[ ] operations = new QName[ ]{new QName("", "*")};
private GridServiceBase base = null;
private ServiceDataSet serviceDataSet = null;
public void initialize(GridServiceBase base) throws GridServiceException {
 this.base = base; serviceDataSet = base.getServiceDataSet( );     }
public QName[ ] getOperations( )  {return operations;}
public void preCreate(GridServiceBase base) throws GridServiceException { }
public void postCreate(GridContext context) throws GridServiceException { }
public void activate(GridContext context) throws GridServiceException { }
public void deactivate(GridContext context) throws GridServiceException { }
public void preDestroy(GridContext context) throws GridServiceException { }
%}			


「戦略 4: サービス」の要約

サーバー・アプリケーション・コードをサービスとしてグリッド化する作業は、わずかな追加設定で実現できます。

次のポイントに留意してください。

  • サービスの設定。プログラムは、逐次再使用可能なサービスで構成される、外部呼び出し可能なサブルーチン・ライブラリーとして設定する必要があります。
  • 集約。各サービスには、項目の配列を処理するマッチング・バージョンが必要です。
  • 入力ソース。サービスの詳細は、標準入力、標準出力、および標準エラー出力としてではなく、パラメーターとして受け渡しする必要があります。
  • 特殊な名前。プログラムは規定に従って命名する必要があります。
  • 初期化と終了。各サービス要求の処理中に特に必要がない限り、プログラムは開始時または終了時に 1 回だけ実行します。
  • 複数インスタンス。サービスには複数のインスタンスが存在していると想定します。
  • 複数ユーザー。サービスには複数のユーザーが存在していると想定します。場合によっては、各インスタンスに複数のユーザーが同時に存在している可能性もあります。
  • ライセンス交付。特にありません。状況に応じて、「使用単位」ベースのライセンス交付を検討することもできます。


参考文献



著者について

Author photo

David Kra is an executive IT architect in IBM's Grid Computing organization. David has spent his 27-year IBM career guiding customers' distributed computing projects from the application layer down to cabling and from requirements through deployment. His scalable, high-volume, and high-availability communicating solutions have involved several non-IBM platforms and almost every IBM platform since the 1970s. He is a member of the IBM Academy of Technology.




記事の評価


サイト改善のため、ご意見をお寄せください。こちらのフォームからお願いいたします。



はいいいえわからない
 


 


54321
大変素晴らしい不充分・不完全である
 


上に戻る


    日本IBMについて プライバシー お問い合わせ