以下、本発明の実施の形態につき図面を参照して説明する。
[第1の実施形態]
図1は本発明の第1の実施形態に係るクラスタシステムの構成を示すブロック図である。
図1に示すクラスタシステムは、3台以上のサーバ計算機、例えば3台のサーバ計算機(以下、ノードと称する)10-1,10-2及び10-3から構成される。図1の例では、ノード10-1は稼動系ノードとして動作し、ノード10-2及び10-3は待機系ノードとして動作しているものとする。ノード10-1〜10-3は、ネットワークのような通信路20によって相互接続されている。
ノード10-1〜10-3では、それぞれオペレーティングシステム(OS)11-1〜11-3が動作する。ノード10-1〜10-3ではまた、当該ノード10-1〜10-3が稼動系ノードである場合に、アプリケーション(アプリケーションプログラム)12-1〜12-3が動作する。アプリケーション12-1〜12-3は、ノード10-1〜10-3がクライアントに対して特定のサービスを提供するために、当該ノード10-1〜10-3において実行される。このため図1の例では、ノード10-1〜10-3上のアプリケーション12-1〜12-3のうち、稼動系ノード10-1上のアプリケーション12-1のみが動作しており、待機系ノード10-2及び10-3上のアプリケーション12-2及び12-3は停止している。アプリケーション12-1〜12-3が実行されることによって提供されるサービス(サービスの種類)は同一である。
ノード10-1〜10-3は、それぞれ、クラスタ管理部13-1〜13-3及びアプリケーションプログラムインタフェース情報記憶部(以下、API情報記憶部と称する)14-1〜14-3を有する。第1の実施形態においクラスタ管理部13-1〜13-3は、通信路20を介して連携することにより、ノード10-1〜10-3のクラスタ構成を管理する。ノード10-i(i=1,2,3)のクラスタ管理部13-iは、ノード10-i内の図示せぬCPUが、ディスクのような記憶媒体に格納されているクラスタソフトウェアと呼ばれるソフトウェアプログラムを例えば当該ノード10-i内の主メモリに読み込んで実行することにより実現されるものとする。
図2は、ノード10-i(i=1,2,3)の構成(特にノード10-i内のクラスタ管理部13-iの構成)を示すブロック図である。クラスタ管理部13-iは、クラスタ制御部131、アプリケーション制御部(以下、アプリ制御部と称する)132、監視部133、アプリケーションプログラムインタフェースフック部(以下、APIフック部と称する)134及び評価部135を含む。
クラスタ制御部131は、アプリ制御部132、監視部133、APIフック部134及び評価部135を制御することによって、クラスタシステム内のノード10-1〜10-3のクラスタ構成を制御する。クラスタ制御部131は、他のノードのクラスタ制御部131と通信路20を介して相互に通信を行うことで、他のノードの障害を検知する。このクラスタ制御部131相互間のノード障害検知のための通信はハートビート通信と呼ばれる。
アプリ制御部132は、クラスタ管理部13-1の制御の下でアプリケーション12-iの起動/停止を制御する。
監視部133は、アプリケーション12-iの状態を監視することによって当該アプリケーション12-iの異常を検知する。監視部133をクラスタ制御部131に含めることも可能である。
APIフック部134は、例えば論理的に、アプリケーション12-iとOS11-iとの間に位置する。APIフック部134は、ノード10-iが稼動系ノードの場合、アプリケーション12-iが使用するAPIをフックするように構成されている。第1の実施形態においてAPIは関数(システム関数)であり、予めOS11-iに用意されている。APIフック部134は、自身がフックしたAPIに関する情報(以下、API情報と称する)をAPI情報記憶部14-1に時系列順に格納する。API情報は、APIフック部134によってフックされた関数(API)の関数名と、当該関数に渡されるべき(つまり当該関数の実行に用いられるべき)入力値である引数(OS11-iに渡される引数)と、当該関数の実行の結果としての出力値(OS11-iからの出力値)である返り値とを含む。
API情報記憶部14-iに格納されたAPI情報、つまりノード10-iが稼動系ノードである場合に、当該ノード10-i内のAPIフック部134によって取得されたAPI情報(アプリケーション12-iが使用した関数の関数名を含むAPI情報)は、ノード10-i内のクラスタ制御部131によって、クラスタシステムを構成する他の全てのノード(つまり待機系ノード)のクラスタ制御部に転送される。転送されたAPI情報は、上記待機系ノードのAPI情報記憶部に格納される。
ノード10-i内の評価部135は、稼動系ノードの異常が検知され、且つ当該ノード10-iが待機系ノードの場合に、API情報記憶部14-iに格納されているAPI情報の示す関数(API)を実行することによって、当該ノード10-iが引き継ぎ先ノードとなり得るかを評価するように構成されている。第1の実施形態において、引き継ぎ先ノードとなり得るノードとは、アプリケーションを稼動することが可能がノードをいう。
評価部135による上述の評価の仕組みは次の通りである。評価部135は、API情報記憶部14-iに格納されているAPI情報の示す関数(つまり稼動系ノードのAPIフック部134によってフックされた関数)をOS11-iを介して実行する。第1の実施形態において評価部135によって実行される関数は、API情報記憶部14-iに格納されているAPI情報の示す全ての関数ではなく、例えば、使用頻度の高い関数、或いはリソースを大量に消費する関数のような、アプリケーション12-iの動作に大きな影響のある関数(API)に限られるものとする。したがってAPIフック部134が、このような関数だけを選択的にフックする構成とすることもできる。リソースを大量に消費する関数として、メモリ確保関数(例えばmalloc関数、realloc関数)や、スレッド作成関数(CreateThread関数)が挙げられる。
評価部135は、関数の実行によってOS11-iから返される値(返り値)が正しいかによって、ノード10-iでアプリケーション12-iを稼動することが可能かを評価する。評価部135の評価結果は、クラスタ制御部131に通知される。待機系ノードのクラスタ制御部131は、相互に評価部135の判定結果を通知する。これにより各待機系ノード内の評価部135は、当該各待機系ノード内の評価部135の評価結果に基づいて、いずれの待機系ノードが引き継ぎ先ノードとして最適かを決定する。なお、第1の実施形態と異なって待機系ノードが1台の場合には、その唯一の待機系ノードでアプリケーションが稼動可能であれば、当該ノードが引き継ぎ先ノードとして決定される。
次に、第1の実施形態の動作について、図1の例のように、ノード10-1が稼動系ノードとして動作し、ノード10-2及び10-3が待機系ノードとして動作している場合を例に説明する。
<稼動系ノード内のAPIフック部の動作>
まず、稼動系ノード10-1内のAPIフック部134の動作について、図3のフローチャートを参照して説明する。
稼動系ノード10-1内のAPIフック部134は、当該ノード10-1で動作するアプリケーション12-1によって呼び出される(コールされる)API(ここではAPIフック部134によって管理されているAPI)をフックする(つかまえる)(ステップS1,S2)。これによりアプリケーション12-1からのAPIの呼び出しが直接アプリケーション12-1に伝えられるのが抑止される。APIフック部134は、フックしたAPI(関数)に関する情報として、当該関数の関数名と、引数と、返り値(つまりAPI)情報を含むAPI情報を取得する(ステップS3)。
APIフック部134は取得されたAPI情報を、API情報記憶部14-1に格納する(ステップS4)。またAPIフック部134は、取得されたAPI情報を、稼動系ノード10-1内のクラスタ制御部131によって待機系ノード10-2及び10-3に転送させる(ステップS5)。
稼動系ノード10-1内のクラスタ制御部131によって待機系ノード10-2及び10-3に転送されたAPI情報は、当該待機系ノード10-2及び10-3内のクラスタ制御部131によって、それぞれAPI情報記憶部14-2及び14-3に格納される。これにより、稼動系ノード10-1内のAPIフック部134によって取得されたAPI情報は、当該稼動系ノード10-1及び待機系ノード10-2及び10-3によって共有される。つまり、API情報記憶部14-1乃至14-3は、論理的に共有API情報記憶部を構成する。
第1の実施形態では、作図の都合で、ノード10-1〜10-3が、それぞれAPI情報記憶部14-1〜14-3を有している。しかし、ノード10-1〜10-3が、それぞれAPI情報記憶部14-1〜14-3を持つ代わりに、当該ノード10-1〜10-3によって共有される共有ストレージ装置(の記憶領域)内に、API情報記憶部(つまり共有API情報記憶部)が確保される構成としてもよい。この場合、ノード10-1(稼動系ノード10-1)のAPIフック部134がAPI情報を共有ストレージ装置のAPI情報記憶部に格納するだけで、ノード10-1〜10-3は当該API情報を共有することができる。
稼動系ノード10-1内のAPIフック部134の詳細について、図4の動作説明図を参照して説明する。
アプリケーション12-iは自身が呼び出すべき関数(API)の関数名のリストである関数テーブル120を含んでいる。この関数テーブル120は、アプリケーション12-iが本来呼び出すべき第1の関数(第1のAPI)の関数名、及び当該第1の関数に予め対応付けられた第2の関数(第2のAPI)の関数名の対のリストを保持する。
図4の例では、関数テーブル120に保持されるリストは、第1の関数fun1()の関数名及び第2の関数fun1′()の関数名の対と、第1の関数fun2()の関数名及び第2の関数fun2′()の関数名の対とを含む。OS11-1には、このリストで示される関数fun1()及びfun2()を含む第1の関数の集合(第1の集合)が予めAPIの集合として用意されている。一方、APIフック部134には、関数fun1′()及びfun2′()を含む第2の関数の集合が予めAPIの集合として用意されている。APIフック部134において、関数fun1′()及びfun2′()の関数名は関数fun1()及びfun2()の関数名と対応付けて管理されている。
今、アプリケーション12-1が第1の関数fun1()を呼び出したいものとする。第1の実施形態において、アプリケーション12-1が呼び出そうとする第1の関数(の関数名)に第2の関数(の関数名)が関数テーブル120によって対応付けられている場合、当該アプリケーション12-iは第2の関数を呼び出す。これにより、例えば関数fun1()の呼び出しが必要な場合であれば、関数fun1′()の呼び出しが行われる。関数fun1()の呼び出しに用いられる引数は、そのまま関数fun1′()の呼び出しに用いられる(継承される)。この引数は、例えば整数(Integer)型(INT型)のXXであるものとする。
上記したように、関数fun1′()はAPIフック部134に予め用意されている。そこでAPIフック部134は、関数fun1()に対応付けられた関数fun1′()の呼び出しがアプリケーション12-1によって行われると、図4において矢印41で示されるように、当該fun1′()の呼び出しをフックする。これによりAPIフック部134では、関数fun1′()が呼び出されて実行される。
APIフック部134は、関数fun1′()の実行により、当該関数fun1′()に対応付けられた関数fun1()の関数名と、当該関数fun1′()に継承された引数(つまり関数fun1()を呼び出すために用いられる入力値である引数(XX))とを取得する。そしてAPIフック部134は、関数fun1′()に対応付けられた関数fun1()の呼び出し、つまりアプリケーション12-1が本来行うべき関数fun1()の呼び出しを、図4において矢印42で示すように、当該アプリケーション12-1に代わって行う。この呼び出しにより、OS11-1に用意されている関数fun1()が呼び出され、当該関数fun1()に上記取得された引数(XX)が渡される。
するとOS11-1では、呼び出された関数fun1()(つまり、APIフック部134からの呼び出しに応じて呼び出された関数fun1())が、APIフック部134を介して渡されたアプリケーション12-1からの引数(XX)に基づいて実行される。OS11-1による関数fun1()の実行結果を示す、当該OS11-1(関数fun1())からの出力値(つまり返り値)は、図4において矢印43で示すように、当該関数fun1()の直接の呼び出し元であるAPIフック部134に返される。この返り値は、例えば整数型(INT型)のYYであるものとする。
APIフック部134は、OS11-1から返される、当該OS11-1による関数fun1()の実行結果である返り値(YY)を取得する。APIフック部134は、取得された返り値(YY)を、図4において矢印44で示されるように、アプリケーション12-1に返す。
以上の動作は、アプリケーション12-1にとっては、図4において矢印45で示されるように、アプリケーション12-1からOS11-1に対して関数fun1()の呼び出しを行い、図4において矢印46で示されるように、関数fun1()の実行結果である返り値(YY)をアプリケーション12-1がOS11-1(関数fun1())から受け取ったことと等価である。
さてAPIフック部134は、アプリケーション12-1からの関数fun1′()の呼び出しをフックした際に取得された、当該fun1′()が対応付けられた関数fun1()の関数名及び当該関数fun1()に渡されるべき引数(XX)と、当該関数fun1()をOS11-1から呼び出すことによって当該OS11-1から取得された返り値(YY)とを含むAPI情報を、図4において矢印47で示されるように、API情報記憶部14-1に格納する。
APIフック部134が関数fun1()の関数名、引数(XX)及び返り値(YY)を取得する動作は、当該APIフック部134がアプリケーション12-1の使用する関数fun1()をフックして、当該関数fun1()の関数名及び当該関数fun1()の引数(関数fun1()の実行に関する入力値)と、当該関数fun1()の実行結果である返り値(YY)とを取得することと等価である。
以上に述べた稼動系ノード10-1内のAPIフック部134の動作は、アプリケーション12-1から第1の関数に対応付けられた第2の関数の呼び出しが行われる都度実行される。これにより、ノード10-1〜10-3内のそれぞれAPI情報記憶部14-1〜14-3には、アプリケーション12-1が使用する第1の関数の各々について、関数名と入出力値である引数及び返り値とを含むAPI情報が蓄積される。
このような状態で、稼動系ノード10-1に障害が発生したものとする。ここでは稼動系ノード10-1の障害として、ノード10-1内のアプリケーション12-1に異常が発生した場合を想定している。稼動系ノード10-1内の監視部133は、アプリケーション12-1の異常を検知すると、その旨を当該ノード10-1内のクラスタ制御部131に通知する。
稼動系ノード10-1内のクラスタ制御部131は、監視部133からアプリケーション12-1の異常が通知されると、待機系ノード10-2及び10-3内のクラスタ制御部131に、その旨を通知する。この通知に応じて待機系ノード10-2及び10-3内のクラスタ制御部131は、当該ノード10-2及び10-3内の評価部135に、それぞれ当該ノード10-2及び10-3が引き継ぎ先ノードとなり得るか、つまりアプリケーション12-2及び12-3を稼動することが可能かを評価するように要求する。
なお、稼動系ノード10-1においてアプリケーション12-1の異常以外の障害が発生した場合、例えば稼動系ノード10-1のハードウェア障害が発生した場合には、稼動系ノード10-1のクラスタ制御部131は、待機系ノード10-2及び10-3内のクラスタ制御部131との間でハートビート通信を行うことができなくなる。そこで、待機系ノード10-2及び10-3内のクラスタ制御部131は、稼動系ノード10-1内のクラスタ制御部131との間のハートビート通信が途絶えたことをもって、当該稼動系ノード10-1の障害を検知することができる。
<待機系ノード内の評価部の動作>
待機系ノード10-2及び10-3内の評価部135は、待機系ノード10-2及び10-3内のクラスタ制御部131から評価要求を受け取ると、それぞれAPI情報記憶部14-2及び14-3(つまり論理的な共有API情報記憶部)に格納されているAPI情報(つまり、稼動系ノード10-1内のAPIフック部134によって取得されたAPI情報)に基づき、当該API情報の示す関数(API)を実行することによって、当該ノード10-2及び10-3自身についての要求された評価を行う。
第1の実施形態において評価部135によって実行される関数は、API情報記憶部14-iに格納されているAPI情報の示す全ての関数ではなく、例えば、リソースを大量に消費する関数のような、アプリケーション12-iの動作に大きな影響のある関数(API)に限られる。したがってAPIフック部134が、このような関数だけを選択的にフックする構成とすることもできる。リソースを大量に消費する関数としては、前述したように、メモリ確保関数やスレッド作成関数などが知られている。
以下、評価部135による評価処理の手順について、待機系ノード10-2内の評価部135の動作を例に、図5のフローチャートを参照して説明する。
まず評価部135は、API情報記憶部14-2から、実行されるべきAPI情報(詳細には、実行されるべき関数の関数名及び引数を含むAPI情報)を選択する(ステップS11)。評価部135は、選択されたAPI情報中の関数名と引数とを用いて、当該関数名で示される関数(API)の呼び出しを行う(ステップS12)。
OS11-2は、評価部135による呼び出しに応じ、呼び出された関数に、当該関数の呼び出しに用いられた引数を適用することで、当該関数を実行する。そしてOS11-2(呼び出された関数)は、呼び出された関数の実行の結果である返り値を評価部135に返す。これにより評価部135は、自身が呼び出した関数の実行の結果である返り値を取得する(ステップS13)。つまり評価部135は、選択されたAPI情報中の関数名で示される関数を実行することにより、関数の実行の結果である返り値を取得する。
評価部135は、取得された返り値が正しいかを判定する(ステップS14)。このステップS14での判定は、次のように行われる。まず、取得された返り値が選択されたAPI情報中の返り値と比較される。そして、両返り値が同じであるならば、取得された返り値は正しいと判定される。これに対し、両返り値が異なっているならば、取得された返り値は誤っていると判定される。
ところで、返り値の「型」は様々である。例えば返り値の型が整数型のように、選択されたAPI情報中の返り値と比較可能な場合には、上述の判定手法を適用することができる。しかし、比較ができない「型」の返り値もある。そこで、比較ができないような「型」の返り値が返される関数に関するAPI情報は、例えばステップS11での選択の対象から外せばよい。また、値の比較ができないような「型」の返り値の場合に、取得された返り値自体が、対応する関数の実行に成功したと見なせるか否かによって、当該返り値が正しいかを判定するようにしても構わない。例えば「RegOpenKeyEx」というレジストリ操作関数は、レジストリのハンドルを返す。したがって、レジストリ操作関数の実行の場合、返り値として「ハンドル」が返されたなら、当該返り値が正しいと判定するようにしても構わない。
さて、取得された返り値が正しくないと、上記ステップS14において判定された場合、評価部135は待機系ノード10-2でのアプリケーション12-2の稼動が不可であることを示す評価結果を、当該ノード10-2内のクラスタ制御部131に通知する(ステップS15)。するとクラスタ制御部131は、この評価部135による評価結果を、他の待機系ノードであるノード10-3のクラスタ制御部131に通知する。待機系ノード10-3内のクラスタ制御部131は、待機系ノード10-2内のクラスタ制御部131から通知された評価結果を当該ノード10-3内の評価部135に送る。
評価部135はステップS15を実行した場合、待機系ノード10-2でアプリケーション12-2を稼動することはできず、当該ノード10-2は引き継ぎ先ノードとして不適であると決定する(ステップS16)。この評価部135の決定結果は待機系ノード10-2内のクラスタ制御部131に通知される(ステップS20)。
これに対し、取得された返り値が正しいと、上記ステップS14において判定された場合、評価部135は、実行されるべきAPI情報を全て実行したかを判定する(ステップS17)。もし、実行されるべきAPI情報(未選択のAPI情報)があるならば(ステップS17)、評価部135は当該未選択のAPI情報を選択して(ステップS11)、ステップS12以降の処理を行う。
一方、実行されるべき未選択のAPI情報がないならば(ステップS17)、評価部135は、実行されるべきAPI情報は全て選択されて、当該API情報の示す全ての関数の実行により取得された返り値はいずれも正しかったと判断する。この場合、評価部135は、待機系ノード10-2でのアプリケーション(ここではアプリケーション12-2)の稼動が可能であることを示す評価結果を、当該ノード10-2内のクラスタ制御部131に通知する(ステップS18)。すると待機系ノード10-2内のクラスタ制御部131は、評価部135の評価結果を、他の待機系ノードであるノード10-3のクラスタ制御部131に通知する。待機系ノード10-3内のクラスタ制御部131は、待機系ノード10-2内のクラスタ制御部131から通知された評価結果を当該ノード10-3内の評価部135に送る。
待機系ノード10-3においても、待機系ノード10-2と同様の処理が行われ、当該ノード10-3内の評価部135による評価結果、つまりノード10-3でアプリケーション12-3を稼動することが可能であるかの評価結果が、待機系ノード10-2内のクラスタ制御部131に通知される。待機系ノード10-2内のクラスタ制御部131は、待機系ノード10-3についての評価結果を、当該待機系ノード10-2内の評価部135に通知する。
待機系ノード10-2内の評価部135はステップS18を実行すると、当該ノード10-2を含む各待機系ノード(ここでは待機系ノード10-2及び10-3)の評価結果に基づき、当該ノード10-2が引き継ぎ先ノードとして最適かを決定(判定)する(ステップS19)。もし、待機系ノード10-2及び10-3の評価結果が、いずれもアプリケーションの稼動が可能であることを示す場合、待機系ノード10-2内の評価部135は、当該ノード10-2の方が予め定められた優先度が高いかによって、当該ノード10-2が引き継ぎ先ノードとして最適かを決定する。これに対し、待機系ノード10-2及び10-3の評価結果のうち、待機系ノード10-2の評価結果のみアプリケーションの稼動が可能であることを示す場合、当該待機系ノード10-2内の評価部135は、当該ノード10-2が引き継ぎ先ノードとして最適であると決定する。
評価部135は、ステップS19における決定結果を待機系ノード10-2内のクラスタ制御部131に通知する。待機系ノード10-2内のクラスタ制御部131は、当該ノード10-2が引き継ぎ先ノードとして最適であると決定された場合だけ、稼動系ノード10-1での処理を引き継ぐための制御を行う。
待機系ノード10-3においても、待機系ノード10-2と同様の処理が行われ、当該ノード10-3を含む各待機系ノード(ここでは待機系ノード10-2及び10-3)の評価結果に基づき、当該ノード10-3が引き継ぎ先ノードとして最適かが決定される。
このように第1の実施形態においては、アプリケーション12-1が稼動している稼動系ノード10-1に異常が発生した場合に、待機系ノード10-2及び10-3のいずれかが引き継ぎ先ノードとなって稼動系ノード10-1での処理を実際に引き継ぐ前に、当該待機系ノード10-2及び10-3でアプリケーション12-2及び12-3が稼動可能であるかを評価し、稼動可能と評価されたノードが引き継ぎ先ノードとして決定される。このため第1の実施形態によれば、アプリケーションの実行失敗による障害発生を減少させることができる。
第1の実施形態では、リソースを大量に消費する関数を、評価部135によって実行される関数、つまりアプリケーション12-iの動作に大きな影響のある関数として挙げている。しかし、使用頻度の高い関数も、アプリケーション12-iの動作に大きな影響のある関数として挙げることができる。このような使用頻度の高い関数は、例えばAPI情報記憶部14-iに格納されているAPI情報の示す関数の中から、予め定められた閾値を超える使用頻度の関数として選択することができる。
また第1の実施形態では、待機系ノードの評価結果が他の待機系ノードに通知され、これにより全待機系ノードは、それぞれの評価結果を共有する。しかし、ノード10-1〜10-3によって共有される共有ストレージ装置内に各待機系ノードの評価結果を格納するための特別の記憶領域が確保される構成とするならば、待機系ノード10-2及び10-3内の評価部135が当該記憶領域に自身の評価結果を格納するだけで、待機系ノード10-2及び10-3は、それぞれの評価結果を共有することができる。
また第1の実施形態では、稼動系ノードがノード10-1の1台、待機系ノードがノード10-2及び10-3の2台であるクラスタシステムを想定している。しかし、N及びMを0より大きい整数であるとすると、N台の稼動系ノードとM台の待機系ノードで構成されるクラスタシステムであっても構わない。ここでMが1の場合、つまり待機系ノードが1台の場合、当該待機系ノードは前述したように、自身の評価結果(アプリケーションを稼動することが可能であるかの評価結果)のみで、引き継ぎ先ノードとして最適かを決定すればよい。
[第2の実施形態]
次に本発明の第2の実施形態について、図1のブロック図を援用して説明する。
図6は、第2の実施形態で適用されるノード10-i(i=1,2,3)の構成を示すブロック図である。図6において、図2と等価な部分には同一参照符号が付されている。
図6に示すノード10-iの構成は、当該ノード10-i内のクラスタ管理部13-iに情報収集部136が追加されている点と、当該ノード10-i内に収集情報記憶部15-iが追加されている点で、第1の実施形態におけるノード10-i(図2に示すノード10-iの構成)と相違する。したがって以下の説明では、図1において、ノード10-1〜10-3が、それぞれ収集情報記憶部15-1〜15-3を有しているものとする。また、図6に示すノード10-i内の評価部135の機能は、上記第1の実施形態と一部相違する。
ノード10-i内の情報収集部136は、引き継ぎ先ノードを決定する際に利用される情報を予め収集するように構成されている。この情報は、ノード10-iが稼動系ノードであって、且つ当該稼動系ノード10-iにおいてアプリケーション12-iが正常に動作している場合における、リソース消費量の時系列データである。情報収集部136は、収集したリソース消費量の時系列データに基づいて、当該リソース消費量の統計値を算出する。ここでは説明を簡単にするために、リソース消費量がメモリ消費量であるものとする。
ノード10-i内の収集情報記憶部15-iは、稼動系ノードの情報収集部136で収集された情報(リソース消費量の時系列データ及びリソース消費量の統計値)を格納するのに用いられる。
第2の実施形態において、ノード10-i内の評価部135は、稼動系ノードの異常が検知され、且つ当該ノード10-iが待機系ノードの場合に、API情報記憶部14-iに格納されているAPI情報(つまり稼動系ノードのAPIフック部134によって取得されたAPI情報)の示す関数を実行することによって、収集情報記憶部15-i内に収集されているリソース消費量の統計値の示すリソース量が確保できるかを判定する。ノード10-i内の評価部135は、この判定結果に基づいて、当該ノード10-iを引き継ぎ先ノードとするかを決定する。
次に第2の実施形態の動作について、上記第1の実施形態と同様に、ノード10-1が稼動系ノードとして動作し、ノード10-2及び10-3が待機系ノードとして動作している場合を例に説明する。
<稼動系ノード内の情報収集部の動作>
まず、稼動系ノード10-1内の情報収集部136の動作について説明する。
稼動系ノード10-1内のAPIフック部134は、第1の実施形態と同様に、アプリケーション12-1が使用するAPI(関数)をフックする。稼動系ノード10-1内の情報収集部136は、アプリケーション12-1の起動時から、当該アプリケーション12-1が正常に稼動している限り、APIフック部134によってフックされた関数の実行によって消費されるリソース量を収集する。ここで、関数の実行によって消費されるリソース量は、アプリケーション12-1が関数を呼び出す際に明示的に示される。例えば、メモリ確保関数としてのmalloc関数は、確保されるべきサイズ(size)を指定する引数を用いて、「malloc(size)」の形式で表される。この引数sizeから、「malloc(size)」が実行された場合に、sizeバイトのメモリ量(リソース)が確保(確保)されることを認識できる。
情報収集部136は、例えばmalloc関数がAPIフック部134によってフックされた場合、当該APIフック部134から、このmalloc関数の引数size、つまりsizeバイトという確保されるべきメモリ量を示すデータを、消費されるメモリ量(リソース量)を示すデータとして取得する。情報収集部136は、APIフック部134によってフックされた関数の実行によって消費されるメモリ量(メモリ消費量)を示すデータを収集する都度、そのデータを時系列順に収集情報記憶部15-1に格納する。
情報収集部136は、収集情報記憶部15-1に収集されたメモリ消費量の時系列データに基づき、メモリ消費量の統計値を、例えば定期的に算出する。ここで、メモリ消費量の統計値は、例えば、メモリ消費量の最大値または平均値である。また、平均値の計算に、予め定められた閾値を超えるようなスパイク値を除くことも可能である。更に、平均値として、アプリケーション12-1の起動時からの全期間に亙る平均値、日平均値または週平均値を適用することも可能である。
情報収集部136は、メモリ消費量(リソース消費量)の統計値を算出すると、当該統計値を最新のメモリ消費量の統計値として収集情報記憶部15-1内の統計値領域に格納する。これにより統計値領域の内容が、最新のメモリ消費量の統計値に更新される。同時に情報収集部136は、この最新のメモリ消費量の統計値を、クラスタ制御部131によって、待機系ノード10-2及び10-3のクラスタ制御部131を介して当該待機系ノード10-2及び10-3の情報収集部136に転送させる。
転送された最新のメモリ消費量の統計値は、待機系ノード10-2及び10-3の情報収集部136によって当該待機系ノード10-2及び10-3の収集情報記憶部15-2(i=2)及び16-3(i=3)に格納される。これにより、稼動系ノード10-1内の情報収集部136によって取得されたメモリ消費量の統計値は、当該稼動系ノード10-1及び待機系ノード10-2及び10-3によって共有される。つまり、各ノード10-i(i=1,2,3)の収集情報記憶部15-iは、論理的に共有収集情報記憶部を構成する。なお、各ノード10-iが収集情報記憶部15-iを持つ代わりに、共有ストレージ装置(の記憶領域)内に、収集情報記憶部が確保される構成としてもよい。
<待機系ノード内の評価部の動作>
次に、第1の実施形態と同様に稼動系ノード10-1に障害が発生したものとする。この場合、待機系ノード10-2内の評価部135は、当該ノード10-2がアプリケーション12-2を稼動することが可能かを評価する。同様の評価は、待機系ノード10-3内の評価部135でも行われる。
以下、評価部135による評価処理の手順について、待機系ノード10-2内の評価部135の動作を例に、図7のフローチャートを参照して説明する。
まず評価部135は、収集情報記憶部15-i(i=2)、つまり収集情報記憶部15-2から、メモリ消費量の統計値を読み込む(ステップS21)。次に評価部135は、API情報記憶部14-2から、実行されるべきAPI情報を選択する(ステップS22)。ここでは、実行されるべきAPI情報が、メモリ領域を確保するためのメモリ確保関数の関数名を含むAPI情報であるものとする。
評価部135は、選択されたAPI情報中の関数名を用いると共に、当該関数名で指定される関数の引数として、収集情報記憶部15-2から読み出されたメモリ消費量の統計値を用いて、当該関数(メモリ確保関数)を実行する(ステップS23)。次に評価部135は、関数の実行の結果に基づき、メモリ消費量の統計値(引数)で示されるサイズのメモリ量が確保できたかを判定する(ステップS24)。
もし、統計値で示されるサイズのメモリ量が確保できなかったならば(ステップS24)、評価部135は第1の実施形態において返り値が正しくないと判定された場合と同様の処理(つまりステップS15,S16,S20と同様の処理)を実行する(ステップS25,S26,S30)。
これに対し、統計値で示されるサイズのメモリ量が確保できたならば(ステップS24)、評価部135は第1の実施形態において返り値が正しいと判定された場合と同様の処理を実行する。即ち評価部135は、実行されるべきAPI情報を全て実行したかを判定し(ステップS27)、実行されるべきAPI情報(未選択のAPI情報)があるならば、当該未選択のAPI情報を選択して(ステップS22)、ステップS23以降の処理を行う。ここで、統計値で示されるサイズのメモリ量が確保できたということは、当該サイズを引数とした関数(API)の呼び出し及び実行に必要なメモリ量も確保できたことを意味する点に注意する、
一方、実行されるべき未選択のAPI情報がないならば(ステップS27)、評価部135は第1の実施形態において実行されるべき未選択のAPI情報がないと判定された場合と同様の処理(つまりステップS18〜S20と同様の処理)を実行する(ステップS28〜S30)。
待機系ノード10-3内の評価部135においても、上述の待機系ノード10-2内の評価部135と同様の動作が行われる。
これにより、待機系ノード10-2及び10-3のいずれか一方においてのみ、上記統計値で示されるサイズのメモリ量が確保できたと判定された場合、つまり待機系ノード10-2及び10-3のいずれか一方においてのみアプリケーションを稼動可能であると判定された場合には、その一方のノードが引き継ぎ先ノードとして決定される。また、待機系ノード10-2及び10-3の双方で、上記統計値で示されるサイズのメモリ量が確保できたと判定された場合には、待機系ノード10-2及び10-3のうち、予め定められた優先度が高い方のノードが引き継ぎ先ノードとして決定される。
[第3の実施形態]
次に本発明の第3の実施形態について、図1のブロック図を援用して説明する。
図8は、第3の実施形態で適用されるノード10-i(i=1,2,3)の構成を示すブロック図である。図8において、図6と等価な部分には同一参照符号が付されている。
図8に示すノード10-iの構成は、当該ノード10-i内のクラスタ管理部13-iにAPIフック部134及び情報収集部136が設けられていない点と、当該ノード10-i内に情報収集部136に相当する情報収集部16-iが設けられている点と、当該ノード10-i内にAPI情報記憶部14-iが設けられていない点で、第2の実施形態におけるノード10-i(図6に示すノード10-iの構成)と相違する。したがって以下の説明では、図1において、ノード10-1〜10-3が、それぞれ収集情報記憶部15-1〜15-3と情報収集部16-1〜16-3を有する一方、API情報記憶部14-1〜14-3を有していないものとする。また、図8に示すノード10-i内の評価部135の機能は、上記第2の実施形態と一部相違する。
第3の実施形態において、ノード10-i内の情報収集部16-iは、当該ノード10-iが稼動系ノードである場合に、アプリケーション12-iが消費するリソース量の時系列データを、引き継ぎ先を決定する際に利用される情報として収集するように構成されている。情報収集部16-iは、収集した、アプリケーション12-iが消費するリソース量(リソース消費量)の時系列データに基づいて、当該リソース消費量の統計値を算出する。
ノード10-i内の収集情報記憶部15-iは、稼動系ノードの情報収集部で収集された情報(アプリケーション12-iが消費するリソース量の時系列データ及び当該リソース消費量の統計値)を格納するのに用いられる。
ノード10-i内の評価部135は、稼動系ノードの異常が検知され、且つ当該ノード10-iが待機系ノードの場合に、収集情報記憶部15-i内に収集されているリソース消費量の統計値の示すリソース量と、当該ノード10-iの現在の空きリソース量とに基づき、当該統計値の示すリソース量が確保できるかを評価する。ノード10-i内の評価部135は、この評価結果に基づいて、当該ノード10-iを引き継ぎ先ノードとするかを決定する。
次に第3の実施形態の動作について、上記第2の実施形態と同様に、ノード10-1が稼動系ノードとして動作し、ノード10-2及び10-3が待機系ノードとして動作している場合を例に説明する。
<稼動系ノード内の情報収集部の動作>
まず、稼動系ノード10-1内の情報収集部16-i(i=1)の動作、つまり情報収集部16-1の動作について説明する。
情報収集部16-1は、アプリケーション12-1が消費するリソース量の時系列データを、当該アプリケーション12-iの外部から観測(監視)することによって収集する。このような、アプリケーション12-iが消費するリソース量を観測する仕組みは従来から知られており、専用のコマンド或いはツールを用いることにより実現される。
アプリケーション12-1が消費するリソース量(第1のリソース量)は、当該アプリケーション12-1によるAPI(例えばメモリ確保関数)の呼び出し及び実行に必要なリソース量(第2のリソース量)と、当該API(関数)の実行によって確保されるリソース量(第3のリソース量)との和である。
このように、第2の実施形態では、第3のリソース量を示すデータだけが収集されるのに対し、第3の実施形態では、第3のリソース量を示すデータに加えて第2のリソース量を示すデータも収集される。第2のリソース量は、関数の引数を保持するためのスタックやAPIの内部処理で消費するリソース量などである。
情報収集部16-1は、第1のリソース量を示すデータを収集する都度、そのデータを時系列順に収集情報記憶部15-1に格納する。情報収集部16-1は、第2の実施形態における情報収集部136と同様に、収集情報記憶部15-1に収集された第1のリソース量の時系列データに基づき、当該第1のリソース量(アプリケーション12-1で消費されるリソース量)の統計値を、例えば定期的に算出する。
情報収集部16-1は、第1のリソース量の統計値を算出すると、当該統計値を最新の第1のリソース量(リソース消費量)の統計値として収集情報記憶部15-1内の統計値領域に格納する。これにより統計値領域の内容が、最新の第1のリソース量の統計値に更新される。同時に情報収集部16-1は、この最新の第1のリソース量の統計値を、クラスタ制御部131によって、待機系ノード10-2及び10-3のクラスタ制御部131を介して当該待機系ノード10-2及び10-3の情報収集部16-2(i=2)及び16-3(i=3)に転送させる。転送された最新の第1のリソース量の統計値は、待機系ノード10-2及び10-3の情報収集部16-2及び16-3によって、当該待機系ノード10-2及び10-3の収集情報記憶部15-2(i=2)及び16-3(i=3)に格納される。以下では、リソース量がメモリ量であるものとして説明する。
<待機系ノード内の評価部の動作>
次に、第2の実施形態と同様に稼動系ノード10-1に障害が発生したものとする。この場合、待機系ノード10-2内の評価部135は、当該ノード10-2がアプリケーション12-2を稼動することが可能かを評価する。同様の評価は、待機系ノード10-3内の評価部135でも行われる。
以下、評価部135による評価処理の手順について、待機系ノード10-2内の評価部135の動作を例に、図9のフローチャートを参照して説明する。
まず、評価部135は、収集情報記憶部15-2(i=2)から、第1のメモリ量(第1のリソース量)の統計値(つまりアプリケーションが消費するメモリ量の統計値)を読み込む(ステップS31)。次に評価部135は、読み込まれた統計値で示されるメモリ量(リソース量)を、待機系ノード10-2の現在の空きメモリ量(リソース量)と比較する(ステップS32)。ここで、待機系ノード10-2の現在の空きメモリ量を示すデータは、周知のように、OS11-2(i=2)に問い合わせることによって当該OS11-2から取得することができる。
評価部135は、上記の比較の結果に基づき、上記読み込まれた統計値で示されるメモリ量が待機系ノード10-2において確保で可能であるかを判定する(ステップS33)。
さて、収集情報記憶部15-2(i=2)に収集されている第1のメモリ量の統計値は最新の統計値である。したがって、この統計値の示すメモリ量は、現時点(つまり稼動系ノード10-1で障害が発生した時点)において待機系ノード10-2が引き継ぎ先ノードとして動作してアプリケーション12-2を実行するのに必要となるメモリ量であると見なすことができる。このため、待機系ノード10-2内の評価部135が、上述の比較の結果に基づいて、当該ノード10-2において上記統計値の示すメモリ量を確保可能であると判定できるならば、当該ノード10-2でアプリケーション12-2を稼動することができると判定できる。
そこで、上記統計値で示されるメモリ量が待機系ノード10-2において確保できないと判定されたならば(ステップS33)、評価部135は第2の実施形態において引数で示されるメモリ量が確保できなかった場合と同様の処理(つまりステップS25,S26,S30と同様の処理)を実行する(ステップS34,S35,S38)。
これに対し、上記統計値で示されるメモリ量が待機系ノード10-2において確保できると判定されたならば(ステップS33)、評価部135は第2の実施形態おいて引数で示されるメモリ量が確保でき、且つ実行されるべき未選択のAPI情報がないと判定された場合と同様の処理(つまりステップS28〜S30と同様の処理)を実行する(ステップS36〜S38)。
待機系ノード10-3内の評価部135においても、上述の待機系ノード10-2内の評価部135と同様の動作が行われる。
これにより、待機系ノード10-2及び10-3のいずれか一方においてのみ、上記統計値で示されるサイズのメモリ量が確保可能であると判定された場合、つまり待機系ノード10-2及び10-3のいずれか一方においてのみアプリケーションを稼動可能であると判定された場合には、その一方のノードが引き継ぎ先ノードとして決定される。また、待機系ノード10-2及び10-3の双方で、上記統計値で示されるサイズのメモリ量が確保可能であると判定された場合には、待機系ノード10-2及び10-3のうち、予め定められた優先度が高い方のノードが引き継ぎ先ノードとして決定される。第3の実施形態では、アプリケーションからのAPIの呼び出しをフックすることなく、待機系ノードの中から最適な引き継ぎ先ノードを決定することができる。
[第4の実施形態]
次に本発明の第4の実施形態について、図1のブロック図を援用して説明する。
図10は、第4の実施形態で適用されるノード10-i(i=1,2,3)の構成を示すブロック図である。図10において、図2と等価な部分には同一参照符号が付されている。
図10に示すノード10-iの構成は、当該ノード10-i内のクラスタ管理部13-iにAPIフック部134に代えてAPIフック・I/O隔離部137が設けられている点で、第1の実施形態におけるノード10-i(図2に示すノード10-iの構成)と相違する。また、図10に示すノード10-i内の評価部135の機能は、上記第1の実施形態と一部相違する。
第4の実施形態において、ノード10-i内のクラスタ管理部13-iに設けられたAPIフック・I/O隔離部137は、図2に示されるAPIフック部134と同様の機能(APIフック機能)に加えて、評価部135による評価のためにアプリケーション12-iから呼び出される関数(API)を当該評価部135に代わって仮想的に実行することにより、通常であれば当該アプリケーション12-iとOS11-iとの間で授受される入出力(I/O)を当該OS11-iから隔離する機能(I/O隔離機能)を有する。APIフック・I/O隔離部137は、アプリケーション12-iから呼び出された関数と返り値とを評価部135に渡す。
第4の実施形態において、評価部135はAPI情報記憶部14-iに格納されている関数の呼び出し(実行)を自身が行う代わりに、アプリケーション12-iを動作させることにより、当該関数の呼び出し(実行)を当該アプリケーション12-i自身に行わせる。つまり評価部135は、API情報記憶部14-iに格納されている関数の呼び出し(実行)を、アプリケーション12-iを動作させることによって実現する。
評価部135は、アプリケーション12-1による関数の呼び出し(実行)に応じてAPIフック・I/O隔離部137によって取得された返り値が正しいかを、当該関数の関数名に対応付けてAPI情報記憶部14-iに格納されている返り値に基づいて判定することにより、ノード10-iでのアプリケーション12-iの稼動が可能であるかを評価する。
次に、第4の実施形態の動作について、図1の例のように、ノード10-1が稼動系ノードとして動作し、ノード10-2及び10-3が待機系ノードとして動作している場合を例に説明する。
<稼動系ノード内のAPIフック・I/O隔離部の動作>
稼動系ノード10-1内のAPIフック・I/O隔離部137は、上記第1の実施形態におけるAPIフック部134と同様に、図3のフローチャートの示す手順で動作する。即ちAPIフック・I/O隔離部137は、アプリケーション12-1によってコールされたAPI(関数)をフックする。但し、第4の実施形態では、待機系ノード10-2及び10-3内の評価部135は、APIフック・I/O隔離部137によってフックされたAPIを直接実行しない。このため、APIフック・I/O隔離部137が引数を取得する必要はない。つまり、第4の実施形態においてAPIフック・I/O隔離部137は、アプリケーション12-1によってコールされた関数の関数名と返り値とを取得する。取得された、関数名及び返り値を含むAPI情報は、ノード10-1〜10-3のAPI情報記憶部14-1〜14-3(つまり共有API情報記憶部)に時系列順に格納される。
<待機系ノード内の評価部及びAPIフック・I/O隔離部の動作>
次に、稼動系ノード10-1に障害が発生した結果、待機系ノード10-2及び10-3内の評価部135が起動されたものとする。これにより待機系ノード10-2及び10-3内の評価部135は、それぞれ当該ノード10-2及び10-3においてアプリケーション12-2及び12-3を稼動することが可能であるかを評価する。
以下、評価部135及びAPIフック・I/O隔離部137の動作について、待機系ノード10-2内の評価部135及びAPIフック・I/O隔離部137の動作を例に、図11の動作説明図を参照して説明する。
待機系ノード10-2内の評価部135は、図11において矢印111で示されるように、APIフック・I/O隔離部137に対して評価モードを通知すると共に、矢印112で示されるように、アプリケーション12-2を実際に起動する。するとアプリケーション12-2は、稼動系ノードにおけるのと同様に動作して、必要に応じてAPI(関数)を呼び出す。
APIフック・I/O隔離部137は、第1の実施形態において稼動系ノードで動作するけるAPIフック部134と同様に、アプリケーション12-2によって呼び出される(コールされる)APIを、図11において矢印113で示されるようにフックする。評価モードにおいて、APIフック・I/O隔離部137は、フックしたAPI(関数)を、アプリケーション12-2とOS11-2との間で授受されるI/Oが隔離されるように、以下に述べるように仮想的に実行する。そしてAPIフック・I/O隔離部137は、関数の実行結果としての返り値を、図11において矢印114で示されるようにアプリケーション12-2に返す。
APIフック・I/O隔離部137(待機系ノード10-2内のAPIフック・I/O隔離部137)によってフックされたAPIに関するAPI情報は、当該APIが稼動系ノード10-1内のAPIフック・I/O隔離部137によってフックされた際に、API情報記憶部14-1〜14-3に格納されている。したがって、評価部135から評価モードの通知を受けた待機系ノード10-2内のAPIフック・I/O隔離部137が、フックしたAPIを実行することは、API情報記憶部14-2に格納されているAPI情報の示すAPIを、評価部135がAPIフック・I/O隔離部137を用いて実行することと等価である。
さて、待機系ノード10-2内のAPIフック・I/O隔離部137によってフックされた関数が、当該ディスクライトやネットワークへのデータ送出を伴う特別の関数である場合があり得る。そこでAPIフック・I/O隔離部137は、少なくとも、自身がフックした関数が上記のような特別な関数の場合には、当該関数をOS11-2を用いて実際に実行しないように構成されている。これにより、通常であればアプリケーション12-2とOS11-2との間で授受されるI/Oが隔離され、上記のような特別な関数の実行に起因してディスクライトやネットワークへのデータ送出が発生するのを防止できる。
そこでAPIフック・I/O隔離部137は、自身がフックした関数を仮想的に実行することにより当該関数の実行結果としての返り値を生成する。APIフック・I/O隔離部137は、生成された返り値を上述のようにアプリケーション12-2に返す。これによりAPIフック・I/O隔離部137は、アプリケーション12-2から呼び出された関数(API)が実行されたかのように見せかけて、当該アプリケーション12-2に次の処理を行わせることができる。なお、APIフック・I/O隔離部137がフックした関数が上記特別な関数でない場合、OS11-2を用いて当該関数を実行しても構わない。
APIフック・I/O隔離部137は、アプリケーション12-2に返り値を返す際に、その返り値と実行された関数の関数名とを、図11において矢印115で示されるように、評価部135に渡す。ここでアプリケーション12-2の動作が正常であるならば、当該アプリケーション12-2が起動されてから少なくとも当該アプリケーション12-2の起動が完了するまでの間は、APIフック・I/O隔離部137によってフックされる関数の順番は、API情報記憶部14-2に時系列順に格納されているAPI情報の示す関数の順番に一致する。したがって評価部135は、アプリケーション12-2の動作が正常であるならば、APIフック・I/O隔離部137から渡された関数名の関数が、APIフック・I/O隔離部137によって何番目にフックされたかに基づいて、図11において矢印116で示されるようにAPI情報記憶部14-1を参照することで、当該関数名を含むAPI情報に含まれている返り値を取得することができる。
なお、ノード10-i(i=1,2,3)が、APIフック・I/O隔離部137に代えて、稼動系ノードの場合にだけ動作する、第1の実施形態におけるAPIフック部134に相当するAPIフック部と、待機系ノードの場合にだけ動作するAPIフック・I/O隔離部とを有していても構わない。
評価部135は、APIフック・I/O隔離部137から渡された返り値が正しいかを、API情報記憶部14-1から取得された返り値と比較することによって判定する。
評価部135は、アプリケーション12-2の起動から予め定められたタイミングが到来するまで評価モードを継続する。このタイミングは、例えばアプリケーション12-2の起動が完了するタイミングである。評価部135は、このタイミングが到来すると、評価モードを解除する。これによりAPIフック・I/O隔離部137は、フック動作とフックされた関数の実行とを停止する。
評価部135は、評価モードの期間に、APIフック・I/O隔離部137によってフックされた関数の実行の結果である返り値が全て正しかったならば、第1の実施形態におけるステップS18と同様に、待機系ノード10-2でのアプリケーション12-2の稼動が可能であることを示す評価結果を、当該ノード10-2内のクラスタ制御部131に通知する。この評価結果は、ノード10-2内のクラスタ制御部131によって他の待機系ノード10-3に通知される。また、この待機系ノード10-3内の評価部135の評価結果は待機系ノード10-2にも通知される。
待機系ノード10-2内の評価部135は、上記第1の実施形態と同様に、当該ノード10-2を含む各待機系ノード(ここでは待機系ノード10-2及び10-3)の評価結果に基づき、当該ノード10-2が引き継ぎ先ノードとして最適かを決定する。
待機系ノード10-3においても、待機系ノード10-2と同様の処理が行われ、当該ノード10-3を含む各待機系ノード(ここでは待機系ノード10-2及び10-3)の評価結果に基づき、当該ノード10-3が引き継ぎ先ノードとして最適かが決定される。
このように第4の実施形態では、待機系ノード10-2及び10-3において、それぞれアプリケーション12-2及び12-3を実際に動作させることにより、当該アプリケーション12-2及び12-3を正常に稼動可能かを判定することができるため、第1の実施形態に比べてより正確に引き継ぎ先ノードを決定することが可能となる。
なお、本発明は、上記第1乃至第4の実施形態そのままに限定されるものではなく、実施段階ではその要旨を逸脱しない範囲で構成要素を変形して具体化できる。また、第1乃至第4の実施形態に開示されている複数の構成要素の適宜な組み合わせにより種々の発明を形成できる。例えば、第1乃至第4の実施形態に示される全構成要素から幾つかの構成要素を削除してもよい。
10-1〜10-3,10-i…ノード(サーバ計算機)、11-1〜11-3,11-i…OS(オペレーティングシステム)、12-1〜12-3,12-i…アプリケーション、13-1〜13-3,13-i…クラスタ管理部、14-1〜14-3,14-i…API(アプリケーションプログラムインタフェース)情報記憶部(記憶手段)、15-i…収集情報記憶部(記憶手段)、16-i,136…情報収集部、131…クラスタ制御部、134…APIフック部、135…評価部、137…APIフック・I/O隔離部。