(57)【要約】【課題】性能低下を抑制できるストレージシステムを実現する。【解決手段】実施形態によれば、ストレージシステムは、不揮発性メモリを各々が含む複数のストレージと、前記複数のストレージをアクセス可能なプロセッサとを具備し、前記プロセッサは、アプリケーションプログラムから発行される各データ入力要求を其々の前記複数のストレージに向けて送出するとともに、データ処理状況を参照して前記複数のストレージの中から第１ストレージを特定するように構成され、前記アプリケーションプログラムは、前記第１ストレージの特定に伴い、当該第１ストレージ向けのデータ入力要求の発行を制御し、当該第１ストレージに入力予定のデータを予約領域に入力するように構成されたストレージシステム。【選択図】図３１
2018041162.tif 000002
【特許請求の範囲】
【請求項１】
不揮発性メモリを各々が含む複数のストレージと、
前記複数のストレージをアクセス可能なプロセッサとを具備し、
前記プロセッサは、
アプリケーションプログラムから発行される各データ入力要求を其々の前記複数のストレージに向けて送出するとともに、データ処理状況を参照して前記複数のストレージの中から第１ストレージを特定するように構成され、
前記アプリケーションプログラムは、前記第１ストレージの特定に伴い、当該第１ストレージ向けのデータ入力要求の発行を制御し、当該第１ストレージに入力予定のデータを予約領域に入力するように構成されたストレージシステム。
【請求項２】
バックグラウンド動作の開始が必要とされることによってアクセス速度が遅くなるストレージ、或いは前記アクセス速度が遅くなったストレージは、前記第１ストレージとして特定されるように構成されている請求項１記載のストレージシステム。
【請求項３】
前記第１ストレージにおけるアクセス速度の回復に伴い、前記予約領域に入力されたデータは、オリジナルのストレージに戻されるように構成されている請求項１記載のストレージシステム。
【請求項４】
書込み対象となるストレージは、他のストレージとペアを構成するとともに、当該ペアのうち一方の前記ストレージが前記第１ストレージと認識された場合、他方の前記ストレージが前記予約領域として働くように構成されている請求項１記載のストレージシステム。
【請求項５】
前記予約領域として専用のストレージが指定され、当該専用のストレージは、所定数の前記ストレージに対して１つの割合で設けられるように構成されている請求項１記載のストレージシステム。
【請求項６】
前記予約領域として前記ストレージ内の揮発性記憶領域が指定されるように構成されている請求項１記載のストレージシステム。
【請求項７】
前記複数のストレージ内には退避領域が其々設けられ、前記第１ストレージが特定された場合、当該特定されたストレージ内の退避領域、或いは他のストレージ内の退避領域の何れか少なくとも一つが前記予約領域として働くように構成されている請求項１記載のストレージシステム。
【請求項８】
前記複数のストレージ内には退避領域が其々設けられ、前記第１ストレージが特定された場合、当該特定されたストレージ以外の他のストレージ内の退避領域の何れか少なくとも一つが前記予約領域として働くように構成されている請求項１記載のストレージシステム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明の実施形態は、不揮発性メモリを含むストレージを制御する技術に関する。
【背景技術】
【０００２】
近年、各種企業が取り扱うデータ量の飛躍的な増大に伴い、大量且つ多様なデータを高速・効率的に扱う分散処理システムが求められている。
【０００３】
また、近年、不揮発性メモリにデータを格納するストレージが広く普及している。このようなストレージとしては、ソリッドステートドライブ（ＳＳＤ）やエンベデッドマルチメディアカード（ｅＭＭＣ（登録商標））が知られている。このようなストレージは、その低電力消費、高性能という特徴により、様々なコンピューティングデバイスのメインストレージとして使用されている。
【０００４】
最近では、大量且つ多様なデータを高速・効率的に扱うために、複数のストレージを含むシステムも開発され始めている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２０１２−１０３９２６号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
しかし、複数のストレージを含むシステムでは、ある一つのストレージの性能低下に起因してシステム全体の性能低下が引き起こされる場合がある。
【０００７】
本発明が解決しようとする課題は、性能低下を抑制できるストレージシステムおよび制御方法を提供することである。
【課題を解決するための手段】
【０００８】
実施形態によれば、ストレージシステムは、不揮発性メモリを各々が含む複数のストレージと、前記複数のストレージをアクセス可能なプロセッサとを具備し、前記プロセッサは、アプリケーションプログラムから発行される各データ入力要求を其々の前記複数のストレージに向けて送出するとともに、データ処理状況を参照して前記複数のストレージの中から第１ストレージを特定するように構成され、前記アプリケーションプログラムは、前記第１ストレージの特定に伴い、当該第１ストレージ向けのデータ入力要求の発行を制御し、当該第１ストレージに入力予定のデータを予約領域に入力するように構成されたストレージシステム。
【図面の簡単な説明】
【０００９】
【図１】実施形態に係るストレージシステムの構成を示すブロック図。
【図２】同実施形態のストレージシステムの一実装例を示すブロック図。
【図３】同実施形態のストレージシステムに含まれるコネクションユニット（ＣＵ）の各々の構成を示すブロック図。
【図４】同実施形態のストレージシステムに含まれるノードモジュール（ＮＭ）の各々の構成を示すブロック図。
【図５】同実施形態のストレージシステムにおける、アプリケーションプログラムとキューと複数のストレージとの間の関係を示す図。
【図６】同実施形態のストレージシステムにおける理想的な並列度と実際の並列度との関係を示す図。
【図７】低並列度が起きる要因を説明するための図。
【図８】低並列度の分析結果を示す図。
【図９】低並列度の分析結果の続きを示す図。
【図１０】低並列度の分析結果の続きを示す図。
【図１１】アプリケーションプログラムが全てのコマンドの完了を待つケースを説明するための図。
【図１２】同実施形態のストレージシステムによって実行されるＩ／Ｏ管理（パート１）の基本コンセプトを説明するための図。
【図１３】同実施形態のストレージシステムに適用されるステータス取得動作の例を示す図。
【図１４】遅いストレージの検出に応答して同実施形態のストレージシステムによって実行される動作の概要を説明するための図。
【図１５】遅いストレージの検出に応答して同実施形態のストレージシステムによって実行される処理の手順を示すフローチャート。
【図１６】アプリケーションプログラムによって実行されるデータＩ／Ｏ要求制御処理の手順を示すフローチャート。
【図１７】遅くなりそうなストレージの予測に基づいて、同実施形態のストレージシステムによって実行される動作の概要を説明するための図。
【図１８】遅くなりそうなストレージの予測に基づいて、同実施形態のストレージシステムによって実行される処理の手順を示すフローチャート。
【図１９】アプリケーションプログラムによって実行されるデータＩ／Ｏ要求制御処理の別の手順を示すフローチャート。
【図２０】遅くなりそうなストレージの特定と遅いストレージの検出の双方に基づいて同実施形態のストレージシステムによって実行される処理の手順を示すフローチャート。
【図２１】同実施形態のストレージシステムのコネクションユニット（ＣＵ）ドライバまたはノードモジュール（ＮＭ）での対策を説明するための図。
【図２２】プロセッサコア毎にキューを用意する構成を示す図。
【図２３】ノードモジュール（ＮＭ）毎にキューを用意する構成を示す図。
【図２４】上位レイヤに大サイズのキューを用意する構成を示す図。
【図２５】上位レイヤのキューに入れられたデータＩ／Ｏ要求から送出可能データＩ／Ｏ要求それぞれを選択する処理の手順を示すフローチャート。
【図２６】ノードモジュール（ＮＭ）への要求を制御する動作の概要を説明するための図。
【図２７】ノードモジュール（ＮＭ）への要求を制御する処理の手順を示すフローチャート。
【図２８】アイドル状態となったストレージのバックグラウンド動作を開始する動作の概要を説明するための図。
【図２９】アイドル状態となったストレージのバックグラウンド動作を開始する処理の手順を示すフローチャート。
【図３０】同実施形態のストレージシステムによって実行される第２のＩ／Ｏ管理（パート２）のコンセプトを説明するための図。
【図３１】遅いストレージに書き込むべきデータを退避用の予約領域に書き込む動作の概要を説明するための図。
【図３２】キューに入ってから一定時間を超えたコマンドをタイムアウトエラーにする動作の概要を説明するための図。
【図３３】キューに入ってから一定時間を超えたコマンドをタイムアウトエラーにする処理の手順を示すフローチャート。
【図３４】コネクションユニット（ＣＵ）ドライバまたはノードモジュール（ＮＭ）によって採られる基本コンセプトを説明するための図。
【図３５】遅いストレージに書き込むべき後続データを退避用の予約領域に書き込むための処理の手順を示すフローチャート。
【図３６】書き込み対象のストレージを２つのストレージ間でトグルする動作の概要を説明するための図。
【図３７】書き込み対象のストレージを２つのストレージ間でトグルする動作を示すタイミングチャート。
【図３８】書き込み対象のストレージを２つのストレージ間でトグルする処理の手順を示すフローチャート。
【図３９】遅いストレージに書き込むべきデータを退避用の専用のストレージに書き込む動作の概要を説明するための図。
【図４０】遅いストレージに書き込むべきデータを退避用の専用のストレージに一時的に書き込み、後に、データをオリジナルのストレージに戻す動作を示すタイミングチャート。
【図４１】遅いストレージに書き込むべきデータを退避用の専用のストレージに一時的に書き込み、後に、データをオリジナルのストレージに戻す処理の手順を示すフローチャート。
【図４２】遅いストレージに書き込むべきデータをノードモジュール（ＮＭ）内のＲＡＭに書き込む動作の概要を説明するための図。
【図４３】遅いストレージに書き込むべきデータをノードモジュール（ＮＭ）内のＲＡＭに一時的に書き込み、後に、データをオリジナルのストレージに戻す処理の手順を示すフローチャート。
【図４４】遅いストレージに書き込むべきデータを他のストレージ内の退避用の予約領域に書き込む動作の概要を説明するための図。
【図４５】遅いストレージに書き込むべきデータを他のストレージ内の退避用の予約領域に一時的に書き込み、後に、データをオリジナルのストレージに戻す動作を示すタイミングチャート。
【図４６】遅いストレージに書き込むべきデータを他のストレージ内の退避用の予約領域に一時的に書き込み、後に、データをオリジナルのストレージに戻す処理の手順を示すフローチャート。
【発明を実施するための形態】
【００１０】
以下、図面を参照して、実施形態を説明する。  
まず、図１を参照して、一実施形態に係るストレージシステムの構成を説明する。
【００１１】
このストレージシステム１は、複数のクライアント２の各々からの要求に応じて、様々なデータ操作（データ書き込み、データ読み出し、等）を伴う処理を実行するように構成されている。このストレージシステム１は、全てのデータをＮＡＮＤ型フラッシュメモリのような不揮発性メモリに格納することができる。
【００１２】
このストレージシステム１は、複数のＣＰＵ（プロセッサ）２１、マスタＣＰＵ（マスタプロセッサ）２２、および複数のストレージ３１を含み得る。
【００１３】
複数のストレージ３１の各々は、ＮＡＮＤ型フラッシュメモリのような不揮発性メモリを備える。各ストレージ３１は、そのストレージ内に設けられた不揮発性メモリにデータを書き込み、この不揮発性メモリからデータをリードするように構成された半導体ストレージデバイスとして機能する。
【００１４】
例えば、各ストレージ３１は、エンベデッドマルチメディアカード（ｅＭＭＣ（登録商標））、ソリッドステートドライブ（ＳＳＤ）、または不揮発性メモリを備える他の種類の半導体ストレージとして実現されている。以下では、限定されないが、各ストレージ３１がｅＭＭＣとして実現されている場合を想定する。
【００１５】
各ストレージ３１は複数の入出力ポートを有している。複数のストレージ３１は、互いの入出力ポートを介して相互に接続されている。相互接続されたこれらストレージ３１は、大容量のデータ記憶領域（ストレージアレイ）４０を論理的に構築する。
【００１６】
これらストレージ３１は、複数のＣＰＵ（プロセッサ）２１間で共有される。すなわち、ストレージシステム１においては、どのＣＰＵ２１も、データ記憶領域４０内の全てのストレージ３１をアクセスすることができ、このデータ記憶領域４０内の共有データは複数のＣＰＵ（プロセッサ）２１によって並列に処理することができる。したがって、ストレージシステム１は、データ記憶領域４０内の共有データを複数のＣＰＵ（プロセッサ）２１によって並列処理可能な分散処理システムとして機能し得る。
【００１７】
マスタＣＰＵ（マスタプロセッサ）２２は、ネットワーク３を介してクライアント２から要求を受信し、そして、この要求に応じた処理（ジョブとも云う）を一つ以上のＣＰＵ２１に割り当てる。処理が割り当てられた各ＣＰＵ２１は、このジョブに関連付けられた様々なデータ操作を実行する。例えば、各ＣＰＵ２１は、幾つかのストレージ３１を並列にアクセス（データ書き込み、データ読み出し）し、必要に応じて、リードデータに対してあるデータ処理を実行し、そして、レスポンス（書き込み完了レスポンス、読み出し完了レスポンス）またはデータ処理結果を、マスタＣＰＵ２２に返す。マスタＣＰＵ２２は、処理が割り当てられたＣＰＵ２１それぞれからレスポンスまたはデータ処理結果を受信し、これらレスポンスまたはデータ処理結果を統合し、統合されたレスポンスまたはデータ処理結果をネットワーク３を介してクライアント２に送信する。
【００１８】
なお、ここでは、専用のプロセッサがマスタＣＰＵ２２として使用されるシステム構成例について説明したが、複数のＣＰＵ２１内の少なくとも一つが、上述のマスタＣＰＵ２２の機能を兼ねてもよい。この場合、専用のマスタＣＰＵ２２を設ける必要は無い。
【００１９】
複数のＣＰＵ２１の各々は、アプリケーションプログラム１０１、オペレーティングシステム（ＯＳ）１０２、およびドライバプログラム１０３、等を実行する。
【００２０】
アプリケーションプログラム１０１は、マスタＣＰＵ（マスタプロセッサ）２２によって割り当てられた処理を実行する。アプリケーションプログラム１０１は、オペレーティングシステム１０２およびドライバプログラム１０３を介して、データ記憶領域（ストレージアレイ）４０上のデータをアクセスすることができる。より詳しくは、アプリケーションプログラム１０１は、全ての又は幾つかのストレージ（ｅＭＭＣ）３１向けのデータ入出力（Ｉ／Ｏ）要求を発行する。これらデータＩ／Ｏ要求は、データを書き込むためのライトコマンド、データを読み出すためのリードコマンドのような、データアクセスのための要求である。
【００２１】
各ＣＰＵ２１上のアプリケーションプログラム１０１は、クライアント２から見たときには、クライアント２からの要求に応じて各種サービスを実行するサーバアプリケーションとして機能する。
【００２２】
ドライバプログラム１０３は、各ストレージ３１をアクセスするように構成されたプログラムである。ドライバプログラム１０３は、いわゆるファームウェアであってもよい。各ＣＰＵ２１は、ドライバプログラム１０３を実行し、これによってアプリケーションプログラム１０１から発行されるデータＩ／Ｏ要求それぞれに応じて、全ての又は幾つかのストレージ（ｅＭＭＣ）３１をアクセスする。
【００２３】
図２は、ストレージシステム１の一実装例を示す。
【００２４】
図２の実装例においては、ストレージシステム１は、ネットワークスイッチ１０、複数のコネクションユニット（ＣＵ）２０、および複数のノードモジュール（ＮＭ）３０を備える。
【００２５】
各ノードモジュール（ＮＭ）３０は、一つのストレージノードとして機能する。各ノードモジュール（ＮＭ）３０は、上述した一つのストレージ３１と、ノードコントローラ（ＮＣ）３２とを含む。ノードコントローラ（ＮＣ）３２は、ノードモジュール（ＮＭ）３０内のストレージ３１に対するアクセス制御と、データＩ／Ｏ要求およびデータの転送制御とを実行する。
【００２６】
ノードコントローラ（ＮＣ）３２は、複数の入出力ポート（たとえば４つの入出力ポート）を有する。複数のノードモジュール（ＮＭ）３０は、互いの入出力ポートが相互接続されることによって例えばマトリクス状に接続される。接続の形態はマトリクス状に限られない。
【００２７】
複数のコネクションユニット（ＣＵ）２０は、ネットワークスイッチ１０を介してクライアント２に接続される。各コネクションユニット（ＣＵ）２０は、上述の一つのＣＰＵ２１と、ＲＡＭ（例えばＤＲＡＭ）２２と、ノードモジュールインタフェース（ＮＭ  Ｉ／Ｆ）２３とを含む。複数のコネクションユニット（ＣＵ）２０の何れかは、上述のマスタＣＰＵ２２として機能してもよい。
【００２８】
複数のコネクションユニット（ＣＵ）２０は、異なるノードモジュール（ＮＭ）３０に直接的にそれぞれ接続されている。各コネクションユニット（ＣＵ）２０においては、ノードモジュールインタフェース（ＮＭ  Ｉ／Ｆ）２３は、一つのノードモジュール（ＮＭ）３０内のノードコントローラ（ＮＣ）３２と接続されている。つまり、各コネクションユニット（ＣＵ）２０は、ノードモジュールインタフェース（ＮＭ  Ｉ／Ｆ）２３を介して、複数のノードモジュール（ＮＭ）３０の中のいずれか１つのノードモジュール（ＮＭ）３０と直接的に接続され、且つこのノードモジュール（ＮＭ）３０を介して他のノードモジュール（ＮＭ）３０それぞれと間接的に接続される。
【００２９】
各コネクションユニット（ＣＵ）２０は、どのノードモジュール（ＮＭ）３０宛てにデータＩ／Ｏ要求（コマンド）を送出する場合であっても、このデータＩ／Ｏ要求（コマンド）を、まず、各コネクションユニット（ＣＵ）２０に直接的に接続されるノードモジュール（ＮＭ）３０に送出する。その後、そのデータＩ／Ｏ要求（コマンド）は、幾つかのノードモジュール（ＮＭ）３０を介して目的のノードモジュール（ＮＭ）３０に自動的に転送される。
【００３０】
たとえば、複数のノードモジュール（ＮＭ）３０が複数の行および複数の列によって規定されるマトリクス状に接続されている場合においては、これらノードモジュール（ＮＭ）３０には、これらノードモジュール（ＮＭ）３０が配置されているマトリクス内の位置を示す座標（Ｍ，Ｎ）が、その識別子（ノードアドレス）として付与されてもよい。ここで、Ｍは行番号を表し、Ｎは列番号を表す。例えば、マトリクス内の左上隅に位置するノードモジュール（ＮＭ）３０の識別子（ノードアドレス）は、（０，０）である。
【００３１】
各ノードモジュール（ＮＭ）３０においては、ノードコントローラ（ＮＣ）３２は、自身のＮＭ３０の識別子（ノードアドレス）と、データＩ／Ｏ要求内に含まれる宛先識別子（宛先アドレス）とを比較することにより、受信されたデータＩ／Ｏ要求が自身のＮＭ３０宛てのデータＩ／Ｏ要求であるか否かを判定できる。
【００３２】
自身のＮＭ３０ＮＭ３０宛てのデータＩ／Ｏ要求ではない場合、ノードコントローラ（ＮＣ）３２は、自身のＮＭ３０の識別子の行番号および列番号と、受信されたデータＩ／Ｏ要求内の宛先識別子の行番号および列番号それぞれとの間の大小関係から、受信されたデータＩ／Ｏ要求を転送すべき隣接するノードモジュール（ＮＭ）３０を決定できる。
【００３３】
また、アクセス結果（コマンド完了レスポンス、読み出しデータ、等）も、前述したデータＩ／Ｏ要求の転送と同様に、複数のＮＣ３１の働きにより、アクセスされたノードモジュール（ＮＭ）３０から、データＩ／Ｏ要求を発行したコネクションユニット（ＣＵ）２０に転送される。また、図示はしないが、コネクションユニット（ＣＵ）２０はノードモジュールインタフェース（ＮＭ  Ｉ／Ｆ）２３を複数有していても良い。その際、それぞれのノードモジュールインタフェース（ＮＭ  Ｉ／Ｆ）２３は、それぞれ別のノードコントローラ（ＮＣ）３２に接続されていても良い。これにより、平常時のアクセス性能が向上するだけでなく、ノードモジュールインタフェース（ＮＭ  Ｉ／Ｆ）２３やノードコントローラ（ＮＣ）３２等が故障した際の耐障害性を高めることができる。
【００３４】
図３は、各コネクションユニット（ＣＵ）２０の構成を示す。
【００３５】
各コネクションユニット（ＣＵ）２０において、ＣＰＵ２１は、ＲＡＭ（例えばＤＲＡＭ）３２上のアプリケーションプログラム１０１、オペレーティングシステム１０２、およびドライバプログラム（ＣＵドライバ）１０３を実行する。アプリケーションプログラム１０１上においては、複数のスレッド１１１が走る。これらスレッド１１１は、異なるストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求を発行してもよい。また、アプリケーションプログラム１０１は、マネージャ１１２を含む。マネージャ１１２は、各スレッド１１１を制御する。例えば、マネージャ１１２は、必要に応じて、特定のスレッド１１１をスリープ状態に設定してもよく、さらに、このスリープ状態の特定のスレッド１１１を、必要に応じて、ウェイクアップさせてもよい。さらに、マネージャ１１２は、必要に応じてドライバプログラム（ＣＵドライバ）１０３と通信することによって、目的のストレージ（ｅＭＭＣ）３１のステータスを取得することもできる。
【００３６】
さらに、ＲＡＭ（例えばＤＲＡＭ）３２上においてはキュー２００が用意されている。キュー２００は、ドライバプログラム（ＣＵドライバ）１０３によって管理されるキュー（ＣＵドライバキュー）である。アプリケーションプログラム１０１によって発行されるデータＩ／Ｏ要求それぞれはこのキュー２００に入れられる。ＣＰＵ２１は、ドライバプログラム（ＣＵドライバ）１０３の制御の下、キュー２００内のデータＩ／Ｏ要求それぞれを対応するストレージ（ｅＭＭＣ）３１に送出する。ストレージ（ｅＭＭＣ）３１には、リードやライトのコマンドとして許されている最小データサイズ（例えば１セクタ、５１２ｂｙｔｅなど）とは別に、アクセスに適しているデータサイズ（例えば８セクタ、４ＫｉＢなど）があることが知られている。アクセスに適したリードライトサイズになるようにデータＩ／Ｏ要求をためることが、キューを用意する目的の一つとして挙げられる。
【００３７】
図４は、各ノードモジュール（ＮＭ）３０の構成を示す。
【００３８】
前述したように、ＮＭ３０は、ノードコントローラ（ＮＣ）３２と、ストレージ（ｅＭＭＣ）３１とを含む。ノードコントローラ（ＮＣ）３２は、ＣＰＵ３１１、ＲＡＭ（例えばＤＲＡＭ）３１２、Ｉ／Ｏコントローラ３１３、およびＮＡＮＤインタフェース３１４を備える。ノードコントローラ（ＮＣ）３２の各機能は、ＲＡＭ３１２に格納されたプログラムにより実現される。Ｉ／Ｏコントローラ３１３は、コネクションユニット（ＣＵ）２０用の一つのＩ／Ｏポートと、ノードモジュール（ＮＭ）３０用の四つのＩ／Ｏポートとを備えていてもよい。あるいは、ノードコントローラ（ＮＣ）３２の一部あるいは全部をＦＰＧＡ（field-programmable gate array）により実装しても良い。また、一つのＦＰＧＡで一つのノードコントローラ（ＮＣ）３２を実装するだけでなく、一つのＦＰＧＡで複数のノードコントローラ（ＮＣ）３２を集約して実装しても良い。
【００３９】
図５は、アプリケーションプログラム１０１と、キュー１０３と、複数のストレージ（ｅＭＭＣ）３１との間の関係を示す。
【００４０】
アプリケーションプログラム１０１は、データ書き込み、データ読み出し等のために、幾つかのストレージ３１向けのデータＩ／Ｏ要求（例えば、ライトコマンド、リードコマンド、等）を発行する。各ストレージ（ｅＭＭＣ）３１は、その容量に対応する論理ブロックアドレス範囲（ＬＢＡ範囲（ＬＢＡ０〜ＬＢＡｎ））を有していてもよい。
【００４１】
データＩ／Ｏ要求の各々は、一つのストレージ（ｅＭＭＣ）３１を指定する宛先アドレス（宛先識別子）を含んでもよい。データＩ／Ｏ要求がデータ書き込み要求（ライトコマンド）である場合には、データＩ／Ｏ要求は、さらに、開始ＬＢＡ、データ転送長、および書き込むべきデータを含んでいてもよい。開始ＬＢＡは、データが書き込まれるべき最初の論理ブロックアドレスを示す。データＩ／Ｏ要求がデータ読み出し要求（リードコマンド）である場合には、データＩ／Ｏ要求は、開始ＬＢＡ、データ転送長を含んでいてもよい。開始ＬＢＡは、データが読み出されるべき最初の論理ブロックアドレスを示す。
【００４２】
アプリケーションプログラム１０１によって発行されるデータＩ／Ｏ要求それぞれは、ＣＵドライバプログラム１０３のキュー２００に入れられる。ＣＵドライバプログラム１０３は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する。送出可能でない各データＩ／Ｏ要求は、キュー２００から送出されずに、キュー２００内に残される。
【００４３】
送出可能でないデータＩ／Ｏ要求の例には、ガベージコレクションを含むバックグラウンド動作の実行によってアクセス速度が遅くなっている遅いストレージ（遅いｅＭＭＣ）３１向けのデータＩ／Ｏ要求が含まれる。
【００４４】
ＮＡＮＤ型フラッシュメモリのような不揮発性メモリを含むストレージにおいては、データＩ／Ｏ要求（コマンド）の受信からそのコマンドの完了までの時間（レイテンシ、または応答時間と称される）は常に一定ではなく、時折、レイテンシが極端に大きくなる場合がある。通常は、ストレージ（ｅＭＭＣ）３１は、高速にデータアクセスすることができる（ローレイテンシ）。しかし、ストレージ（ｅＭＭＣ）３１は、ガベージコレクションを含むバックグラウンド動作を、時折、実行する。バックグラウンド動作（ガベージコレクション）が実行されている間は、レイテンシは極端に大きくなる。つまり、バックグラウンド動作を実行中のストレージ（ｅＭＭＣ）３１は、遅いストレージ（遅いｅＭＭＣ）３１となる。この極端に大きくなったレイテンシは、「ジャイアントレイテンシ」と称される。
【００４５】
通常、あるストレージ（ｅＭＭＣ）３１内の不揮発性メモリ（ＮＡＮＤ型フラッシュメモリ）のフリースペースが閾値を下回った時、このストレージ（ｅＭＭＣ）３１は、フリースペースを増やすためにバックグラウンド動作（ガベージコレクション）を自動的に開始する。バックグラウンド動作（ガベージコレクション）は、ＮＡＮＤ型フラッシュメモリ内のフリーブロックの個数を増やすため、有効データと無効データの混在する幾つかのブロックを使用して、有効データのみを別のブロック（フリーブロック）に集める。ガベージコレクション動作においては、有効データと無効データとが混在する幾つかのブロックから有効データが読み出され、読み出された有効データが、あるブロック（フリーフロック）にコピーされる。このコピーの結果、有効データが特定の幾つかのブロック（フリーフロック）に集められる。有効データがフリーフロックにコピーされることによって無効データのみとなった各ブロックは、その消去後に、フリーブロックとして再利用することが可能となる。
【００４６】
ストレージ（ｅＭＭＣ）３１へのライトコマンドそれぞれの送出はストレージ（ｅＭＭＣ）３１におけるガベージコレクション動作を引き起こし、この結果、このストレージ（ｅＭＭＣ）３１におけるレイテンシが、時折、極端に長くなる（ジャイアントレイテンシ）。
【００４７】
ライトコマンドのレイテンシは通常は例えば２００マイクロ秒以下である。一方、ジャイアントレイテンシは例えば２０〜３０ミリ秒程度になる。
【００４８】
ジャイアントレイテンシの起こり易さは、アクセスパターンによって異なる。一般に、以下のようなことが知られている。
【００４９】
・小さいサイズのランダムライト（例えば、４ＫｉＢランダムライト）の時に、ジャイアントレイテンシが起こり易い。
【００５０】
・広範囲ランダムライト（例えば、１００％範囲ランダムライト）の時に、ジャイアントレイテンシが起こり易い。つまり、ストレージの容量に対するランダムライト範囲の比率（パーセント）が大きくなるほど、ジャイアントレイテンシが起こり易い。
【００５１】
・シーケンシャルライトの時にはジャイアントレイテンシが起こり難い。
【００５２】
あるストレージ（ｅＭＭＣ）３１がガベージコレクションを含むバックグラウンド動作を実行することによって遅いｅＭＭＣとなった場合、つまり、あるストレージ（ｅＭＭＣ）３１においてジャイアントレイテンシが起きた場合、ドライバプログラム（ＣＵドライバ）１０３は、データＩ／Ｏ要求（コマンド）を効率良く送出することができなくなる場合がある。この理由は、以下の通りである。
【００５３】
遅いｅＭＭＣ向けのコマンドは、キュー２００から送出されずに、キュー２００内に残される。したがって、ドライバプログラム（ＣＵドライバ）１０３が他のｅＭＭＣ向けのコマンドをキュー２００内の任意のエントリーから取り出させるように構成されているケースにおいては、やがて、キュー２００が、遅いｅＭＭＣ向けのコマンドで満杯になってしまう可能性がある。キュー２００が遅いｅＭＭＣ向けのコマンドで満杯の場合、他のストレージ（ｅＭＭＣ）３１向けの新たなコマンドをキュー２００に入れることができなくなる。したがって、あるストレージ（ｅＭＭＣ）３１においてジャイアントレイテンシが起きている間は、ジャイアントレイテンシが起きているｅＭＭＣ３１のみならず、他のｅＭＭＣ３１それぞれへのアクセス効率も低下されてしまう場合がある。
【００５４】
この結果、アクセスの並列度（ｃｏｎｃｕｒｒｅｎｃｙ）が抑えられ、ストレージシステム１の性能が低下される。
【００５５】
図６は、ストレージシステムにおける理想的な並列度と実際の並列度との関係を示す。
【００５６】
図６においては、四つのｅＭＭＣ（ｅＭＭＣ＃１、ｅＭＭＣ＃２、ｅＭＭＣ＃３、ｅＭＭＣ＃４）が並列にアクセスされる場合が想定されている。図６において、幅の狭い矩形は通常レイテンシを表し、幅の広い矩形はジャイアントレイテンシを表している。
【００５７】
たとえｅＭＭＣ＃２においてジャイアントレイテンシが起きたとしても、図６の左部に示すように、並列度が常に最大並列度（この例では、４）であることが理想である。
【００５８】
しかし、実際には、図６の右部に示すように、ｅＭＭＣ＃２にジャイアントレイテンシが起きている間は、ジャイアントレイテンシが起きていないｅＭＭＣ＃１、ｅＭＭＣ＃３、ｅＭＭＣ＃４向けのコマンドも効率良く送出することができなくなる場合がある。このため、ジャイアントレイテンシは並列度を下げる。
【００５９】
バックグラウンド動作（ガベージコレクション）が終了されることによって、やがて、極端に大きなレイテンシを伴うコマンド（ジャイアントレイテンシコマンド）の実行も終了する。しかし、ジャイアントレイテンシコマンドが終了した直後においても、並列度は低いままに維持されてしまう。低並列度は、ストレージシステム１の性能低下の要因となる。
【００６０】
図７は、このような低並列度が起きる要因を示す。
【００６１】
（１）ドライバプログラム（ＣＵドライバ）１０３は、遅いｅＭＭＣ向けのコマンドを送出できず、遅いｅＭＭＣ向けのこれらコマンドがキュー２００に留まる。
【００６２】
（２）ドライバプログラム（ＣＵドライバ）１０３は、他のｅＭＭＣ向けのコマンドを送出可能である。
【００６３】
（３）やがて、キュー２００内の全てのコマンドは遅いｅＭＭＣ向けのものとなる。
【００６４】
（４）キュー２００が満杯なので、アプリケーションプログラム１０１はどのコマンドもキュー２００に入れることができない。
【００６５】
以下、図８〜図１０を参照して、低並列度の分析の詳細を説明する。
【００６６】
（１）図８に示すように、例えばｅＭＭＣ＃２が、バックグラウンド動作を開始すると、ｅＭＭＣ＃２においてはコマンドの処理に長時間かかる（ジャイアントレイテンシ）。
【００６７】
（２）やがて、キュー２００内の全てのコマンドは遅いｅＭＭＣ（ｅＭＭＣ＃２）向けのものとなる。
【００６８】
（３）アプリケーションプログラム１０１はどのコマンドもキュー２００に入れることができず、並列度が低下する。
【００６９】
（４）やがて、ｅＭＭＣ＃２においてバックグラウンド動作が完了することによって、図９に示すように、ジャイアントレイテンシコマンドも終了する。これにより、ｅＭＭＣ＃２のレイテンシは、通常使用時のレイテンシ（ノーマルレイテンシ）に回復される。
【００７０】
（５）しかし、しばらくの間は、キュー２００内のコマンドの多くは、遅かったｅＭＭＣ（ｅＭＭＣ＃２）向けのものである。
【００７１】
（６）他のｅＭＭＣ（ｅＭＭＣ＃１、ｅＭＭＣ＃３、ｅＭＭＣ＃４）向けの十分なコマンドの数がキュー２００内に無いので、並列度は回復されない。
【００７２】
（７）図１０に示すように、やがて、キュー２００においては、他のｅＭＭＣ（ｅＭＭＣ＃１、ｅＭＭＣ＃３、ｅＭＭＣ＃４）向けのコマンドの数が増加する。
【００７３】
（８）これによって、並列度が回復する。
【００７４】
図１１は、アプリケーションプログラム１０１が全てのコマンドの完了を待つケースを示す。
【００７５】
アプリケーションプログラム１０１が全てのコマンドの完了を待つケースにおいては、アプリケーションプログラム１０１は、全てのコマンドが完了するまでは、次の処理に進まない。このケースにおいては、ジャイアントレイテンシに伴う性能低下は表面化されない。
【００７６】
図１１においては、アプリケーションプログラム１０１がｅＭＭＣ毎に８個のコマンドの完了を待つケースが例示されている。
【００７７】
アプリケーションプログラム１０１が全てのコマンドの完了を待つケースにおいては、キュー２００は、遅かったｅＭＭＣ（ｅＭＭＣ＃２）向けの全てのコマンド（ここでは８個のコマンド）が完了した時に空になる。この後、キュー２００内のコマンドの宛先は上手く分散され、これによって最大並列度がすぐに回復される。
【００７８】
以上の解析から、次のことが理解されよう。
【００７９】
ドライバプログラム（ＣＵドライバ）１０３は、一つのキュー２００のみを有する。このため、あるｅＭＭＣがコマンドの実行に長い時間を要した場合、キュー２００は、この遅いｅＭＭＣ向けのコマンドで満杯になり、他のｅＭＭＣ向けのコマンドを受信できなくなる。この結果、並列度が低くなる。ジャイアントレイテンシコマンドの終了直後は、キュー２００内の多くのコマンドは、遅かったｅＭＭＣ向けのコマンドである。他のｅＭＭＣは十分なコマンドを受け取ることができず、これによって並列度が低く維持される。
【００８０】
アプリケーションプログラム１０１が全てのコマンドの完了を待つケースにおいては、ジャイアントレイテンシに伴う性能低下は表面化されない。
【００８１】
したがって、アプリケーションプログラム１０１が全てのコマンドの完了を待つケースでは、ジャイアントレイテンシの期間に並列度が低くなることを避ける対策を講じてもあまり効果は得られないが、他のケースでは、並列度が低くなることを避けるための対策が要求される。
【００８２】
この対策は、次の２つに大別される。
【００８３】
パート１：キューの効率的な使用方法
１−１：アプリケーションプログラムと連携する
１−２：ＣＵドライバまたはＮＭで対処する
パート２：書き込みコマンドをジャイアントレイテンシにオーバーラップさせることによって性能向上を図る方法
２−１：アプリケーションプログラムと連携する
２−２：ＣＵドライバまたはＮＭで対処する
まず、パート１：キューの効率的な使用方法について説明する。
【００８４】
図１２は、ストレージシステム１によって実行されるＩ／Ｏ管理の基本コンセプトを示す。
【００８５】
アプリケーションプログラム１０１は、遅いノードモジュール（遅いＮＭ）、つまり遅いｅＭＭＣを含むノードモジュールを検出して、遅いＮＭへのデータＩ／Ｏ要求の発行を停止する。この場合、アプリケーションプログラム１０１は、ポーリングによって各ＮＭのステータス（つまり、各ｅＭＭＣのステータス）を監視することによって遅いＮＭを検出してもよい。あるいは、ドライバプログラム（ＣＵドライバ）１０３が各ＮＭのステータス（つまり、各ｅＭＭＣのステータス）を監視することによって遅いＮＭを検出し、遅いＮＭをアプリケーションプログラム１０１に通知してもよい。
【００８６】
あるいは、各ＮＭから通知されるステータスに基づいて、アプリケーションプログラム１０１またはドライバプログラム（ＣＵドライバ）１０３が、遅いＮＭを検出してもよい。
【００８７】
図１２では、アプリケーションプログラム１０１のマネージャ１１２が、ポーリングによって、またはドライバプログラム（ＣＵドライバ）１０３または各ＮＭからの通知によって、各ＮＭのステータス（ビジー、レディー）を検出するケースが想定されている。
【００８８】
ビジーは、あるＮＭ内のｅＭＭＣのアクセス速度が遅くなっていることを示す。レディーは、あるＮＭ内のｅＭＭＣが通常のレイテンシで動作可能であることを示す。
【００８９】
アプリケーションプログラム１０１上では、４つのスレッド１１１（Ｔｈｒｅａｄ−１、Ｔｈｒｅａｄ−２、Ｔｈｒｅａｄ−３、Ｔｈｒｅａｄ−４）が実行される。Ｔｈｒｅａｄ−１は、ＮＭ−１をアクセスするためのデータＩ／Ｏ要求それぞれを発行する。Ｔｈｒｅａｄ−２は、ＮＭ−２をアクセスするためのデータＩ／Ｏ要求それぞれを発行する。Ｔｈｒｅａｄ−３は、ＮＭ−３をアクセスするためのデータＩ／Ｏ要求それぞれを発行する。Ｔｈｒｅａｄ−４は、ＮＭ−４をアクセスするためのデータＩ／Ｏ要求それぞれを発行する。なお、スレッドの数は４に限られない。また、スレッドとアクセス先のＮＭとの対応付けはこれに限られない。以降の説明は適宜読み替え可能である。
【００９０】
マネージャ１１２がＮＭ−１のビジーを検出した時、マネージャ１１２は、Ｔｈｒｅａｄ−１を制御して、Ｔｈｒｅａｄ−１にデータＩ／Ｏ要求（ＮＭ−１向けのデータＩ／Ｏ要求）の発行を停止させる。この場合、マネージャ１１２は、Ｔｈｒｅａｄ−１をスリープさせてもよい。ＮＭ−１向けのデータＩ／Ｏ要求の発行を停止することにより、他のＮＭ向けの新たなデータＩ／Ｏ要求を入れることが可能な空き領域をキュー２００内に確保することができるので、キュー２００は他のＮＭ向けの新たなデータＩ／Ｏ要求を受信することができる。よって、ＮＭ−１にジャイアントレイテンシが起こっている間、他のＮＭにデータＩ／Ｏ要求を効率良く送出することが可能となる。
【００９１】
遅くなっているＮＭ−１向けの新たなデータＩ／Ｏ要求は発行できなくなる。しかし、たとえ遅くなっているＮＭ−１向けの新たなデータＩ／Ｏ要求が発行されてキュー２００に入れられても、このデータＩ／Ｏ要求は、遅くなっているＮＭ−１のレイテンシが回復されるまではＮＭ−１に送出できない。したがって、遅くなっているＮＭ−１向けの新たなデータＩ／Ｏ要求の発行を停止しても、これによって何らかの悪影響がでることはない。
【００９２】
この後、マネージャ１１２がＮＭ−１のレディーを検出した時、マネージャ１１２は、Ｔｈｒｅａｄ−１を制御して、Ｔｈｒｅａｄ−１にデータＩ／Ｏ要求（ＮＭ−１向けのデータＩ／Ｏ要求）の発行を再開させる。この場合、マネージャ１１２は、Ｔｈｒｅａｄ−１をウェイクアップさせてもよい。これにより、並列度は最大並列度に回復される。
【００９３】
同様に、マネージャ１１２がＮＭ−４のビジーを検出した時、マネージャ１１２は、Ｔｈｒｅａｄ−４を制御して、Ｔｈｒｅａｄ−４にデータＩ／Ｏ要求（ＮＭ−４向けのデータＩ／Ｏ要求）の発行を停止させる。この場合、マネージャ１１２は、Ｔｈｒｅａｄ−４をスリープさせてもよい。この後、マネージャ１１２がＮＭ−４のレディーを検出した時、マネージャ１１２は、Ｔｈｒｅａｄ−４を制御して、Ｔｈｒｅａｄ−４にデータＩ／Ｏ要求（ＮＭ−４向けのデータＩ／Ｏ要求）の発行を再開させる。この場合、マネージャ１１２は、Ｔｈｒｅａｄ−４をウェイクアップさせてもよい。
【００９４】
図１３は、ストレージシステム１に適用されるステータス取得動作の例を示す。
【００９５】
ドライバプログラム（ＣＵドライバ）１０３は、ＮＭステータスを取得するためのアプリケーションプログラムインタフェース（ＡＰＩ）を有している。マネージャ１１２は、このＡＰＩを使用することによって、目的の各ＮＭのステータスをドライバプログラム（ＣＵドライバ）１０３から容易に取得することができる。
【００９６】
ＮＭ（ｅＭＭＣ）がレディーならば、アプリケーションプログラム１０１は、このＮＭ（ｅＭＭＣ）向けのデータＩ／Ｏ要求を発行する。
【００９７】
ＮＭ（ｅＭＭＣ）がビジーならば、アプリケーションプログラム１０１は、このＮＭ（ｅＭＭＣ）向けのデータＩ／Ｏ要求の発行を停止する。そして、ＡＰＩによってこのＮＭのステータス変化（ビジー  →  レディー）を検出したとき、アプリケーションプログラム１０１は、このＮＭ向けのデータＩ／Ｏ要求の発行を再開する。
【００９８】
図１４は、遅いＮＭ（遅いｅＭＭＣ）の検出に応答してストレージシステム１によって実行される動作の概要を示す。
【００９９】
図１４では、ＮＭ＃１（ｅＭＭＣ＃１）においてジャイアントレイテンシが起きた場合が想定されている。
【０１００】
（１）ＮＭ＃１（ｅＭＭＣ＃１）においてジャイアントレイテンシが起きた時、ＮＭ＃１（ｅＭＭＣ＃１）がビジーであることが、ＮＭ＃１またはドライバプログラム（ＣＵドライバ）１０３から、アプリケーションプログラム１０１に通知されてもよい。
【０１０１】
（２）アプリケーションプログラム１０１は、ＮＭ＃１（ｅＭＭＣ＃１）がビジーであることを示す通知を受信する。そして、アプリケーションプログラム１０１は、この遅いＮＭ＃１（ｅＭＭＣ＃１）向けのデータＩ／Ｏ要求の発行を停止する。遅いＮＭ＃１（ｅＭＭＣ＃１）向けのデータＩ／Ｏ要求の発行を停止することにより、他のＮＭ向けの新たなデータＩ／Ｏ要求を入れることが可能な空き領域をキュー２００内に確保することができる。したがって、キュー２００が、遅いＮＭ＃１（ｅＭＭＣ＃１）向けのデータＩ／Ｏ要求で満杯になり、他のＮＭ向けのデータＩ／Ｏ要求を受け取ることができなくなることを防止できる。
【０１０２】
（３）アプリケーションプログラム１０１は、必要に応じて、ＮＭ＃１（ｅＭＭＣ＃１）に対して追加のバックグラウンド動作（ＢＫＯＰＳ）の開始を指示してもよい。
【０１０３】
通常、遅いＮＭによって実行中のバックグラウンド動作（ガベージコレクション（ＧＣ））は、Ｉ／Ｏコマンドをなるべく早期に完了できるようにするために、必要最小限度のフリースペースのみを作り出すガベージコレクション動作を実行する。このため、遅いＮＭのレイテンシが回復した後に幾つかのライトコマンドがこのＮＭに送出されると、このＮＭの次のＧＣタイミングがすぐに到来し、このＮＭは再びバックグラウンド動作を開始する可能性がある。この場合、このＮＭは再び遅いＮＭとなる。したがって、ＮＭ＃１（ｅＭＭＣ＃１）に対して、必要最小限度のフリースペースよりも多くの量のフリースペースを作り出す追加のバックグラウンド動作（ＢＫＯＰＳ）の開始を指示することにより、ＮＭ＃１の次のＧＣタイミングまでの時間を確保することが期待できる。なお、ＢＫＯＰＳの開始を指示する前に、アプリケーションプログラム１０１は、不要データを無効化するためのトリムコマンドをＮＭ＃１（ｅＭＭＣ＃１）に送出してもよい。
【０１０４】
（４）ＮＭ＃１（ｅＭＭＣ＃１）においてジャイアントレイテンシコマンドが終了した時、ＮＭ＃１（ｅＭＭＣ＃１）がレディーであることが、ＮＭ＃１またはドライバプログラム（ＣＵドライバ）１０３から、アプリケーションプログラム１０１に通知されてもよい。この通知に応答して、アプリケーションプログラム１０１は、ＮＭ＃１（ｅＭＭＣ＃１）向けのデータＩ／Ｏ要求の発行を再開する。
【０１０５】
なお、ＮＭ＃１（ｅＭＭＣ＃１）がビジーである間、アプリケーションプログラム１０１は、この遅いＮＭ＃１（ｅＭＭＣ＃１）に書き込むべき後続のデータを退避用の予約領域に一時的に書き込み、後に、このデータを退避用の予約領域からＮＭ＃１（ｅＭＭＣ＃１）に戻してもよい。データを退避用の予約領域に一時的に書き込むための処理においては、アプリケーションプログラム１０１は、この遅いＮＭ＃１（ｅＭＭＣ＃１）向けのデータ書き込み要求（ライトコマンド）の発行を停止し、代わりに、ｅＭＭＣ＃１に書き込むべきデータを退避用の予約領域に書き込むための別のデータ書き込み要求を（別のライトコマンド）を発行する。
【０１０６】
これにより、遅いＮＭ＃１（ｅＭＭＣ＃１）のジャイアントレイテンシコマンドの終了を待つことなく、遅いＮＭ＃１（ｅＭＭＣ＃１）に書き込むべき後続のデータを、退避用の予約領域に書き込むことができる。退避用の予約領域は、遅いＮＭ＃１（ｅＭＭＣ＃１）とは異なる任意の記憶領域である。例えば、退避用の予約領域は、遅いＮＭ＃１（ｅＭＭＣ＃１）以外の他のｅＭＭＣであってもよいし、退避用の専用のｅＭＭＣであってもよいし、あるいは、いずれかのＮＭ内のＲＡＭ（ＤＲＡＭ）であってもよい。
【０１０７】
図１５のフローチャートは、遅いストレージの検出に応答してストレージシステム１によって実行される処理の手順を示す。
【０１０８】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ１１）。
【０１０９】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ１２）。
【０１１０】
ＣＰＵ２１が、バックグラウンド動作の実行によってアクセス速度が遅くなっている遅いストレージ（遅いｅＭＭＣ）３１を検出した時（ステップＳ１３のＹＥＳ）、ＣＰＵ２１は、遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求をキュー２００に留めた状態で、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求をキュー２００から他のｅＭＭＣ３１に向けて送出する。さらに、ＣＰＵ２１は、アプリケーションプログラム１０１による遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を停止する（ステップＳ１４）。ステップＳ１４では、アプリケーションプログラム１０１は、遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求のみの発行を停止し、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を継続する。ステップＳ１４では、ＣＰＵ２１は、遅いｅＭＭＣ３１に対してＢＫＯＰＳの開始を指示してもよい。
【０１１１】
アプリケーションプログラム１０１が遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を停止するので、遅いｅＭＭＣ以外の他のｅＭＭＣ３１向けのデータＩ／Ｏ要求を入れることが可能な空き領域をキュー２００に確保することができる。この結果、キュー２００が、遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求で満杯になり、これによって他のｅＭＭＣ向けのコマンドを受信できなくなる、という状況が発生するのを防ぐことができる。したがって、たとえ、あるｅＭＭＣ３１にジャイアントレイテンシが起きても、図６の左部に示されている理想的な状態が実現されることが期待できる。発行が停止される対象のデータＩ／Ｏ要求の種類は、データ書き込み要求およびデータ読み出し要求の双方であってもよい。あるいは、データ書き込み要求の発行のみを停止してもよい。
【０１１２】
この後、ＣＰＵ２１は、ジャイアントレイテンシコマンドが終了したか否か、つまり遅いｅＭＭＣ３１のアクセス速度が通常のアクセス速度に回復したか否かを判定する（ステップＳ１５）。このｅＭＭＣ３１のアクセス速度が回復したならば（ステップＳ１５のＹＥＳ）、ＣＰＵ２１は、アプリケーションプログラム１０１によるこのｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を再開する（ステップＳ１６）。
【０１１３】
なお、上述したように、あるｅＭＭＣ３１のアクセス速度が遅くなっている間、アプリケーションプログラム１０１は、この遅いｅＭＭＣ３１に書き込むべきデータを退避用の予約領域に一時的に書き込み、後に、このデータを退避用の予約領域からオリジナルｅＭＭＣ（遅かったｅＭＭＣ）に戻してもよい。データは、遅いｅＭＭＣ３１のアクセス速度が通常のアクセス速度に回復した後に、退避用の予約領域からオリジナルｅＭＭＣに戻してもよい。
【０１１４】
図１６のフローチャートは、アプリケーションプログラム１０１によって実行されるデータＩ／Ｏ要求制御処理の手順を示す。
【０１１５】
遅いｅＭＭＣが検出されるまでは、アプリケーションプログラム１０１は、アクセス対象の幾つかのｅＭＭＣ向けのデータ書き込み要求をそれぞれ発行するという通常のデータ書き込み要求発行処理を実行する（ステップＳ２１）。
【０１１６】
アクセス対象の幾つかのｅＭＭＣ内の一つのｅＭＭＣが遅いｅＭＭＣとして検出されたならば（ステップＳ２２のＹＥＳ）、アプリケーションプログラム１０１は、遅いｅＭＭＣ向けのデータ書き込み要求（ライトコマンド）の発行を停止し、且つ遅いｅＭＭＣに書き込むべき後続のデータを、遅いｅＭＭＣとは異なる退避用の予約領域に一時的に書き込む（ステップＳ２３）。ステップＳ２３では、アプリケーションプログラム１０１は、退避用の予約領域向けのデータ書き込み要求（ライトコマンド）を発行する。この退避用の予約領域向けのデータ書き込み要求は、キュー２００に入れられる。この退避用の予約領域向けのデータ書き込み要求は、送出可能なデータＩ／Ｏ要求であるので、キュー２００に長い間留まることはない。ステップＳ２３では、アプリケーションプログラム１０１は、さらに、データの書き込まれるべきアドレスとこのデータの退避先アドレスとの間の関係を示す退避情報を記録する。
【０１１７】
遅いｅＭＭＣのアクセス速度が回復したならば（ステップＳ２４のＹＥＳ）、アプリケーションプログラム１０１は、退避用の予約領域向けに書き込んだデータを、遅かったｅＭＭＣ内の元の格納位置に戻す（ステップＳ２５）。ステップＳ２５では、アプリケーションプログラム１０１は、さらに、戻したデータに対応する退避情報を削除する。
【０１１８】
図１７は、遅くなりそうなストレージの予測に基づいて、ストレージシステム１によって実行される動作の概要を示す。
【０１１９】
ストレージシステム１は、さらに、遅くなりそうなＮＭ（ｅＭＭＣ）を予測する機能を備え得る。遅くなりそうなＮＭ（ｅＭＭＣ）は、バックグラウンド動作（ガベージコレクション）の開始が必要とされることによってアクセス速度が遅くなることが予想されるストレージである。遅くなりそうなＮＭ（ｅＭＭＣ）を予測する機能は、アプリケーションプログラム１０１、ドライバプログラム（ＣＵドライバ）１０３、または各ＮＭ（ｅＭＭＣ）のいずれによって実行されてもよい。
【０１２０】
アプリケーションプログラム１０１が予測機能を実行する場合には、アプリケーションプログラム１０１は、遅くなりそうなＮＭ（ｅＭＭＣ）を予測し、このＮＭ（ｅＭＭＣ）を、遅くなりそうなストレージとして特定する。
【０１２１】
ドライバプログラム（ＣＵドライバ）１０３が予測機能を実行する場合には、ドライバプログラム（ＣＵドライバ）１０３は、遅くなりそうなＮＭ（ｅＭＭＣ）を予測し、このＮＭ（ｅＭＭＣ）をアプリケーションプログラム１０１に通知する。アプリケーションプログラム１０１は、このＮＭ（ｅＭＭＣ）を、遅くなりそうなストレージとして特定することができる。
【０１２２】
各ＮＭ（ｅＭＭＣ）が予測機能を実行する場合には、各ＮＭ（ｅＭＭＣ）は、自身が遅くなりそうなことが予測された時に、その旨を全てのＣＵ２０のＣＰＵ２１（例えば、全てのＣＵ２０上のアプリケーションプログラム１０１）に通知してもよい。各アプリケーションプログラム１０１は、このＮＭ（ｅＭＭＣ）を、遅くなりそうなストレージとして特定することができる。
【０１２３】
遅くなりそうなストレージは、各ＮＭ上の統計情報を学習することによって、予測可能である。上述したように、ジャイアントレイテンシの起こり易さは、アクセスパターンによって異なる。したがって、統計情報としては、アクセスパターン履歴を使用し得る。あるいは、各ＮＭ上のレイテンシ履歴を統計情報として学習してもよい。予測機能は、各ＮＭ上の統計情報（アクセスパターン履歴またはレイテンシ履歴の少なくとも一方）に基づいて、遅くなりそうなＮＭ（ｅＭＭＣ）を予測する。
【０１２４】
図１７では、ＮＭ＃４（ｅＭＭＣ＃４）が遅くなりそうなＮＭ（ｅＭＭＣ）として予測された場合が想定されている。
【０１２５】
（１）ＮＭ＃４（ｅＭＭＣ＃４）が遅くなりそうなＮＭ（ｅＭＭＣ）として予測された時、ＮＭ＃４（ｅＭＭＣ＃４）が遅くなりそうなＮＭ（ｅＭＭＣ）であることが、ＮＭ＃４またはドライバプログラム（ＣＵドライバ）１０３から、アプリケーションプログラム１０１に通知されてもよい。
【０１２６】
（２）アプリケーションプログラム１０１は、ＮＭ＃４（ｅＭＭＣ＃４）が遅くなりそうなＮＭ（ｅＭＭＣ）であることを示す通知を受信する。そして、アプリケーションプログラム１０１は、この通知に基づき、ＮＭ＃４（ｅＭＭＣ＃４）を遅くなりそうなストレージとして特定する。この場合、アプリケーションプログラム１０１は、ＮＭ＃４（ｅＭＭＣ＃４）に対するアクセス頻度が低下されるように、ＮＭ＃４（ｅＭＭＣ＃４）向けのデータＩ／Ｏ要求の数を減少させる。これにより、たとえＮＭ＃４（ｅＭＭＣ＃４）が、将来、実際に遅くなったとしても、キュー２００内に留まるＮＭ＃４（ｅＭＭＣ＃４）向けのコマンドの数を減らすことができる。
【０１２７】
したがって、たとえＮＭ＃４（ｅＭＭＣ＃４）が、将来、実際に遅くなったとしても、キュー２００が、遅いＮＭ＃４（ｅＭＭＣ＃４）向けのデータＩ／Ｏ要求で満杯になってしまい、他のＮＭ向けのデータＩ／Ｏ要求を受け取ることができなくなる、という事態の発生を未然に防止することが期待できる。
【０１２８】
なお、ＮＭ＃４（ｅＭＭＣ＃４）へのアクセス頻度が調整された期間においては、アプリケーションプログラム１０１は、ＮＭ＃４（ｅＭＭＣ＃４）に書き込むべき後続のデータを、退避用の予約領域に一時的に書き込み、後に、このデータを退避用の予約領域からＮＭ＃４（ｅＭＭＣ＃４）に戻してもよい。データは、遅いｅＭＭＣのアクセス速度が通常のアクセス速度に回復した後に、退避用の予約領域からオリジナルｅＭＭＣに戻してもよい。
【０１２９】
（３）アプリケーションプログラム１０１は、必要に応じて、ＮＭ＃４（ｅＭＭＣ＃４）に対して追加のバックグラウンド動作（ＢＫＯＰＳ）の開始を指示してもよい。通常、アプリケーションプログラム１０１は、ｅＭＭＣがバックグラウンド動作（ガベージコレクション）を開始するタイミングを認識することはできない。しかし、本実施形態では、遅くなりそうなｅＭＭＣが予測され、この遅くなりそうなｅＭＭＣをアプリケーションプログラム１０１に通知することができる。したがって、アプリケーションプログラム１０１は、この通知を利用することによって、各ｅＭＭＣのＧＣ開始タイミングを能動的に制御することが可能となる。通常、ＢＫＯＰＳは長い時間がかかるため、ＢＫＯＰＳの実行中は、アプリケーションプログラム１０１はアクセス頻度を調整（減少）することが必要となる。
【０１３０】
（４）もしＮＭ＃４（ｅＭＭＣ＃４）の予測されたステータスが変化したならば、ＮＭ＃４（ｅＭＭＣ＃４）の最新のステータスが、ＮＭ＃４またはドライバプログラム（ＣＵドライバ）１０３から、アプリケーションプログラム１０１に最新ステータスとして通知されてもよい。例えば、ＮＭ＃４（ｅＭＭＣ＃４）の最新ステータスは、ビジーであってもよい。換言すれば、ＮＭ＃４（ｅＭＭＣ＃４）が実際に遅くなった時に、ＮＭ＃４（ｅＭＭＣ＃４）がビジーであることが最新ステータスとしてアプリケーションプログラム１０１に通知される。この場合、アプリケーションプログラム１０１は、ＮＭ＃４（ｅＭＭＣ＃４）向けのデータＩ／Ｏ要求の発行を停止してもよい。
【０１３１】
もしＮＭ＃４（ｅＭＭＣ＃４）が実際に遅くなった場合には、ドライバプログラム（ＣＵドライバ）１０３は、ｅＭＭＣ＃４向けのデータＩ／Ｏ要求をキュー２００に留めた状態で、他のｅＭＭＣ向けのデータＩ／Ｏ要求それぞれをキュー２００から他のｅＭＭＣそれぞれに向けて送出する。
【０１３２】
図１８のフローチャートは、遅くなりそうなストレージが特定されたことに応答してストレージシステム１によって実行される処理の手順を示す。
【０１３３】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ３１）。
【０１３４】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ３２）。
【０１３５】
遅くなりそうなストレージ（遅くなりそうなｅＭＭＣ）３１が特定された時（ステップＳ３３のＹＥＳ）、ＣＰＵ２１は、アプリケーションプログラム１０１によって発行される、この遅くなりそうなｅＭＭＣ３１向けのデータＩ／Ｏ要求の数を減少させる（ステップＳ３４）。ステップＳ３４では、アプリケーションプログラム１０１は、遅くなりそうなｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行の数を減らし、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を通常通り継続する。これにより、このｅＭＭＣ３１が実際に遅くなる前に、このｅＭＭＣ３１向けのデータＩ／Ｏ要求の数を減少することができる。したがって、たとえこのｅＭＭＣ３１が実際に遅くなっても、キュー２００が、この遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求で満杯になることにより、他のｅＭＭＣ向けのコマンドを受信できなくなること、を未然に防ぐことができる。発行数が減少される対象のデータＩ／Ｏ要求の種類は、データ書き込み要求およびデータ読み出し要求の双方であってもよい。あるいは、データ書き込み要求の発行の数のみを減少してもよい。
【０１３６】
ステップＳ３４では、ＣＰＵ２１は、遅くなりそうなｅＭＭＣ３１に対してＢＫＯＰＳの開始を指示してもよい。
【０１３７】
図１９のフローチャートは、アプリケーションプログラム１０１によって実行されるデータＩ／Ｏ要求制御処理の手順を示す。
【０１３８】
遅くなりそうなｅＭＭＣが特定されるまでは、アプリケーションプログラム１０１は、アクセス対象の幾つかのｅＭＭＣ向けのデータ書き込み要求をそれぞれ発行するという通常のデータ書き込み要求発行処理を実行する（ステップＳ４１）。
【０１３９】
アクセス対象の幾つかのｅＭＭＣ内の一つのｅＭＭＣが、遅くなりそうなｅＭＭＣとして特定されたならば（ステップＳ４２のＹＥＳ）、アプリケーションプログラム１０１は、この遅くなりそうなｅＭＭＣ向けのデータ書き込み要求（ライトコマンド）の発行の数を減少し、且つこのｅＭＭＣに書き込むべき後続のデータを、このｅＭＭＣとは異なる退避用の予約領域に一時的に書き込む（ステップＳ４３）。ステップＳ４３では、アプリケーションプログラム１０１は、退避用の予約領域向けのデータ書き込み要求（ライトコマンド）を発行する。この退避用の予約領域向けのデータ書き込み要求は、キュー２００に入れられる。この退避用の予約領域向けのデータ書き込み要求は、送出可能なデータＩ／Ｏ要求であるので、キュー２００に長い間留まることはない。ステップＳ４３では、アプリケーションプログラム１０１は、さらに、データの書き込まれるべきアドレスとこのデータの退避先アドレスとの間の関係を示す退避情報を記録する。
【０１４０】
遅くなりそうなｅＭＭＣが実際に遅くなった後、このｅＭＭＣのアクセス速度はいずれ回復する。このように、このｅＭＭＣのアクセス速度が回復した時（ステップＳ４４のＹＥＳ）、アプリケーションプログラム１０１は、退避用の予約領域に書き込んだデータを、このｅＭＭＣの元の格納位置に戻す（ステップＳ４５）。ステップＳ４５では、アプリケーションプログラム１０１は、さらに、戻されたデータに対応する退避情報を削除する。
【０１４１】
図２０のフローチャートは、遅くなりそうなストレージの特定と遅いストレージの検出の双方に基づいてストレージシステム１によって実行される処理の手順を示す。
【０１４２】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ５１）。
【０１４３】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ５２）。
【０１４４】
遅くなりそうなストレージ（遅くなりそうなｅＭＭＣ）３１が特定された時（ステップＳ５３のＹＥＳ）、ＣＰＵ２１は、アプリケーションプログラム１０１によって発行される、この遅くなりそうなｅＭＭＣ３１向けのデータＩ／Ｏ要求の数を減少させる（ステップＳ５４）。ステップＳ５４では、アプリケーションプログラム１０１は、遅くなりそうなｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行の数を減らし、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を通常通り継続する。ステップＳ５４では、ＣＰＵ２１は、遅くなりそうなｅＭＭＣ３１に対してＢＫＯＰＳの開始を指示してもよい。
【０１４５】
ＣＰＵ２１が、遅くなりそうなｅＭＭＣ３１が実際に遅くなったことを検出した時（ステップＳ５５のＹＥＳ）、ＣＰＵ２１は、この遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求をキュー２００に留めた状態で、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求をキュー２００から他のｅＭＭＣ３１に向けて送出する。さらに、ＣＰＵ２１は、アプリケーションプログラム１０１による遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を停止する（ステップＳ５６）。ステップＳ５６では、アプリケーションプログラム１０１は、遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を停止し、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を継続する。ステップＳ５６では、ＣＰＵ２１は、遅いｅＭＭＣ３１に対してＢＫＯＰＳの開始を指示してもよい。
【０１４６】
この後、ＣＰＵ２１は、ジャイアントレイテンシコマンドが終了したか否か、つまり遅いｅＭＭＣ３１のアクセス速度が通常のアクセス速度に回復したか否かを判定する（ステップＳ５７）。このｅＭＭＣ３１のアクセス速度が回復したならば（ステップＳ５７のＹＥＳ）、ＣＰＵ２１は、アプリケーションプログラム１０１によるこのｅＭＭＣ３１向けのデータＩ／Ｏ要求の発行を再開する（ステップＳ５８）。
【０１４７】
なお、ステップＳ５４、Ｓ５６の各々においては、アプリケーションプログラム１０１は、遅くなりそうなｅＭＭＣ（または遅いｅＭＭＣ）に書き込むべき後続のデータを、退避用の予約領域に一時的に書き込んでも良い。
【０１４８】
そして、ステップＳ５８では、アプリケーションプログラム１０１は、予約領域に書き込んだデータ（退避データ）を、退避用の予約領域から読み出し、そしてこの退避データを、アクセス速度が回復したオリジナルのｅＭＭＣに書き込んでもよい。
【０１４９】
図２１は、ドライバプログラム（ＣＵドライバ）１０３またはＮＭ３０での対策を示す。
【０１５０】
（対策１，２，３）  キュー構造
対策１
対策１：ＣＵ上のキュー２００を、図２２に示されているように、ＣＰＵ２１内のＣＰＵコア（プロセッサコア）毎に用意する。図２２では、ＣＰＵ２１が４つのコア（コア＃１、コア＃２、コア＃３、コア＃４）を含む場合が想定されている。この場合、これら４つのコアに対応する４つのキュー２００−１〜２００−４が、各ＣＵ２０上のＲＡＭ（ＤＲＡＭ）２２に用意される。
【０１５１】
４つのコア（コア＃１、コア＃２、コア＃３、コア＃４）によって、４つのスレッド１１１（Ｔｈｒｅａｄ−１、Ｔｈｒｅａｄ−２、Ｔｈｒｅａｄ−３、Ｔｈｒｅａｄ−４）が同時に実行される。
【０１５２】
コア＃１上で実行されるＴｈｒｅａｄ−１は、ｅＭＭＣ＃１向けのデータＩ／Ｏ要求それぞれを発行する。このｅＭＭＣ＃１向けのデータＩ／Ｏ要求は、コア＃１に対応するキュー２００−１に入れられる。
【０１５３】
コア＃２上で実行されるＴｈｒｅａｄ−２は、ｅＭＭＣ＃２向けのデータＩ／Ｏ要求それぞれを発行する。このｅＭＭＣ＃２向けのデータＩ／Ｏ要求は、コア＃２に対応するキュー２００−２に入れられる。
【０１５４】
コア＃３上で実行されるＴｈｒｅａｄ−３は、ｅＭＭＣ＃３向けのデータＩ／Ｏ要求それぞれを発行する。このｅＭＭＣ＃３向けのデータＩ／Ｏ要求は、コア＃３に対応するキュー２００−３に入れられる。
【０１５５】
コア＃４上で実行されるＴｈｒｅａｄ−４は、ｅＭＭＣ＃４向けのデータＩ／Ｏ要求それぞれを発行する。このｅＭＭＣ＃４向けのデータＩ／Ｏ要求は、コア＃４に対応するキュー２００−４に入れられる。
【０１５６】
いま、ｅＭＭＣ＃１が遅いｅＭＭＣとなった場合を想定する。この場合、キュー２００−１が遅いｅＭＭＣ向けのデータＩ／Ｏ要求で満杯になる可能性がある。しかし、Ｔｈｒｅａｄ−２〜Ｔｈｒｅａｄ−４によって発行されるデータＩ／Ｏ要求は、Ｔｈｒｅａｄ−１によって発行される遅いｅＭＭＣ＃１向けのデータＩ／Ｏ要求に阻害されること無く、キュー２００−２〜キュー２００−４に入れられることができる。
【０１５７】
また、例えばＣＵ当たりのスレッドが８個の場合を考える。この時、一つのコアに複数のスレッドを割り当てる必要がる。ここで、遅いｅＭＭＣ向けのデータＩ／Ｏ要求を出すスレッドと同じコアに割り当てられたスレッドのデータＩ／Ｏ要求は、対応するキューに入れることができなくなるが、他のキューには他のスレッドのデータＩ／Ｏ要求を入れることができる。これにより、キューが１個の場合と比べると、並列度を高めることができる。
【０１５８】
対策２
対策２：十分に長いキュー２００を各ＣＵ２０上に用意する。
【０１５９】
例えば、無限長（無限デプス）のキュー２００を用意することにより、キュー２００が遅いｅＭＭＣ向けのデータＩ／Ｏ要求で満杯になることを防止することができる。実際には、無限長（無限デプス）のキュー２００を用意することは難しいので、典型的なアクセスパターンを考慮することによって、たとえあるｅＭＭＣが遅くなっても、この遅いｅＭＭＣ以外の他のｅＭＭＣ向けの十分な数のデータＩ／Ｏ要求を格納可能なキュー長（キューデプス）を決定すればよい。
【０１６０】
対策３
対策３：各ＣＵ２０上のキューを、図２３に示すように、ｅＭＭＣ毎に用意する。
【０１６１】
図２３では、Ｎ個のｅＭＭＣ（ｅＭＭＣ＃１、ｅＭＭＣ＃２、ｅＭＭＣ＃３、ｅＭＭＣ＃４、…ｅＭＭＣ＃Ｎ）に対応するＮ個のキュー（キュー２００−１、２００−２、２００−３、２００−４、…２００−Ｎ）が用意されている場合が想定されている。
【０１６２】
このように各ＣＵ２０上のキューをｅＭＭＣ毎に用意することにより、並列度を維持することができる。これには２つの理由がある。第１の理由は、いずれかのｅＭＭＣが遅くなった時に、他のｅＭＭＣ向けのデータＩ／Ｏ要求（コマンド）がキューイングでき且つ送出できるからである。第２の理由は、遅いｅＭＭＣのレイテンシが回復した時に、キューイングされている他のｅＭＭＣ向けのコマンドの数が少ないという状況がなくなるので、他のｅＭＭＣ向けのコマンドを即座に送出できるからである。
【０１６３】
キュー構造に関する上述の対策１、２、３は、任意に組み合わせることができる。
【０１６４】
対策４
対策４：図２４に示すように、上位レイヤに大サイズキューを用意する。
【０１６５】
図２４に示されているように、ドライバプログラム（ＣＵドライバ）１０３とアプリケーションプログラム１０１との間には、ＯＳ１０２によって管理される上位レイヤソフトウェアが存在する。アプリケーションプログラム１０１によって発行されるデータＩ／Ｏ要求それぞれは、この上位レイヤソフトウェアのキュー４００を介して、ドライバプログラム（ＣＵドライバ）１０３のキュー２００に入れられる。図２４では、上位レイヤソフトウェアの例として、仮想ファイルシステム（ＶＦＳ）５０１とブロックレイヤ５０２とが示されている。上位レイヤソフトウェアのキュー４００は、ブロックレイヤ５０２によって管理されるキューであってもよい。
【０１６６】
このキュー４００のサイズ（長さまたはデプスとも云う）は、アプリケーションプログラム１０１の制御によって可変設定可能である。したがって、アプリケーションプログラム１０１は、必要に応じて、キュー４００のサイズを大きくすることができる。例えば、アプリケーションプログラム１０１は、ドライバプログラム（ＣＵドライバ）１０３のキュー２００がほぼ満杯になりそうな時にキュー４００のサイズを大きくしてもよい。これにより、たとえドライバプログラム（ＣＵドライバ）１０３のキュー２００が遅いｅＭＭＣ向けのデータＩ／Ｏ要求で満杯になったとしても、アプリケーションプログラム１０１は他のｅＭＭＣ向けのデータＩ／Ｏ要求それぞれを発行でき、且つこのデータＩ／Ｏ要求それぞれをキュー４００にキューイングすることができる。
【０１６７】
一方、キュー２００に十分な空き領域が存在する時には、アプリケーションプログラム１０１は、キュー４００のサイズを小さくしてもよい。
【０１６８】
さらに、本実施形態では、送出のための条件を満たすデータＩ／Ｏ要求（コマンド）それぞれが大サイズのキュー４００から選択され、これら選択されたデータＩ／Ｏ要求（コマンド）のみがドライバプログラム（ＣＵドライバ）１０３のキュー２００に入れられる。
【０１６９】
例えば、あるｅＭＭＣが遅くなった場合には、この遅いｅＭＭＣ以外の他のｅＭＭＣ向けのデータＩ／Ｏ要求それぞれが大サイズのキュー４００から選択される。そして、選択されたデータＩ／Ｏ要求それぞれのみが、キュー４００からキュー２００に入れられる。
【０１７０】
これにより、キュー４００からキュー２００にキューイングされるデータＩ／Ｏ要求は、送出可能なデータＩ／Ｏ要求のみとなる。よって、キュー２００が送出不可能なデータＩ／Ｏ要求（遅いｅＭＭＣ向けのデータＩ／Ｏ要求）で満杯になるという状況を回避することが可能となる。
【０１７１】
また、ＣＵ２０が複数のＮＭ  Ｉ／Ｆ２３を有する場合（ここではＮＭ  Ｉ／Ｆ２３Ａ、２３Ｂとする）には、キュー２００にキューイングされたデータＩ／Ｏ要求は、これら２つのＮＭ  Ｉ／Ｆ２３Ａ、２３Ｂに対応する２つのグループに分けられ、その後に、ＮＭ  Ｉ／Ｆ２３Ａ、２３Ｂそれぞれを経由して送出されてもよい。
【０１７２】
なお、アプリケーションプログラム１０１から発行される一つのデータＩ／Ｏ要求によって指定されるデータサイズが大きい場合には、この大サイズデータＩ／Ｏ要求は、ドライバプログラム（ＣＵドライバ）１０３によって例えば複数の４ＫｉＢデータＩ／Ｏ要求に分割され、これら４ＫｉＢデータＩ／Ｏ要求がキュー２００に入れられてもよい。分割されるサイズは４ＫｉＢに限られない。
【０１７３】
図２５のフローチャートは、上位レイヤのキューに入れられたデータＩ／Ｏ要求から送出可能データＩ／Ｏ要求それぞれを選択する処理の手順を示す。
【０１７４】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１から発行されるデータＩ／Ｏ要求それぞれをブロックレイヤ５０２のキュー４００に入れる（ステップＳ６１）。ＣＰＵ２１は、キュー４００内のデータＩ／Ｏ要求から、送出のための条件を満たすデータＩ／Ｏ要求それぞれを選択する（ステップＳ６３）。
【０１７５】
例えば、あるｅＭＭＣにおいてジャイアントレイテンシが起きており、他のｅＭＭＣそれぞれのレイテンシがノーマルレイテンシである場合には、ＣＰＵ２１は、他のｅＭＭＣ向けのデータＩ／Ｏ要求のみを、送出条件を満たすデータＩ／Ｏ要求として選択する。
【０１７６】
ＣＰＵ２１は、選択したデータＩ／Ｏ要求それぞれを、ブロックレイヤ５０２のキュー４００から、ドライバプログラム（ＣＵドライバ）１０３のキュー２００に入れる（ステップＳ６３）。
【０１７７】
このように、大サイズのキュー４００にキューイングされた多数のデータＩ／Ｏ要求から、送出条件を満たすデータＩ／Ｏ要求を事前に選択することによって、送出条件を満たすデータＩ／Ｏ要求のみをキュー４００からキュー２００に入れることができる。キュー２００に入れられる全てのデータＩ／Ｏ要求は送出可能データＩ／Ｏ要求であるので、キュー２００が、送出不能なデータＩ／Ｏ要求で満杯になることを防ぐことができる。
【０１７８】
対策５
対策５：ＮＭへの要求を制御する。
【０１７９】
図２６は、対策５の概要を示す。この対策５は、ジャイアントレイテンシコマンドの終了直後に並列度をすぐに回復するために実行される。
【０１８０】
（１）各ＣＵ２０のＣＰＵ２１は、あるｅＭＭＣが遅くなったこと、つまりこのｅＭＭＣにおいてジャイアントレイテンシが起きたことを検出する。図２６では、ｅＭＭＣ＃２が遅くなった場合が想定されている。
【０１８１】
（２）ＣＰＵ２１は、ｅＭＭＣ＃２以外の他のｅＭＭＣ（ｅＭＭＣ＃１、ｅＭＭＣ＃３、またはｅＭＭＣ＃４）向けのコマンドをキュー２００から取り出して送出可能である。しかし、対策５の制御においては、ＣＰＵ２１は、キュー２００から取り出して他のｅＭＭＣへ送出するコマンドの数を減少する。
【０１８２】
（３）この結果、他のｅＭＭＣ向けの多くのコマンドがキュー２００に維持される。
【０１８３】
（４）他のｅＭＭＣ向けの十分な数のコマンドがキュー２００に維持できるので、遅いｅＭＭＣのレイテンシが回復した時に、並列度はすぐに回復する。
【０１８４】
図２７のフローチャートは、ＮＭへの要求を制御する処理の手順を示す。
【０１８５】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ７１）。
【０１８６】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ７２）。
【０１８７】
ＣＰＵ２１が、バックグラウンド動作の実行によってアクセス速度が遅くなっている遅いストレージ（遅いｅＭＭＣ）３１を検出した時（ステップＳ７３のＹＥＳ）、ＣＰＵ２１は、遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求をキュー２００に残したまま、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求をキュー２００から他のｅＭＭＣ３１に向けて送出する。この場合、ＣＰＵ２１は、キュー２００から取り出すべき他のｅＭＭＣ３１向けのデータＩ／Ｏ要求の数を減少させる（ステップＳ７４）。これにより、キュー２００に残る他のｅＭＭＣ３１向けのデータＩ／Ｏ要求の数を増やすことができる。
【０１８８】
キュー２００から取り出すべき他のｅＭＭＣ３１向けのデータＩ／Ｏ要求の数を減少させる処理は、ドライバプログラム（ＣＵドライバ）１０３によって実行することができる。
【０１８９】
この後、ＣＰＵ２１は、ジャイアントレイテンシコマンドが終了したか否か、つまり遅いｅＭＭＣ３１のアクセス速度が通常のアクセス速度に回復したか否かを判定する（ステップＳ７５）。このｅＭＭＣ３１のアクセス速度が回復したならば（ステップＳ７５のＹＥＳ）、ＣＰＵ２１は、キュー２００から取り出すべき他のｅＭＭＣ３１向けのデータＩ／Ｏ要求の数を元の数に増加させる（ステップＳ７６）。遅いｅＭＭＣ３１のレイテンシが回復した直後においては、遅かったｅＭＭＣ３１向けのデータＩ／Ｏ要求のみならず、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求もキュー２００に維持されている。したがって遅いｅＭＭＣ３１のレイテンシが回復した直後、並列度をすぐに回復することができる。
【０１９０】
対策６
対策６：アイドルｅＭＭＣのＢＫＯＰＳを開始する。
【０１９１】
図２８は、対策６の概要を示す。この対策６は、遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求でキュー２００が満杯状態になったことによってアイドル状態となる他のｅＭＭＣに、バックグラウンド動作（ガベージコレクション（ＧＣ））を実行させる。これにより、アイドルｅＭＭＣの次のＧＣタイミングまでの時間を確保することが期待できる。
【０１９２】
（１）各ＣＵ２０のＣＰＵ２１は、あるｅＭＭＣが遅くなったこと、つまりこのｅＭＭＣにおいてジャイアントレイテンシが起きたことを検出する。図２８では、ｅＭＭＣ＃２が遅くなった場合が想定されている。
【０１９３】
（２）キュー２００にｅＭＭＣ＃１、ｅＭＭＣ＃３、ｅＭＭＣ＃４向けのコマンドが無くなり、ｅＭＭＣ＃１、ｅＭＭＣ＃３、ｅＭＭＣ＃４がアイドル状態（アイドルｅＭＭＣ）となった場合、ＣＰＵ２１は、これらアイドルｅＭＭＣ（ｅＭＭＣ＃１、ｅＭＭＣ＃３、ｅＭＭＣ＃４）それぞれにバックグラウンド動作の開始を指示する。
【０１９４】
図２９のフローチャートは、アイドル状態となったストレージのバックグラウンド動作を開始する処理の手順を示す。
【０１９５】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ８１）。
【０１９６】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ８２）。
【０１９７】
ＣＰＵ２１が、バックグラウンド動作の実行によってアクセス速度が遅くなっている遅いストレージ（遅いｅＭＭＣ）３１を検出した時（ステップＳ８３のＹＥＳ）、ＣＰＵ２１は、遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求をキュー２００に残したまま、他のｅＭＭＣ３１向けのデータＩ／Ｏ要求をキュー２００から他のｅＭＭＣ３１に向けて送出する。
【０１９８】
そして、ＣＰＵ２１は、キュー２００が、遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求で満杯状態であるか否かを判定する（ステップＳ８４）。
【０１９９】
キュー２００が遅いｅＭＭＣ３１向けのデータＩ／Ｏ要求で満杯状態であるならば（ステップＳ８４のＹＥＳ）、このキュー２００の満杯状態によってアイドルとなる他の各ｅＭＭＣにバックグラウンド動作（ガベージコレクション）の実行を指示し、これによって他の各ｅＭＭＣのバックグラウンド動作を開始する（ステップＳ８５）。
【０２００】
次に、パート２：書き込みコマンドをジャイアントレイテンシにオーバーラップさせることによって性能向上を図る方法、について説明する。
【０２０１】
図３０は、ストレージシステムによって実行される第２のＩ／Ｏ管理（パート２）のコンセプトを示す。
【０２０２】
図３０では、ｅＭＭＣ＃２においてジャイアントレイテンシが起きた場合が想定されている。このジャイアントレイテンシの期間中においては、データをｅＭＭＣ＃２に書き込むことはできない。このため、通常使用時の性能は、ｅＭＭＣ＃２向けの後続のライトコマンドをこのジャイアントレイテンシにオーバーラップさせることによって、改善される。
【０２０３】
まず、アプリケーションプログラム１０１との連携によって処理オーバーラップ機能を実現する方法について説明する。
【０２０４】
図３１は、アプリケーションとの連携（＃１）の概要を示す。
【０２０５】
アプリケーションプログラム１０１は、遅くなった（または遅くなりそうな）ｅＭＭＣに書き込むべき後続のデータを、遅くなった（または遅くなりそうな）ｅＭＭＣ＃２とは異なる退避用の予約領域（別のアドレスエリア）に書き込む。そして、アプリケーションプログラム１０１は、後続の処理に進む。このアプリケーションとの連携（＃１）は、例えば、図１４および図１６で説明した処理によって実現することができる。この場合、アプリケーションプログラム１０１は、図１３で説明したＡＰＩ（ＮＭステータスの通知のためのインタフェース）と同じＡＰＩを使用することができる。
【０２０６】
アプリケーションプログラム１０１が遅くなった（または遅くなりそうな）を検出した時、アプリケーションプログラム１０１は、遅くなった（または遅くなりそうな）ｅＭＭＣ向けのデータ書き込み要求（ライトコマンド）の発行を停止し（またはライトコマンドの発行頻度の減少し）、且つ遅くなった（または遅くなりそうな）ｅＭＭＣに書き込むべき後続のデータを、遅くなった（または遅くなりそうな）とは異なる退避用の予約領域に一時的に書き込む。これによって、たとえ遅くなった（または遅くなりそうな）ｅＭＭＣ向けのデータ書き込み要求（ライトコマンド）の発行を停止（またはライトコマンドの発行頻度の減少）しても、遅くなった（または遅くなりそうな）向けの後続のライトコマンドの処理を効率良く実行することができる。
【０２０７】
図３２は、アプリケーションとの連携（＃２）の概要を示す。
【０２０８】
（１）ドライバプログラム（ＣＵドライバ）１０３は、キュー２００に入ってから一定時間を超えたデータＩ／Ｏ要求（コマンド）をタイムアウトエラーにし、このコマンドのタイムアウトエラーをアプリケーションプログラム１０１に通知する。例えば、ｅＭＭＣ＃３においてジャイアントレイテンシが起きた場合、ｅＭＭＣ＃３向けのコマンドは送出できなくなる。このため、キュー２００内のｅＭＭＣ＃３向けのコマンドは、タイムアウトエラーとなる。アプリケーションプログラム１０１は、このタイムアウトエラーを無視して、次の処理に進む。タイムアウトエラーになったコマンドはキュー２００から破棄することができる。
【０２０９】
（２）キュー２００内のｅＭＭＣ＃３向けのコマンドがタイムアウトエラーとなることによって、空き領域がキュー２００に確保される。したがって、アプリケーションプログラム１０１は、後続のコマンドをキュー２００に入れることができる。
【０２１０】
図３３のフローチャートは、キューに入ってから一定時間を超えたコマンドをタイムアウトエラーにする処理の手順を示す。
【０２１１】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ９１）。
【０２１２】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ９２）。
【０２１３】
ＣＰＵ２１は、キュー２００に入ってから一定時間を超えたデータＩ／Ｏ要求を検出する（ステップＳ９３）。キュー２００に入ってから一定時間を超えたデータＩ／Ｏ要求が検出されたならば（ステップＳ９３のＹＥＳ）、ＣＰＵ２１は、このデータＩ／Ｏ要求をタイムアウトエラーにし、このデータＩ／Ｏ要求のタイムアウトエラーをアプリケーションプログラム１０１に通知する（ステップＳ９４）。
【０２１４】
ＣＰＵ２１は、タイムアウトエラーになったデータＩ／Ｏ要求をキュー２００から破棄する（ステップＳ９５）。ステップＳ９３〜Ｓ９５の処理は、ドライバプログラム（ＣＵドライバ）１０３によって実行してもよい。
【０２１５】
このように、アプリケーションとの連携（＃２）では、一定時間を超えたデータＩ／Ｏ要求をタイムアウトエラーにして、継続するデータＩ／Ｏ要求を処理する。これが、ジャイアントレイテンシにオーバーラップさせることに相当する。また、以上に説明した動作から、次のことが理解されよう。アプリケーションとの連携（＃２）では、タイムアウトエラーを無視するため、アプリケーションプログラム１０１がデータＩ／Ｏ要求したデータを実際には活用しない場合に有効である。データＩ／Ｏ要求したデータを実際には活用しないアプリケーションプログラムとして、例えば、データＩ／Ｏ要求のテストプログラムなどが考えられる。
【０２１６】
次に、ドライバプログラム（ＣＵドライバ）１０３またはＮＭ３０によって処理オーバーラップ機能を実現する方法について説明する。
【０２１７】
図３４は、ドライバプログラム（ＣＵドライバ）１０３またはＮＭ３０によって採られる基本コンセプトを示す。なお、以降の説明では、ドライバプログラム（ＣＵドライバ）１０３が処理主体となる場合を示しているが、ＮＭ３０が処理主体となる場合でも、適宜読み替え可能である。
【０２１８】
図３４では、ｅＭＭＣ＃２においてジャイアントレイテンシが起きた場合が想定されている。
【０２１９】
（１）各ＣＵ２０のＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃２における通常よりもはるかに長いレイテンシ（ジャイアントレイテンシ）を検出する。
【０２２０】
（２）ＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃２向けの後続するライトコマンドそれぞれのデータ、つまりｅＭＭＣ＃２に書き込むべき後続のデータを、退避用の予約領域６０１に書き込む。これによって、遅いｅＭＭＣ＃２向けの後続のライトコマンドそれぞれの処理をこの遅いｅＭＭＣ＃２のジャイアントレイテンシにオーバーラップさせることができる。
【０２２１】
図３５のフローチャートは、遅いストレージに書き込むべき後続データを退避用の予約領域に書き込むための処理の手順を示す。
【０２２２】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ１０１）。
【０２２３】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ１０２）。
【０２２４】
ＣＰＵ２１が、バックグラウンド動作の実行によってアクセス速度が遅くなっている遅いストレージ（遅いｅＭＭＣ）３１を検出した時（ステップＳ１０３のＹＥＳ）、ＣＰＵ２１は、ｅＭＭＣ＃２向けの後続するデータ書き込み要求（ライトコマンド）それぞれのデータを退避用の予約領域６０１に書き込む（ステップＳ１０４）。これらライトコマンドは、ジャイアントレイテンシコマンドに後続するｅＭＭＣ＃２向けのライトコマンドである。ステップＳ１０４では、ドライバプログラム（ＣＵドライバ）１０３は、キュー２００からｅＭＭＣ＃２向けの後続のライトコマンドそれぞれを取り出す。そして、ドライバプログラム（ＣＵドライバ）１０３は、これらライトコマンドによって指定されるデータを退避用の予約領域６０１に書き込む。この場合、ドライバプログラム（ＣＵドライバ）１０３は、このデータを退避用の予約領域６０１に書き込むためのライトコマンドそれぞれを生成してもよい。
【０２２５】
この後、ＣＰＵ２１は、ジャイアントレイテンシコマンドが終了したか否か、つまり遅いｅＭＭＣ３１のアクセス速度が通常のアクセス速度に回復したか否かを判定する（ステップＳ１０５）。このｅＭＭＣ３１のアクセス速度が回復したならば（ステップＳ１０５のＹＥＳ）、ＣＰＵ２１（例えば、ＣＵドライバ）は、退避用の予約領域６０１に書き込んだデータを、オリジナルｅＭＭＣ３１に戻す（ステップＳ１０６）。
【０２２６】
次に、退避用の予約領域に関する幾つかのバリエーションについて説明する。
【０２２７】
バリエーション（１）：書き込み対象のストレージを２つのストレージ間でトグル
図３６は、書き込み対象のストレージを２つのストレージ間でトグルする動作の概要を示す。
【０２２８】
図３６では、データ記憶領域（ストレージアレイ）４０内の全てのｅＭＭＣは、各々が２つのｅＭＭＣを含む複数のグループ（複数のｅＭＭＣペア）に分類される。アプリケーションプログラム１０１は、一つのｅＭＭＣペアを一つのストレージとして認識する。つまり、ストレージアレイ４０の提供容量は、ストレージアレイ４０の実際の容量の半分となる。各ｅＭＭＣペアに対するデータ書き込みは次のように実行される。
【０２２９】
（１）各ＣＵ２０のＣＰＵ２１（例えば、ＣＵドライバ）は、まず、あるｅＭＭＣペア内の一方のｅＭＭＣにデータを書き込む。
【０２３０】
（２）一方のｅＭＭＣが遅くなったならば、ＣＰＵ２１（例えば、ＣＵドライバ）は、ライト対象ｅＭＭＣを切り換え、このｅＭＭＣペア内の他方のｅＭＭＣにデータを書き込む。そして、他方のｅＭＭＣが遅くなったならば、ＣＰＵ２１（例えば、ＣＵドライバ）は、ライト対象ｅＭＭＣを再び切り換え、このｅＭＭＣペア内の一方のｅＭＭＣにデータを書き込む。
【０２３１】
現在のライト対象ｅＭＭＣが遅くなる時には、前のライト対象ｅＭＭＣのＧＣが終了し且つ前のライト対象ｅＭＭＣのレイテンシが通常レイテンシに回復していることが期待できる。ノーマルレイテンシへの回復があまりに遅いならば、提供する容量を減少させ各グループのｅＭＭＣの数を３または４に増加させることができる。但し、通常スループットはそれぞれ１／２、１／３、または１／４になる。
【０２３２】
一つのｅＭＭＣペアを構成する２つのｅＭＭＣ（ここでは、ｅＭＭＣ＃１、ｅＭＭＣ＃２）は、同じ容量を有する。ｅＭＭＣ＃１およびｅＭＭＣ＃２の各々には、その容量に対応する論理アドレス範囲が割り当てられている。例えば、ｅＭＭＣ＃１およびｅＭＭＣ＃２の各々の容量が３２ＧＢであるならば、３２ＧＢに対応するＬＢＡ範囲（ＬＢＡ０〜ＬＢＡｎ）がｅＭＭＣ＃１およびｅＭＭＣ＃２の各々に割り当てられる。
【０２３３】
ビットマップ６０２は、最新データが書き込まれたｅＭＭＣを識別するための情報を保持する。このビットマップ６０２は、データ書き込み時にＣＵドライバによって作成される。ＣＵドライバは、このビットマップ６０２を参照することにより、正しいｅＭＭＣからデータを読み出すことができる。
【０２３４】
ビットマップ６０２は、３２ＧＢに対応するＬＢＡ範囲をある管理サイズ（例えば４ＫｉＢ）単位で区切ることによって得られる複数のアドレス範囲それぞれに対応するビットを格納する。各ビット（“０”または“１”）は、対応する４ＫｉＢアドレス範囲に書き込まれた最新データが、ｅＭＭＣ＃１またはｅＭＭＣ＃２のどちちらに存在するかを示す。例えば、ある４ＫｉＢアドレス範囲に対応するビット“０”は、この４ＫｉＢアドレス範囲に対応する最新データがｅＭＭＣ＃１に書き込まれていることを表す。一方、ある４ＫｉＢアドレス範囲に対応するビット“１”は、この４ＫｉＢアドレス範囲に対応する最新データがｅＭＭＣ＃２に書き込まれていることを表す。古いデータ（書き込まなかった方のｅＭＭＣの当該アドレス範囲のデータ）はＴｒｉｍコマンドによって無効化してもよい。
【０２３５】
図３７のタイミングチャートは、書き込み対象のストレージを２つのストレージ間でトグルする動作を示す。
【０２３６】
ここでは、ｅＭＭＣ＃３とｅＭＭＣ＃４とを含むｅＭＭＣペアへのデータ書き込み動作について説明する。
【０２３７】
（１）各ＣＵ２０のＣＰＵ２１（例えば、ＣＵドライバ）は、まず、このｅＭＭＣペアに書き込むべきデータを、ｅＭＭＣペア内のｅＭＭＣ＃３に書き込む。ＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃３における通常よりもはるかに長いレイテンシを検出する。この検出に応答して、ＣＰＵ２１（例えば、ＣＵドライバ）は、書き込み対象のストレージをｅＭＭＣ＃３からｅＭＭＣ＃４に切り換える。
【０２３８】
（２）そして、ＣＰＵ２１（例えば、ＣＵドライバ）は、このｅＭＭＣペアに書き込むべき後続のデータを、ｅＭＭＣ＃４に書き込む。ＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃４における通常よりもはるかに長いレイテンシを検出する。この検出に応答して、ＣＰＵ２１（例えば、ＣＵドライバ）は、書き込み対象のストレージをｅＭＭＣ＃４からｅＭＭＣ＃３に切り換える。
【０２３９】
（３）現在の書き込み対象ｅＭＭＣが遅くなった時、前の書き込み対象のｅＭＭＣのレイテンシはノーマルレイテンシに回復していることが期待できる。
【０２４０】
図３８のフローチャートは、書き込み対象のストレージを２つのストレージ間でトグルする処理の手順を示す。
【０２４１】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージペア（ｅＭＭＣペア）向けのデータ書き込み要求それぞれをキュー２００に入れる（ステップＳ１１１）。
【０２４２】
ＣＰＵ２１は、送出可能な各データ書き込み要求のデータを、対応するストレージペア（ｅＭＭＣペア）内の一方のｅＭＭＣに書き込む（ステップＳ１１２）。
【０２４３】
ＣＰＵ２１が一方のｅＭＭＣが遅くなったことを検出すると（ステップＳ１１３のＹＥＳ）、ＣＰＵ２１は、このｅＭＭＣペア向けの後続のデータ書き込み要求のデータを、このｅＭＭＣペアの他方のｅＭＭＣに書き込む（ステップＳ１１４）。
【０２４４】
ＣＰＵ２１が他方のｅＭＭＣが遅くなったことを検出すると（ステップＳ１１５のＹＥＳ）、ＣＰＵ２１は、このｅＭＭＣペア向けの後続のデータ書き込み要求のデータを、このｅＭＭＣペアの一方のｅＭＭＣに書き込む（ステップＳ１１６）。
【０２４５】
また、それぞれの書き込みのステップ（ステップＳ１１２、ステップＳ１１４、ステップＳ１１６）において、ビットマップ６０２の書き込んだアドレス範囲に対応する情報を、書き込み先のｅＭＭＣを示すように更新する。また、古いデータ（書き込まなかった方のｅＭＭＣの当該アドレス範囲のデータ）はＴｒｉｍコマンドによって無効化してもよい。
【０２４６】
また、バリエーション（１）では、あるｅＭＭＣに対して同容量の退避先ｅＭＭＣをペアとして確保されているため、退避先ｅＭＭＣの容量が枯渇する恐れはない。したがって、図３５のステップＳ１０６のように、データを書き戻す処理は不要である。
【０２４７】
バリエーション（２）：データを退避用の専用のストレージに書き込む
図３９は、遅いストレージに書き込むべきデータを退避用の専用のストレージに書き込む動作の概要を示す。
【０２４８】
図３９では、複数のｅＭＭＣに一つの割合で、退避用の専用のｅＭＭＣ（予約ｅＭＭＣ）が用意される。ｅＭＭＣ＃１〜ｅＭＭＣ＃５は通常のｅＭＭＣとして使用され、ｅＭＭＣ＃６は、退避用の専用のｅＭＭＣ（予約ｅＭＭＣ）として使用される。このケースでは、通常のスループットは５／６となる。データ書き込みは次のように実行される。以下では、ｅＭＭＣ＃３が遅くなっている場合を想定する。
【０２４９】
（１）各ＣＵ２０のＣＰＵ２１（例えば、ＣＵドライバ）は、遅いｅＭＭＣ＃３向けのデータ書き込み要求のデータを、退避用の予約ｅＭＭＣ＃６に書き込む。この場合、ＣＰＵ２１（例えば、ＣＵドライバ）は、遅いｅＭＭＣ＃３向けのデータ書き込み要求のデータが予約ｅＭＭＣ＃６にシーケンシャルライトされるように、アドレス変換を行っても良い。例えば、遅いｅＭＭＣ＃３に書き込まれるべきデータのＬＢＡ（例えば＝０ｘｅ０）は、予約ｅＭＭＣ＃６の先頭ＬＢＡ（例えば＝０ｘ００）に変換される。そして、遅いｅＭＭＣ＃３に書き込まれるべき次のデータのＬＢＡ（例えば＝０ｘ８ｆ）は、予約ｅＭＭＣ＃６の次のＬＢＡ（例えば＝０ｘ０１）に変換される。これにより、予約ｅＭＭＣ＃６には、概ねシーケンシャルライトによってデータが書き込まれる。この結果、予約ｅＭＭＣ＃６においてはジャイアントレイテンシが起こり難くなるので、予約ｅＭＭＣ＃６は、ノーマルレイテンシを長い間維持することができる。
【０２５０】
そして、ＣＰＵ２１（例えば、ＣＵドライバ）は、データの書き込まれるべきｅＭＭＣとアドレスとこのデータの退避先アドレスとの間の関係を示す退避情報をログとして記録する。もしリードコマンドによって指定されるデータが予約ｅＭＭＣ＃６に格納されていることが退避情報から判定されたならば、このデータは予約ｅＭＭＣ＃６から読み出される。
【０２５１】
（２）ｅＭＭＣ＃３においてジャイアントレイテンシコマンドが終了した時、ＣＰＵ２１（例えば、ＣＵドライバ）は、退避データを予約ｅＭＭＣ＃６から読み出して元の格納位置に書き込む（データ移動）。ＣＰＵ２１（例えば、ＣＵドライバ）は、対応する退避情報を削除し、予約ｅＭＭＣ＃６内の退避データをｔｒｉｍコマンドによって無効化する。なお、アプリケーションプログラム１０１は、ｅＭＭＣ＃３への通常アクセスと書き戻し（データ移動）とが同時に発生するのを避けるために、データ移動のタイミングについてのヒントをＣＵドライバに提供してもよい。あるいは、アプリケーションプログラム１０１が、自ら、予約ｅＭＭＣ＃６への退避と元の格納位置へのデータ移動とを制御してもよい。
【０２５２】
図４０のタイミングチャートは、遅いストレージに書き込むべきデータを退避用の専用のストレージに一時的に書き込み、後に、データをオリジナルのストレージに戻す動作を示す。
【０２５３】
（１）各ＣＵ２０のＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃３における通常よりもはるかに長いレイテンシを検出する。
【０２５４】
（２）ＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃３向けの後続するライトコマンドそれぞれのデータが書き込まれるべきｅＭＭＣを、退避用の予約ｅＭＭＣ＃６に切り換える。そして、ＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃３に書き込むべき後続のデータを、予約ｅＭＭＣ＃６に書き込む。これにより、これによって、遅いｅＭＭＣ＃３向けの後続のライトコマンドそれぞれの処理をこの遅いｅＭＭＣ＃３のジャイアントレイテンシにオーバーラップさせることができる。
【０２５５】
（３）（４）ｅＭＭＣ＃３においてジャイアントレイテンシコマンドが終了した時、ＣＰＵ２１（例えば、ＣＵドライバ）は、予約ｅＭＭＣ＃６から退避データを読み出し、読み出した退避データをオリジナルｅＭＭＣ（ｅＭＭＣ＃３）の元の格納位置に書き込む。オリジナルｅＭＭＣへの通常のリード／ライトが存在するならば、これらアクセスと退避データ移動は時分割されて並列に実行される。
【０２５６】
図４１のフローチャートは、遅いストレージに書き込むべきデータを退避用の専用のストレージに一時的に書き込み、後に、データをオリジナルのストレージに戻す処理の手順を示す。
【０２５７】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ１２１）。
【０２５８】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ１２２）。
【０２５９】
ＣＰＵ２１が、バックグラウンド動作の実行によってアクセス速度が遅くなっている遅いストレージ（遅いｅＭＭＣ）３１を検出した時（ステップＳ１２３のＹＥＳ）、ＣＰＵ２１は、遅いｅＭＭＣ向けの後続するデータ書き込み要求（ライトコマンド）それぞれのデータを退避用の専用ｅＭＭＣ（予約ｅＭＭＣ）にシーケンシャルに書き込む（ステップＳ１２４）。ステップＳ１２４では、ドライバプログラム（ＣＵドライバ）１０３は、キュー２００から遅いｅＭＭＣ向けのライトコマンドそれぞれを取り出し、これらライトコマンドによって指定されるデータを予約ｅＭＭＣに書き込んでもよい。この場合、ドライバプログラム（ＣＵドライバ）１０３は、データを予約ｅＭＭＣにシーケンシャルに書き込むためのライトコマンドそれぞれを生成し、これらライトコマンドを予約ｅＭＭＣに送出してもよい。そして、ドライバプログラム（ＣＵドライバ）１０３は、退避情報を記録する（ステップＳ１２５）。
【０２６０】
遅いｅＭＭＣのアクセス速度が回復した時（ステップＳ１２６のＹＥＳ）、ＣＰＵ２１は、退避情報を参照することによって退避データをオリジナルｅＭＭＣの元の格納位置に戻し、退避情報を削除し、そして予約ｅＭＭＣ内の退避データを無効化する（ステップＳ１２７）。ステップＳ１２７の処理も、ドライバプログラム（ＣＵドライバ）１０３によって実行することができる。
【０２６１】
バリエーション（３）：データをあるＮＭ３０内のＲＡＭ（ＤＲＡＭ）３１２に書き込む
図４２は、遅いストレージに書き込むべきデータを、あるＮＭ内のＲＡＭ（ＤＲＡＭ）に書き込む動作の概要を示す。
【０２６２】
バリエーション（３）の基本的な考え方は、バリエーション（２）と同じである。
【０２６３】
バリエーション（３）の長所は、次の３点である。
【０２６４】
・通常スループットを維持できる。
【０２６５】
・提供容量を維持できる。
【０２６６】
・ジャイアントレイテンシは予約エリア（ＤＲＡＭ）においては決して起こらないので、ある期間内でのデータ退避の完了を保証できる。
【０２６７】
バリエーション（３）の短所としては、以下の２点が考えられる。
【０２６８】
・ＤＲＡＭの限られた容量．退避のためのＤＲＡＭの容量は退避用ｅＭＭＣよりも少ない。
【０２６９】
・予期しない電源断が生じた時にＤＲＡＭ上のデータは失われる。
【０２７０】
退避のためのＤＲＡＭは、基本的には、どのＮＭ内のＤＲＡＭであってもよい。退避のためのＤＲＡＭの典型的な例としては、遅いｅＭＭＣを含むＮＭ内のＤＲＡＭが挙げられる。この場合、データが書き込まれるべきｅＭＭＣを含むＮＭ内にこのデータが退避データとして書き込まれるので、退避データの管理が容易となる。
【０２７１】
例えば、ｅＭＭＣ＃３が遅くなっている場合、ｅＭＭＣ＃３向けの後続するライトコマンドのデータは、ｅＭＭＣ＃３を含むＮＭ内のＤＲＡＭに書き込まれる。
【０２７２】
図４３のフローチャートは、遅いストレージに書き込むべきデータをＮＭ内のＤＲＡＭに一時的に書き込み、後に、データをオリジナルのストレージに戻す処理の手順を示す。
【０２７３】
以下では、ＮＭのＮＣ内のＣＰＵ３１１が、データの退避、および元の格納位置へのデータ移動を制御する場合を想定する。
【０２７４】
ＮＭのＣＰＵ３１１は、このＮＭ宛てのデータ書き込み要求を受信する（ステップＳ１３１）。ＣＰＵ３１１は、このＮＭ内のｅＭＭＣが遅くなっているか否かを判定する（ステップＳ１３２）。このＮＭ内のｅＭＭＣが遅くなっていないならば（ステップＳ１３２のＮＯ）、ＣＰＵ３１１は、データ書き込み要求によって指定されるデータをこのＮＭ内のｅＭＭＣに書き込む（ステップＳ１３２）。
【０２７５】
一方、このＮＭ内のｅＭＭＣが遅くなっているならば（ステップＳ１３２のＹＥＳ）、ＣＰＵ３１１は、データ書き込み要求によって指定されるデータをこのＮＭ内のＤＲＡＭ３１２に書き込む（ステップＳ１３４）。そして、このＮＭ内のｅＭＭＣのアクセス速度が回復した時（ステップＳ１３５のＹＥＳ）、ＣＰＵ３１１は、退避データを、このＮＭ内のＤＲＡＭからこのＮＭ内のｅＭＭＣの元の格納位置に戻す（ステップＳ１３６）。
【０２７６】
バリエーション（４）：各ｅＭＭＣに退避用の予約領域を確保
図４４は、遅いストレージに書き込むべきデータを他のストレージ内の退避用の予約領域に書き込む動作の概要を示す。
【０２７７】
図４４では、ｅＭＭＣ＃１、ｅＭＭＣ＃２、ｅＭＭＣ＃３、ｅＭＭＣ＃４、ｅＭＭＣ＃５、ｅＭＭＣ＃６の各々は、通常書き込み領域３１Ａと、退避用の予約領域３１Ｂとを含む。つまり、各ｅＭＭＣの記憶領域の一部が、退避用の予約領域として使用される。このケースでは、ｅＭＭＣ＃１〜ｅＭＭＣ＃６の全てが通常のリード／ライトアクセスのために利用可能であるため、通常のスループットは最大（６／６）に維持される。
【０２７８】
データ書き込みは次のように実行される。以下では、ｅＭＭＣ＃３が遅くなっている場合を想定する。
【０２７９】
（１）各ＣＵ２０のＣＰＵ２１（例えば、ＣＵドライバ）は、遅いｅＭＭＣ＃３向けのデータ書き込み要求のデータを、他の（遅くない）ｅＭＭＣの予約領域に書き込む。図４４では、このデータがｅＭＭＣ＃５の退避用の予約領域３１Ｂに書き込まれる場合が例示されている。ジャイアントレイテンシが発生した時、退避先のｅＭＭＣ（ここではｅＭＭＣ＃５）は、ｅＭＭＣ＃５向けの通常のリード／ライトとデータ退避のためのライトとの双方を処理するので、退避先のｅＭＭＣは通常使用時の２倍の時間を要する。全てのｅＭＭＣが同じ期間に遅くなったならば意味がないが、通常、複数のｅＭＭＣが同じ期間に遅くなる確率は低い。そして、ＣＰＵ２１（例えば、ＣＵドライバ）は、データが書き込まれるべき元の格納位置のｅＭＭＣとアドレスとこのデータの退避先のｅＭＭＣとアドレスとの間の関係を示す退避情報（不図示）をログとして記録する。
【０２８０】
（２）ｅＭＭＣ＃３においてジャイアントレイテンシコマンドが終了した時、ＣＰＵ２１（例えば、ＣＵドライバ）は、退避データをｅＭＭＣ＃５の予約領域３１Ｂから読み出して元の格納位置に書き込む（データ移動）。ＣＰＵ２１（例えば、ＣＵドライバ）は、対応する退避情報を削除し、ｅＭＭＣ＃５の予約領域３１Ｂ内の退避データをｔｒｉｍコマンドによって無効化する。
【０２８１】
図４５のタイミングチャートは、遅いストレージに書き込むべきデータを他のストレージ内の退避用の予約領域に一時的に書き込み、後に、データをオリジナルのストレージに戻す動作を示す。
【０２８２】
（１）各ＣＵ２０のＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃３における通常よりもはるかに長いレイテンシ（ジャイアントレイテンシ）を検出する。
【０２８３】
（２）ＣＰＵ２１（例えば、ＣＵドライバ）は、ｅＭＭＣ＃３向けの後続するライトコマンドそれぞれのデータを、他のｅＭＭＣ内の予約領域に書き込む。図４５では、ｅＭＭＣ＃３向けの後続するライトコマンドのデータが、ｅＭＭＣ＃２内の予約領域、ｅＭＭＣ＃４内の予約領域、ｅＭＭＣ＃６内の予約領域、ｅＭＭＣ＃５内の予約領域、およびｅＭＭＣ＃１内の予約領域、という順番で分散された場合が例示されている。あるいは、ｅＭＭＣ＃３向けのこれら後続するライトコマンドのデータは、ｅＭＭＣ＃３以外の単一ｅＭＭＣの予約領域にシーケンシャルに書き込まれてもよい。
【０２８４】
（３）（４）ｅＭＭＣ＃３においてジャイアントレイテンシコマンドが終了した時、ＣＰＵ２１（例えば、ＣＵドライバ）は、退避データを他のｅＭＭＣの予約領域から読み出し、読み出した退避データをオリジナルｅＭＭＣ（ｅＭＭＣ＃３）の通常書き込み領域内の元の格納位置に書き込む。オリジナルｅＭＭＣへの通常のリード／ライトが存在するならば、これらアクセスと退避データ移動は時分割で並列に実行される。
【０２８５】
図４６のフローチャートは、遅いストレージに書き込むべきデータを他のストレージ内の退避用の予約領域に一時的に書き込み、後に、データをオリジナルのストレージに戻す処理の手順を示す。
【０２８６】
各ＣＵ２０のＣＰＵ２１は、アプリケーションプログラム１０１を実行する。そして、ＣＰＵ２１は、アプリケーションプログラム１０１から発行される複数のストレージ（ｅＭＭＣ）３１向けのデータＩ／Ｏ要求それぞれをキュー２００に入れる（ステップＳ１４１）。
【０２８７】
ＣＰＵ２１は、キュー２００内の送出可能なデータＩ／Ｏ要求それぞれを、これら送出可能なデータＩ／Ｏ要求に対応するストレージ（ｅＭＭＣ）３１それぞれに向けて送出する（ステップＳ１４２）。
【０２８８】
ＣＰＵ２１が、バックグラウンド動作の実行によってアクセス速度が遅くなっている遅いストレージ（遅いｅＭＭＣ）３１を検出した時（ステップＳ１４３のＹＥＳ）、ＣＰＵ２１は、遅いｅＭＭＣ向けの後続するデータ書き込み要求（ライトコマンド）それぞれのデータを他のｅＭＭＣの予約領域に書き込む（ステップＳ１４４）。ステップＳ１４４では、ドライバプログラム（ＣＵドライバ）１０３は、キュー２００から遅いｅＭＭＣ向けのライトコマンドを取り出し、このライトコマンドによって指定されるデータを他のｅＭＭＣの予約領域に書き込んでもよい。この場合、ドライバプログラム（ＣＵドライバ）１０３は、データを他のｅＭＭＣの予約領域にシーケンシャルに書き込むためのＬＢＡを含むライトコマンドを生成し、このライトコマンドを他のｅＭＭＣに送出してもよい。なお、遅いｅＭＭＣ向けの後続するライトコマンドそれぞれのデータは、遅いｅＭＭＣ以外の他の幾つかのｅＭＭＣの予約領域に分散されてもよい。
【０２８９】
そして、ドライバプログラム（ＣＵドライバ）１０３は、退避情報を記録する（ステップＳ１４５）。
【０２９０】
遅いｅＭＭＣのアクセス速度が回復した時（ステップＳ１４６のＹＥＳ）、ＣＰＵ２１は、退避情報を参照することによって退避データをオリジナルｅＭＭＣの通常書き込み領域の元の格納位置に戻し、退避情報を削除し、そして他のｅＭＭＣの予約領域内の退避データを無効化する（ステップＳ１４７）。ステップＳ１４７の処理も、ドライバプログラム（ＣＵドライバ）１０３によって実行することができる。
【０２９１】
他の対策：
次に、できるだけジャイアントレイテンシの発生を防止するための対策について説明する。
【０２９２】
上述したように、シーケンシャルライトの時にはジャイアントレイテンシが起こり難いので、各ｅＭＭＣへのアクセスパターンがシーケンシャルライトになるようにアプリケーションプログラム１０１の実行条件を制限してもよい。
【０２９３】
もし複数のスレッドが同じｅＭＭＣにデータを書き込んだならば、たとえ各スレッドがシーケンシャルにライトしても、このｅＭＭＣへの組み合わされたアクセスパターンはシーケンシャルライトにならない。したがって、例えば、一つのスレッドがシーケンシャルにライトし、この一つのスレッドのみが特定のｅＭＭＣに書き込むことができるようにアプリケーションプログラム１０１の実行条件を制限してもよい。
【０２９４】
また、上述したように、ストレージの容量に対するランダムライト範囲の比率（パーセント）が大きくなるほど、ジャイアントレイテンシが起こり易い。したがって、例えば、６４ＧＢ  ｅＭＭＣ内の３２ＧＢ範囲のみを利用可能ユーザエリアとして使用するようにしてもよい。
【０２９５】
以上説明したように、本実施形態のパート１で説明した機能によれば、遅いストレージが検出された場合に、アプリケーションプログラム１０１によるこの遅いストレージ向けのデータＩ／Ｏ要求の発行が停止される。これにより、キュー２００が遅いストレージ向けのデータＩ／Ｏ要求で満杯になることを防止できる。したがって、たとえあるストレージが遅くなっても、他の（遅くない）ストレージ向けのデータＩ／Ｏ要求をキュー２００に入れることができるので、あるストレージが遅くなっている期間においても、遅くないストレージそれぞれを効率良くアクセスすることができる。よって、あるストレージが遅くなることに起因して他の（遅くない）ストレージへのアクセスも遅くなるという事態の発生を防止することができ、ストレージシステム１の性能低下を最小限に留めることができる。
【０２９６】
また、遅くなりそうなストレージを予測する機能によれば、あるストレージのアクセス速度が実際に遅くなる前にこのストレージ向けのデータＩ／Ｏ要求の数が減少される。したがって、たとえこのストレージのアクセス速度が実際に遅くなっても、キュー２００が遅いストレージ向けのデータＩ／Ｏ要求ですぐに満杯になることを防止できることが期待できる。
【０２９７】
さらに、アプリケーションプログラム１０１との連携によって、遅いストレージまたは遅くなりそうなストレージに書き込まれるべきデータを、退避用の予約領域に書き込むことができる。
【０２９８】
また、本実施形態のパート２で説明した機能によれば、書き込みコマンドをジャイアントレイテンシにオーバーラップさせることができるので、ストレージシステム１の性能向上を図ることができる。
【０２９９】
なお、本実施形態で説明した個々の機能は単独で使用されてもよいし、他の一つ以上の任意の機能と組み合わせて使用されてもよい。
【０３００】
また、本実施形態では、複数のＣＰＵ２１と複数のストレージ３１とを含むシステム構成を説明したが、本実施形態で説明した個々の機能は、１つの以上のＣＰＵ２１と複数のストレージ３１とを含むシステム構成にも適用可能である。
【０３０１】
本発明のいくつかの実施形態を説明したが、これらの実施形態は、例として提示したものであり、発明の範囲を限定することは意図していない。これら新規な実施形態は、その他の様々な形態で実施されることが可能であり、発明の要旨を逸脱しない範囲で、種々の省略、置き換え、変更を行うことができる。これら実施形態やその変形は、発明の範囲や要旨に含まれるとともに、特許請求の範囲に記載された発明とその均等の範囲に含まれる。
【符号の説明】
【０３０２】
１…ストレージシステム、２０…コネクションユニット（ＣＵ）、２１…ＣＰＵ、３０…ノードモジュール（ＮＭ）、３１…ストレージ（ｅＭＭＣ）、３２…ノードコントローラ（ＮＣ）、１０１…アプリケーションプログラム、１０３…ドライバプログラム（ＣＵドライバ）、２００…キュー。
【図１】
2018041162.tif 000003
【図２】
2018041162.tif 000004
【図３】
2018041162.tif 000005
【図４】
2018041162.tif 000006
【図５】
2018041162.tif 000007
【図６】
2018041162.tif 000008
【図７】
2018041162.tif 000009
【図８】
2018041162.tif 000010
【図９】
2018041162.tif 000011
【図１０】
2018041162.tif 000012
【図１１】
2018041162.tif 000013
【図１２】
2018041162.tif 000014
【図１３】
2018041162.tif 000015
【図１４】
2018041162.tif 000016
【図１５】
2018041162.tif 000017
【図１６】
2018041162.tif 000018
【図１７】
2018041162.tif 000019
【図１８】
2018041162.tif 000020
【図１９】
2018041162.tif 000021
【図２０】
2018041162.tif 000022
【図２１】
2018041162.tif 000023
【図２２】
2018041162.tif 000024
【図２３】
2018041162.tif 000025
【図２４】
2018041162.tif 000026
【図２５】
2018041162.tif 000027
【図２６】
2018041162.tif 000028
【図２７】
2018041162.tif 000029
【図２８】
2018041162.tif 000030
【図２９】
2018041162.tif 000031
【図３０】
2018041162.tif 000032
【図３１】
2018041162.tif 000033
【図３２】
2018041162.tif 000034
【図３３】
2018041162.tif 000035
【図３４】
2018041162.tif 000036
【図３５】
2018041162.tif 000037
【図３６】
2018041162.tif 000038
【図３７】
2018041162.tif 000039
【図３８】
2018041162.tif 000040
【図３９】
2018041162.tif 000041
【図４０】
2018041162.tif 000042
【図４１】
2018041162.tif 000043
【図４２】
2018041162.tif 000044
【図４３】
2018041162.tif 000045
【図４４】
2018041162.tif 000046
【図４５】
2018041162.tif 000047
【図４６】
2018041162.tif 000048