(57)【要約】【課題】データストレージシステムの冗長データの割り当て及びレイアウトのための技法を提供する。【解決手段】データストレージシステム（１００）は、データのＭ個の複製を記憶する。システム（１００）に割り当てられるデータの要件に対応するのに利用可能な十分な資源を有するノード（１０２）が特定される。ノード（１０２）の個数がＭよりも多い場合、特定されたノードの中からランダムに選択されたＭ個のノード（１０２）にデータが割り当てられる。割り当てられるデータは、データセグメントのグループを含むことができ、ノード（１０２）の個数がＭ未満である場合に、そのグループは分割されて、削減された要件を有するデータセグメントのグループが形成される。次に、削減された要件に対応するのに利用可能な十分な資源を有するノード（１０２）が特定される。【選択図】図１
2007520783.tif 000002
【特許請求の範囲】
【請求項１】
データストレージシステム（１００）のストレージデバイスノード（１０２）にデータを割り当てる方法であって、前記データストレージシステム（１００）は、前記データのＭ個の複製を記憶し、
該方法は、
前記データの要件に対応するのに利用可能な十分な資源を有するノード（１０２）を特定することと、
ノード（１０２）の個数がＭよりも大きい場合に、特定したノードの中から、ランダムに選択したＭ個のノード（１０２）に前記データを割り当てることと
を含む方法。
【請求項２】
割り当てられる前記データはデータセグメントのグループを含み、ノード（１０２）の個数がＭ未満である場合、前記データセグメントのグループを分割し、それによって、削減された要件を有するデータセグメントのグループを形成することと、前記削減された要件に対応するのに利用可能な十分な資源を有するノード（１０２）を特定することとをさらに含む
請求項１に記載の方法。
【請求項３】
少なくともＭ個のノード（１０２）が特定されるまで、前記データセグメントのグループを前記分割することと、
利用可能な十分な資源を有するノード（１０２）を前記特定することを繰り返すことと
をさらに含む
請求項２に記載の方法。
【請求項４】
ノード（１０２）の利用可能な容量が、少なくとも、前記データの容量要件と同程度の大きさである場合にのみ、該ノード（１０２）は、前記データの十分な資源を有するものとして特定される
請求項３に記載の方法。
【請求項５】
ノード（１０２）の利用可能な性能パラメータが、少なくとも、前記データの対応する性能要件と同程度の大きさである場合にのみ、該ノード（１０２）は、前記データの十分な資源を有するものとして特定される
請求項４に記載の方法。
【請求項６】
エントリをデータロケーションテーブルに追加することをさらに含み、
該エントリは、前記データと、前記データが割り当てられる前記Ｍ個のノード（１０２）とを特定する
請求項１に記載の方法。
【請求項７】
前記データストレージシステム（１００）に新しいストレージデバイスノード（１０２）を追加することであって、既存のノード（１０２）のうちの他のノードと比較して重い負荷を有する或る既存のノード（１０２）を特定することと、前記特定した既存のノード（１０２）に記憶されたデータを新しいノードに移動させることとを含む追加することと、
前記新しいノード（１０２）が前記既存のノード（１０２）と比較して十分な負荷を有するかどうかを判断して、前記新しいノード（１０２）が十分な負荷を有しない場合に、前記新しいノード（１０２）が十分な負荷を有するまで、前記特定すること及び前記移動させることを繰り返すことと
をさらに含む
請求項１に記載の方法。
【請求項８】
前記データストレージシステム（１００）のストレージデバイスノード（１０２）からデータを除去することであって、
データが除去されるストレージデバイスノード（１０２）からデータを選択することと、
前記データの要件に対応するのに利用可能な十分な資源を有する、前記データストレージシステム（１００）の他のノード（１０２）を特定することと、
特定した他のノードの中からランダムに選択されたノード（１０２）に前記データを移動させることと、
除去される前記ストレージデバイスノード（１０２）が空になるまで、前記選択することと、前記特定することと、前記移動させることとを繰り返すことと
を含む除去すること
をさらに含む
請求項１に記載の方法。
【請求項９】
冗長データを記憶するための複数の既存のストレージデバイスノード（１０２）を有するデータストレージシステム（１００）に新しいストレージデバイスノード（１０２）を追加するための方法であって、
前記既存のノード（１０２）のうちの他のノードと比較して重い負荷を有する或る既存のノード（１０２）を特定するステップと、
前記特定した既存のノード（１０２）に記憶されたデータを前記新しいノード（１０２）へ移動させるステップと、
前記新しいノード（１０２）が前記既存のノード（１０２）と比較して十分な負荷を有するかどうかを判断し、前記新しいノード（１０２）が十分な負荷を有しない場合に、前記新しいノード（１０２）が十分な負荷を有するまで、前記特定するステップ及び前記移動させるステップを繰り返すステップと
を含む方法。
【請求項１０】
冗長データを記憶するためのデータストレージシステム（１００）のストレージデバイスノード（１０２）からデータを除去するための方法であって、該データストレージシステム（１００）は複数のストレージデバイスノードを有し、
該方法は、
データが除去される前記ストレージデバイスノード（１０２）からデータを選択するステップと、
前記データの要件に対応するのに利用可能な十分な資源を有する、前記データストレージシステム（１００）の他のノード（１０２）を特定するステップと、
特定した他のノードの中からランダムに選択されたノード（１０２）に前記データを移動させるステップと、
除去される前記ストレージデバイスノード（１０２）が空になるまで、前記選択するステップと、前記特定するステップと、前記移動させるステップとを繰り返すステップと、
を含む方法。
【発明の詳細な説明】
【技術分野】
【０００１】
［発明の分野］
本発明は、データストレージの分野に関し、より詳細には、フォールトトレラントデータ複製に関する。
【０００２】
本出願は、（本出願と同日に）出願された米国特許出願第（代理人整理番号２００３１０７４２−１及び２００３１０１４３−１）号に関係する。これらの米国特許出願の内容は参照により本明細書に援用される。
【背景技術】
【０００３】
［発明の背景］
企業クラスのデータストレージシステムは、主として、データストレージシステムの信頼性の要件において、民生クラスのストレージシステムと異なる。例えば、企業クラスのストレージシステムに共通に望まれる特徴は、ストレージシステムが、全面的な惨事に達しない状況ではデータを喪失すべきでもないし、データのサーブを停止すべきでもないということである。これらの要件を満たすために、このようなストレージシステムは、一般に、カスタマイズされた非常に信頼性のあるホットスワップ可能なハードウェアコンポーネントから構成される。それらハードウェアコンポーネントのファームウェアは、オペレーティングシステムを含めて、通常、根底から構築される。それらハードウェアコンポーネントの設計及び構築は多くの時間及び費用を要し、このことが、比較的低い製造ボリュームと結びついて、このようなストレージシステムが一般に高い価格である主な要因となっている。このようなシステムの別の不利な点は、単一システムの拡張性に欠けるということである。顧客は、通常、最小のディスクアレイ構成であっても、高い先行投資コストを支払うが、単一システムは、有限の容量及び性能しかサポートすることができない。顧客は、これらの限界を超えることができるが、その結果、システムが十分に動作しなくなるか、又は、複数のシステムを購入しなければならないことになり、これらの双方とも、管理コストが増大する。
【０００４】
出来合いのストレージシステムコンポーネント又は普及品のストレージシステムコンポーネントのフォールトトレランスを、データ複製の使用を通じて増大させることが提案されている。しかしながら、このソリューションは、冗長コンポーネントのオペレーションの調整及び複製されたデータの同期を必要とする。
【発明の開示】
【発明が解決しようとする課題】
【０００５】
したがって、冗長デバイスが設けられるストレージ環境又はデータが複製されるストレージ環境の改善された技法が必要とされている。本発明はこの目的を対象としている。
【課題を解決するための手段】
【０００６】
［発明の概要］
本発明は、データストレージシステムの冗長データの割り当て及びレイアウトのための技法を提供する。一態様では、データストレージシステムは、データのＭ個の複製を記憶する。システムに割り当てられるデータの要件に対応するのに利用可能な十分な資源を有するノードが特定される。ノードの個数がＭよりも多い場合、特定されたノードの中からランダムに選択されたＭ個のノードにデータが割り当てられる。割り当てられるデータは、データセグメントのグループを含むことができ、ノードの個数がＭ未満である場合に、そのグループは分割されて、削減された要件を有するデータセグメントのグループが形成される。次に、削減された要件に対応するのに利用可能な十分な資源を有するノードが特定される。
【０００７】
別の態様では、新しいストレージデバイスノードが、複数の既存のストレージデバイスノードを有するデータストレージシステムに追加される。既存のノードのうちの他のノードと比較して重い負荷を有する或る既存のノードが特定される。特定された既存のノードに記憶されたデータは、新しいノードに移動される。新しいノードが、既存のノードと比較して十分な負荷を有するかどうかの判断が行われる。新しいノードが十分な負荷を有しない場合、新しいノードが十分な負荷を有するまで、特定及び移動が繰り返される。
【０００８】
さらに別の態様では、データが、データストレージシステムのストレージデバイスノードから除去される。データが除去されるストレージデバイスノードにおいてデータが選択される。そのデータの要件に対応するのに利用可能な十分な資源を有するデータストレージシステムの他のノードが特定される。特定されたノードの中からランダムに選択されたノードへデータが移動される。この選択、特定、及び移動は、除去されるストレージデバイスノードが空になるまで繰り返される。次に、空になったノードは、システムから除去することができる。
【０００９】
さらなる態様では、マシンによって読み出し可能なプログラム記憶媒体が、上記で要約したように、データを割り当てる方法、ノードをシステムに追加する方法、又はデータをノードから除去する方法を実行するマシンによって実行可能な命令のプログラムを有形に実施することができる。
【００１０】
本発明のこれらの態様及び他の態様は、本明細書でより詳細に説明される。
【発明を実施するための最良の形態】
【００１１】
［好ましい実施の形態の詳細な説明］
本発明は、冗長デバイスが設けられるストレージ環境又はデータが複製されるストレージ環境の改善された技法を提供する。ストレージデバイスのアレイが、企業クラスのストレージシステムの信頼性及び性能を提供するが、この提供は、より低コストで、且つ、拡張性が改善されて行われる。各ストレージデバイスは、普及品のコンポーネントから構成することができると同時に、それらコンポーネントのオペレーションは、非集中化方式で調整される。ストレージサービスを必要とするアプリケーションの観点から、データはアレイにおいて複製されるが、アレイは、データの高可用性を有する単一のコピーを提供する。これに加えて、失敗、及び、数秒のディスク遅延等の他の振る舞い、並びに、デバイスの異なる性能特性に、ストレージサービスを必要とするアプリケーションにトランスペアレントな方法で対応するための技法も提供される。
【００１２】
図１は、本発明の一実施の形態による、複数の冗長ストレージデバイス１０２を含む例示のストレージシステム１００を示している。ストレージデバイス１０２は、（例えば、イーサネット（登録商標）上でのリモートダイレクトメモリアクセス又はＲＤＭＡを使用して）ネットワーク等の通信媒体１０４を介して相互に通信する。１つ又は複数のクライアント１０６（例えば、サーバ）は、通信媒体１０８を介してストレージシステム１００にアクセスし、読み出しオペレーション及び書き込みオペレーションを実行することによりストレージシステム１００に記憶されたデータにアクセスする。通信媒体１０８は、例えば、イーサネット（登録商標）上のｉＳＣＳＩプロトコル、ファイバチャネルプロトコル、ＳＣＳＩプロトコル、又はシリアルアッタチドＳＣＳＩプロトコルを使用する直接接続又はネットワーク接続によって実施することもできる。通信媒体１０４及び通信媒体１０８は、別個のものとして示されているが、組み合わせることもできるし、相互に接続することもできる。クライアント１０６は、データを生成し、且つ／又は、データへのアクセスを必要とするアプリケーションソフトウェア（例えば、電子メール又はデータベースアプリケーション）を実行することができる。
【００１３】
図２は、本発明の一実施の形態による、図１のストレージシステム１００で使用される例示のストレージデバイス１０２を示している。図２に示すように、ストレージデバイス１０２は、インターフェース１１０、中央処理装置（ＣＰＵ）１１２、マスストレージ１１４、及びメモリ１１６を含むことができる。マスストレージ１１４は、１つ又は複数のハードディスク等である。メモリ１１６は、好ましくは不揮発性（例えば、ＮＶ−ＲＡＭ）である。インターフェース１１０は、ストレージデバイス１０２がストレージシステム１００の他のデバイス１０２及びストレージシステム１００の外部のデバイスと通信することを可能にする。ストレージシステム１００の外部のデバイスはサーバ１０６等である。ＣＰＵ１１２は、一般に、ストレージデバイス１０２のオペレーションを制御する。メモリ１１６は、一般に、マスストレージ１１４に書き込まれるデータ及びマスストレージ１１４から読み出されたデータを一時的に記憶するためのキャッシュメモリとして動作する。また、メモリ１１６は、本明細書でより詳細に説明するように、データに関連したタイムスタンプも記憶することができる。
【００１４】
好ましくは、各ストレージデバイス１０２は、コストを最小にするために、出来合いの部品又は普及品の部品で構成される。しかしながら、各ストレージデバイス１０２は他のストレージデバイスと同一である必要はない。例えば、ストレージデバイス１０２は、異種の部品で構成することができ、性能及び／又は記憶容量において異なっていてもよい。
【００１５】
フォールトトレランスを提供するために、データは、ストレージシステム１００内で複製される。好ましい実施の形態では、ブロックやファイル等の各データ要素について、システム１００の少なくとも２つの異なるストレージデバイス１０２が、データの複製を記憶するように指定される。ここで、指定されて記憶されたデバイスの個数、したがって、複製の個数は「Ｍ」として与えられる。書き込みオペレーションの場合、（例えば、データブロックの）値は、指定されたデバイス１０２の過半数（例えば、Ｍが２又は３の場合、少なくとも２つのデバイス１０２）に記憶される。読み出しオペレーションの場合、指定されたデバイスの過半数に記憶された値が返される。
【００１６】
指定されたストレージデバイス１０２間で動作を調整するために、タイムスタンプが使用される。一態様では、各ストレージデバイスの各データブロックには、そのデータブロックが最後に更新された（すなわち、書き込まれた）時刻を示すタイムスタンプが関連付けられる。これに加えて、ブロックのそれぞれに対する保留中の更新のログが保持される。このログは、各保留中の書き込みオペレーションに関連したタイムスタンプを含む。更新は、書き込みオペレーションが開始されたが、まだ完了していない場合に保留中となる。このように、各ストレージデバイスの各データブロックについて、２つのタイムスタンプを保持することができる。
【００１７】
タイムスタンプを生成するために、各ストレージデバイス１０２はクロックを含む。このクロックは、システム１００のイベントの本来備わっている半順序を反映した論理クロックとすることもできるし、各デバイスの「壁時計」の時刻を反映した実時間クロックとすることもできる。実時間クロックを使用する場合、これらのクロックは、ほぼ同じ時刻を有するように、ストレージデバイス１０２間で同期される。ただし、それらクロックは、正確に同期されていなくてもよい。クロックの同期は、ストレージデバイス１０２が相互にメッセージを交換することによるか、又は、（例えば、サーバ１０６の１つ又は複数における）集中化アプリケーションがデバイス１０２にメッセージを送信することにより行うことができる。例えば、各タイムスタンプは、現在の時刻を示す８バイト値、及び、同一のタイムスタンプが生成されることを回避するための、各デバイス１０２に一意の４バイト識別子を含むことができる。
【００１８】
一態様では、本発明は、調整された読み出しオペレーションを実行するための技法を提供する。ストレージシステム１００のストレージデバイス１０２のいずれか１つは、クライアント１０６のいずれか等からの読み出し要求を受信することができる。この要求を受信したストレージデバイス１０２が、要求されたデータブロックを記憶するように指定されたデバイスでない場合、そのデバイスは、好ましくは、本明細書で説明するように、その要求のコーディネータとして動作する。また、要求を受信したデバイスが、データを記憶するように指定されたデバイスである場合もあるが、このことは必要ではない。したがって、デバイス１０２のいずれも要求を受信することができる。各デバイス１０２がシステム１００内におけるデータのロケーションに関する情報を有するように、各デバイスは、データロケーションテーブル（図１０）を記憶することができ、そうでない場合には、データロケーションテーブルにアクセスすることができる。次に、コーディネータデバイスは、指定されたデバイスをポーリングし（また、コーディネータデバイスが、指定されたデバイスである場合には、自身のストレージへのアクセスも行う）、指定されたデバイスの過半数に現在記憶されているデータ値を返す。
【００１９】
図３は、本発明の一実施の形態による、読み出しオペレーションを実行するための例示のタイミング図３００を示している。複数のストレージデバイス１０２を含めて、図１のストレージシステム１００のオペレーションは、図３のタイミング図に従って制御することができる。
【００２０】
図３の３つの縦線３０２、３０４、及び３０６のそれぞれは、要求されたデータを記憶するように指定された図１の３つのストレージデバイス１０２のそれぞれを表している。ストレージデバイス１０２間で通信されるメッセージは、矢印によって表されている。この矢印において、矢印の末端はメッセージを送信したストレージデバイス１０２を示し、矢印の先端はメッセージを受信することになるデバイスを示す。時間は、図３００の上から下に増加するように示されている。３つの線３０２、３０４、及び３０６が示されているので、Ｍはこの例では３に等しい。他の例では、Ｍは３よりも大きくてもよいし、小さくてもよいことは明らかであろう。
【００２１】
左端の縦線３０２は、読み出しオペレーションのコーディネータとして動作しているストレージデバイス１０２を表している一方、他の線３０４及び３０６は、他の指定されたデバイスを表している。読み出し要求は、図３ではメッセージ３０８によって示されている。
【００２２】
３つのストレージデバイス１０２のそれぞれは、要求されたデータブロックの値を記憶する。この値は、図３では「ｖａｌ」として与えられている。各データ値について、３つのストレージデバイスのそれぞれは、「ｖａｌＴＳ」及び「ｌｏｇＴＳ」として与えられた２つのタイムスタンプを記憶する。タイムスタンプｖａｌＴＳは、そのデータ値が最後に更新された時刻を示す。そのデータに対する書き込みオペレーションが開始されたが、完了していない場合には、タイムスタンプｌｏｇＴＳが、その未完了の書き込みオペレーションが開始された時刻を示す。そうでなく、このような保留中の書き込みオペレーションがない場合には、タイムスタンプｖａｌＴＳは、タイムスタンプｌｏｇＴＳよりも大きいか又は等しくなる。図３の例では、読み出しオペレーションを実行する前、３つのストレージデバイスの第１のものは、要求されたデータについての自身の値としてｖａｌ１＝「ｖ」を有し、自身のタイムスタンプｖａｌＴＳ１及びｌｏｇＴＳ１は同じであり、「５」に等しい。これに加えて、３つのストレージデバイス１０２の第２のものは、要求されたデータについての自身の値としてｖａｌ２＝「ｘ」を有し、自身のタイムスタンプｖａｌＴＳ２及びｌｏｇＴＳ２は同じであり、「４」に等しい（「４」は「５」よりも小さいので、このことは、ｖａｌＴＳ２がｖａｌＴＳ１よりも時間が先であることを示す）。ストレージデバイスの第３のものでは、要求されたデータについての自身の値はｖａｌ３＝「ｖ」であり、自身のタイムスタンプｖａｌＴＳ３及びｌｏｇＴＳ３は同じであり、「５」に等しい。
【００２３】
３つのストレージデバイス１０２の第１のものは、読み出し要求メッセージ３０８に応答して、要求されたデータの自身の更新タイムスタンプｖａｌＴＳ１をチェックして、メッセージ３１０及びメッセージ３１２を他の２つのストレージデバイス１０２へ転送する。図３に示すように、メッセージ３１０及びメッセージ３１２は、読み出しオペレーションを示すためにタイプ「Ｒｅａｄ」を有し、好ましくは、コーディネータストレージデバイス（３つのストレージデバイスの第１のもの）におけるｖａｌＴＳ１タイムスタンプの値を含む。したがって、ｖａｌＴＳ１タイムスタンプの値「５」が、メッセージ３１０及びメッセージ３１２に含まれる。
【００２４】
他の指定されたストレージデバイスのそれぞれは、メッセージ３１０及びメッセージ３１２に応答して、自身のローカルなタイムスタンプｖａｌＴＳ及びｌｏｇＴＳタイムスタンプの値を、コーディネータストレージデバイスから受信したｖａｌＴＳタイムスタンプ値と比較する。ローカルなｖａｌＴＳタイムスタンプが、コーディネータデバイスから受信したｖａｌＴＳタイムスタンプと等しい場合、このことは、双方のデバイスがデータブロックの同じバージョンを有することを示す。そうでない場合、バージョンのすべてが、前の書き込みオペレーション中に更新されていたとは限らない場合がある。この場合、それらバージョンは異なることがある。したがって、データ自体ではなく、タイムスタンプを比較することによって、デバイス１０２は、データが同じであるかどうかを判断することができる。タイムスタンプではなく、データ自体（又はハッシュ値等のデータの或る表現）を比較できることも明らかであろう。
【００２５】
また、ローカルなｌｏｇＴＳが、コーディネータのｖａｌＴＳタイムスタンプ以下である場合、このことは、現在保留中のデータに対して近時に更新が行われていないことを示す。ローカルなｌｏｇＴＳがｖａｌＴＳよりも大きい場合、このことは、コーディネータが、利用可能なデータの最新バージョンを有しない場合があることを示す。
【００２６】
上記２つの状況が満たされる場合、ストレージデバイスは、肯定応答（「イエス」又は「真」）をコーディネータデバイスに返す。上記は、以下の式によって表すことができる。
【００２７】
Ｉｆ
ｖａｌＴＳ（ローカル）＝ｖａｌＴＳ（コーディネータ）， 且つ、
ｌｏｇＴＳ（ローカル）≦ｖａｌＴＳ（コーディネータ），
ｔｈｅｎ，「イエス」を応答する；
ｏｔｈｅｒｗｉｓｅ，「ノー」を応答する                            （１）
【００２８】
図３の例を参照して、（縦線３０６によって表された）第３のストレージデバイスが上記式（１）を評価すると、第３のストレージデバイスは、コーディネータに「イエス」を返す。これは、図３では、第３のデバイスからコーディネータへ送信されたメッセージ３１４によって示されている。
【００２９】
コーディネータストレージデバイス及び第３のストレージデバイスは、同じｖａｌＴＳタイムスタンプを有する（且つ、保留中の更新はない）ので、このことは、コーディネータ及び第３のストレージデバイスが、要求されたデータの同じバージョンを有することを示す。したがって、この例では、（３つ存在する場合の）指定されたデバイスの過半数（すなわち、２つ）が同じデータを有する。したがって、コーディネータは、メッセージ３１４を受信したことに応答して、コーディネータに記憶された、要求されたデータを含むリプライメッセージ３１６を送信する。このリプライメッセージ３１６は、要求側サーバ１０６に回送される。
【００３０】
要求されたデータは、コーディネータではない、指定されたデバイスの１つから来ることもある（例えば、コーディネータはデータのローカルなコピーを有しないこともあるし、有することもあるが、いずれにしても別のデバイスからそのデータを取得する）。この場合、コーディネータは、指定されたデバイスの１つを、データを返すためのデバイスとして指名する。このデバイスの選択は、ランダムとすることもできるし、負荷情報に基づくこともできる。システム１００の全体の負荷がバランスされるように、例えば、負荷は、負荷の重いデバイスからその近傍のデバイスへ移動させることができ、近傍のデバイスは、その負荷をさらにその近傍のデバイスへ移動させることができ、以下、同様に移動させることができる。したがって、負荷バランシングを行うように、異質の性能を有するストレージデバイスを適応させることができ、いくつかのストレージデバイスが障害を受けた場合にも、負荷バランシングを行うことができる。
【００３１】
次に、コーディネータは、（例えば、メッセージ３１０及びメッセージ３１２の代わりに）各デバイスへ異なるメッセージを送信することによって、指定されたデバイスから＜データ，ｖａｌＴＳ，ステータス＞を請求し、他のデバイスから＜ｖａｌＴＳ，ステータス＞を請求する。その後、それらデバイスは、自身のｖａｌＴＳタイムスタンプをコーディネータに返し、その結果、コーディネータはタイムスタンプをチェックすることができる。ステータス情報（「イエス」又は「ノー」応答）は、それらデバイスにおいて、ｌｏｇＴＳがｖａｌＴＳ以下であるかどうかを示す。（例えば、指定されたデバイスがダウンしているか、若しくは、時間内に応答しないことから）指定されたデバイスが定足数の一部でないか、又は、定足数が検出されない場合、コーディネータは、本明細書で説明するような修復オペレーション（「回復」オペレーションとも呼ばれる）を開始することができる（すなわち、コーディネータは、読み出しが失敗したものとみなす）。指定されたデバイスが応答し、肯定応答の定足数が受信された場合、コーディネータは、成功を宣言し、指定されたデバイスからのデータを返す。
【００３２】
このように、コーディネータは、データ自体を比較する必要があるのではなく、関連したタイムスタンプのみを検査することによって、指定されたストレージデバイス１０２の過半数がデータの同じバージョンを有するかどうかを判断することができる。これに加えて、コーディネータは、デバイスの少なくとも過半数がデータの同じバージョンを有するとタイムスタンプから判断すると、指定されたストレージデバイスのすべてから「イエス」又は「ノー」の回答を待つ必要なく、そのデータでリプライすることができる。
【００３３】
図３の例に戻って、（縦線３０４で表された）第２のストレージデバイスが上記式（１）を評価すると、第２のストレージデバイスは、図３のメッセージ３１８によって示すように、コーディネータに否定応答（「ノー」又は「偽」）を返す。これは、第２のデバイスのｖａｌＴＳタイムスタンプの値及びｌｏｇＴＳタイムスタンプの値が、コーディネータのｖａｌＴＳタイムスタンプよりも小さいからである。これは、通信が失敗し、その結果、第２のデバイスが時刻「５」で行われた更新を受信しなかったことに起因している場合がある。しかしながら、上述したように、コーディネータは、要求されたデータをすでに提供している場合がある。いずれにしても、過半数は「イエス」で応答したので、「ノー」メッセージ３１８をコーディネータは無視することができる。
【００３４】
上述したように、読み出しオペレーションによって、指定されたデバイスのいずれかから（タイムスタンプではなく）データを読み出すことが可能になる。
【００３５】
別の態様では、本発明は、調整された書き込みオペレーションを実行するための技法を提供する。一般に、書き込みオペレーションは２つのフェーズで実行される。この２つのフェーズは、「事前書き込み」フェーズ及び書き込みフェーズを含む。事前書き込みフェーズでは、書き込まれるデータのｌｏｇＴＳタイムスタンプが更新され、次いで、書き込みフェーズでは、データ及びｖａｌＴＳタイムスタンプが更新される。部分的な書き込みオペレーション又は未完了の書き込みオペレーションは、データブロックを記憶するように指定されたストレージデバイスのすべてが、そのブロックに対する更新を受信しているとは限らないオペレーションである。これは、例えば、デバイスの１つに影響を与える障害が発生した場合、又は、デバイスのすべてが更新を受信する前に障害が発生したときに起こり得る。２つのタイムスタンプを保持することによって、部分的な書き込み又は未完了の書き込みを検出して、これに対処することができる。
【００３６】
サーバ１０６のいずれか等からの書き込み要求は、ストレージシステム１０２のストレージデバイス１０２のいずれか１つが受信することができる。その要求を受信したストレージデバイス１０２は、たとえ要求されたデータブロックを記憶するように指定されたデバイスでなくても、好ましくはコーディネータとして動作する。代替的な実施の形態では、そのデバイスは、要求を、そのように指定されたデバイス１０２の１つへ転送することができ、その１つのデバイスが、その後、この書き込み要求のコーディネータとして動作する。読み出しオペレーションと同様に、指定されたデバイスのいずれも、書き込み要求を受信することができる。しかしながら、要求を受信したデバイスは、その後、その要求のコーディネータとして動作する。
【００３７】
図４は、本発明の一実施の形態による、書き込みオペレーションを実行するための例示のタイミング図４００を示している。複数のストレージデバイス１０２を含めて、図１のストレージシステム１００のオペレーションは、図４のタイミング図に従って制御することができる。
【００３８】
図４の３つの縦線４０２、４０４、及び４０６のそれぞれは、図１の３つのストレージデバイス１０２のそれぞれを表している。これらのうち、左端の縦線４０２は、書き込みオペレーションのコーディネータとして動作しているストレージデバイスを表し、他の線４０４及び４０６は、他の指定されたデバイスを表している。書き込み要求は、図４では、コーディネータによって受信されたメッセージ４０８により示されている。
【００３９】
図４の例では、書き込みオペレーションを実行する前に、３つのストレージデバイス１０２の第１のものは、書き込まれるロケーションのデータについての自身の現在の値としてｖａｌ１＝「ｖ」を有し、自身のタイムスタンプｖａｌＴＳ１及びｌｏｇＴＳ１は同じであり、「５」に等しい。これに加えて、３つのストレージデバイス１０２の第２のものは、書き込まれるロケーションのデータについての自身の値としてｖａｌ２＝「ｘ」を有し、自身のタイムスタンプｖａｌＴＳ２は「４」に等しく、自身のタイムスタンプｌｏｇＴＳ２は「５」に等しい。ストレージデバイスの第３のものでは、データについての自身の値はｖａｌ３＝「ｖ」であり、自身のタイムスタンプｖａｌＴＳ３及びｌｏｇＴＳ３は同じであり、「５」に等しい。
【００４０】
コーディネータは、書き込み要求メッセージ４０８に応答して、ｌｏｇＴＳタイムスタンプの新しい値として新しいタイムスタンプ値「８」のｎｅｗＴＳを他の２つのストレージデバイスへメッセージ４１０及びメッセージ４１２を介して転送する。この新しいタイムスタンプ値は、好ましくは、書き込み要求が開始される現在の時刻を表す。図４に示すように、これらの書き込み開始メッセージ４１０及び４１２は、事前書き込みオペレーションを示すタイプ「ＷＯｒｄｅｒ」を有し、新しいタイムスタンプ値「８」を含む。
【００４１】
次に、他の指定されたストレージデバイスのそれぞれは、メッセージ４１０及び４１２に応答して、自身のローカルなｌｏｇＴＳタイムスタンプの現在の値及び自身のローカルなｖａｌＴＳタイムスタンプの値を、コーディネータストレージデバイスから受信したｎｅｗＴＳタイムスタンプ値と比較する。ローカルなｌｏｇＴＳタイムスタンプ及びローカルなｖａｌＴＳタイムスタンプの双方が、コーディネータデバイスから受信したｎｅｗＴＳタイムスタンプよりも小さい場合、このことは、それより後のｌｏｇＴＳタイムスタンプを有する別の保留中の書き込みオペレーション又は完了した書き込みオペレーションが現在存在しないことを示す。この場合、ストレージデバイスは、自身のローカルなｌｏｇＴＳタイムスタンプをその新しい値に更新し、肯定応答メッセージ又は「イエス」応答メッセージをコーディネータに返す。
【００４２】
そうでなく、進行中の近時の書き込みオペレーションが存在する場合、ストレージデバイスは、否定応答又は「ノー」応答で応答する。指定されたデバイスの過半数が、それらデバイスのタイムスタンプのいずれかについてより大きい値を有する場合、このことは、現在の書き込みオペレーションがそれより後の書き込みオペレーションを優先して中止されるべきであることを示す。その理由は、それより後の書き込みオペレーションのデータが、より最新である可能性があるからである。この場合、コーディネータは過半数の「ノー」応答を受信し、現在の書き込みオペレーションは中止される。コーディネータは、その後、新しい（後の）タイムスタンプを使用して、そのオペレーションを再試行することができる。
【００４３】
上記は、以下の式によって表すことができる。
【００４４】
Ｉｆ，
ｖａｌＴＳ（ローカル）＜ｎｅｗＴＳ，且つ、
ｌｏｇＴＳ（ローカル）＜ｎｅｗＴＳ，
ｔｈｅｎ，「イエス」を応答し、ｌｏｇＴＳ（ローカル）＝ｎｅｗＴＳに設定する；
ｏｔｈｅｒｗｉｓｅ，「ノー」を応答する                            （２）
【００４５】
図４の例を参照して、ｖａｌＴＳ２は「４」であり、ｌｏｇＴＳ２は「５」である。双方の値はｎｅｗＴＳ値「８」よりも小さいので、（縦線４０４によって表された）第２のストレージデバイスは、メッセージ４１４で「イエス」を返し、自身のｌｏｇＴＳ２タイムスタンプをｎｅｗＴＳ値「８」に等しく設定する。同様に、ｖａｌＴＳ３及びｌｏｇＴＳ３は、共に「５」に等しい。これは「８」よりも小さい。したがって、（縦線４０６によって表された）第３のストレージデバイスも、メッセージ４１６で「イエス」を返し、自身のｌｏｇＴＳ３タイムスタンプをｎｅｗＴＳ値「８」に等しく設定する。その一方で、コーディネータデバイスも、自身のタイムスタンプｖａｌＴＳ１及びｌｏｇＴＳ１をタイムスタンプｎｅｗＴＳと比較する。これら２つの値は共に「５」であり、これは「８」よりも小さいので、コーディネータデバイスも、「イエス」の回答を有し（ただし、この回答は転送される必要はない）、自身のｌｏｇＴＳ１タイムスタンプを「８」に等しく設定する。
【００４６】
この時点で、事前書き込みフェーズは完了し、指定されたストレージデバイスの３つのすべては初期化されて、書き込みオペレーションの第２フェーズを実行する。ただし、この第２フェーズはデバイスの過半数で進めることができる。したがって、この例では、第２フェーズは、指定されたデバイスの１つが「ノー」応答を返していたとしても進めることができる。
【００４７】
第２フェーズを実行するために、コーディネータデバイスは、メッセージタイプ「Ｗｒｉｔｅ」を他の指定されたデバイスのそれぞれへ送信する。このメッセージタイプ「Ｗｒｉｔｅ」は、書き込みオペレーションの第２フェーズを示し、データの新しいバージョン及びタイムスタンプｎｅｗＴＳを含む。これらのメッセージは、図４では、メッセージ４１８及びメッセージ４２０によってそれぞれ示されている。メッセージ４１８及びメッセージ４２０のそれぞれは、メッセージタイプ「Ｗｒｉｔｅ」、データの新しいバージョン「ｙ」、及び新しいタイムスタンプ「８」を含む。
【００４８】
次に、他の指定されたストレージデバイスのそれぞれは、メッセージ４１８及びメッセージ４２０に応答して、好ましくは、自身のローカルなｌｏｇＴＳタイムスタンプの現在の値及び自身のローカルなｖａｌＴＳタイムスタンプの値を、コーディネータストレージデバイスからの「Ｗｒｉｔｅ」メッセージで受信したｎｅｗＴＳタイムスタンプ値と比較する。この比較によって、現在のオペレーションの完了前に別の書き込みオペレーションが開始された場合に発生し得るように、それより後のｌｏｇＴＳタイムスタンプを有する別の保留中の書き込みオペレーション又は完了した書き込みオペレーションが現在存在しないことが確保される。
【００４９】
より詳細には、ローカルなｖａｌＴＳタイムスタンプが、コーディネータデバイスから受信されたｎｅｗＴＳタイムスタンプよりも小さく、且つ、ローカルなｌｏｇＴＳタイムスタンプがｎｅｗＴＳタイムスタンプ以下である場合、このことは、それより後のタイムスタンプを有する別の保留中の書き込みオペレーション又は完了した書き込みオペレーションが現在存在しないことを示す。この場合、ストレージデバイスは、データをその新しい値に更新する。これに加えて、ストレージデバイスは、好ましくは、自身のローカルなｖａｌＴＳタイムスタンプをｎｅｗＴＳタイムスタンプの値に更新し、肯定応答メッセージ又は「イエス」応答メッセージをコーディネータに返す。
【００５０】
そうでなく、進行中の近時の書き込みオペレーションが存在する場合、ストレージデバイスは、「ノー」応答で応答する。コーディネータが過半数の「ノー」応答を受信した場合、現在の書き込みオペレーションは中止される。
【００５１】
上記は、以下の式によって表すことができる。
【００５２】
Ｉｆ，
ｖａｌＴＳ（ローカル）＜ｎｅｗＴＳ，且つ、
ｌｏｇＴＳ（ローカル）≦ｎｅｗＴＳ，
ｔｈｅｎ，「イエス」を応答し、ｖａｌＴＳ（ローカル）＝ｎｅｗＴＳ及びｖａｌ（ローカル）＝ｖａｌ（コーディネータ）に設定する；
ｏｔｈｅｒｗｉｓｅ，「ノー」を応答する                            （３）
【００５３】
図４の例を参照して、（縦線４０４によって表された）第３のストレージデバイスは、メッセージ４２２を介して「イエス」応答を返し、（縦線４０６によって表された）第２のストレージデバイスも、メッセージ４２４を介して「イエス」を返す。その一方で、コーディネータデバイスも、自身のタイムスタンプｖａｌＴＳ１及びｌｏｇＴＳ１をタイムスタンプｎｅｗＴＳと比較する。コーディネータデバイスも、「イエス」の回答を有し（ただし、この回答は転送される必要はない）、自身のｖａｌＴＳ１タイムスタンプを「８」に等しく設定し、自身のデータのバージョンｖａｌ１を「ｖ」に設定する。
【００５４】
これに加えて、コーディネータは、ストレージデバイスの過半数が書き込みオペレーションの第２フェーズについて「イエス」回答を返したと判断すると、リプライメッセージを要求者に送信する。コーディネータ及び第３のデバイス、したがって、過半数が第２のフェーズを確認したので、図４に示すように、コーディネータが第３のデバイスからリプライメッセージ４２２を受信するとすぐにメッセージ４２６を送信することができる。
この場合、メッセージ４２４がたとえ「ノー」回答を含んでいたとしても、過半数は、オペレーションが成功したことを示す「イエス」回答を返したので、第２のデバイスからのリプライメッセージ４２４を無視することができる。
【００５５】
別の態様では、本発明は、修復オペレーションを実行するための技法を提供する。書き込みオペレーションデバイスのコーディネータが、事前書き込みメッセージを送信した後であって、書き込みオペレーションを完了する前に障害を受けたことから、書き込みオペレーションは失敗したものと仮定する。この場合、失敗した書き込みオペレーションが試みられた、データ（例えば、ブロック）を記憶するように指定されたストレージデバイスは、コーディネータのｖａｌＴＳタイムスタンプよりも大きなｌｏｇＴＳタイムスタンプを有する。別の例として、ストレージデバイスが書き込みオペレーションの事前書き込みメッセージ及び書き込みメッセージを受信することが、通信エラーによって妨げられていた場合がある。この場合、そのストレージデバイスは、このデータブロックについて、そのデータブロックを記憶するように指定された他のストレージデバイスのｖａｌＴＳタイムスタンプとは異なるｖａｌＴＳタイムスタンプを有する。いずれの場合も、読み出しオペレーションがそのデータについて要求されると、この読み出しオペレーションのコーディネータデバイスは、他のデバイスが、コーディネータによって送信された読み出しメッセージに応答して「ノー」リプライを返した時に、これらの障害を検出する。この場合、この障害を検出したコーディネータは、修復オペレーションを開始して、データブロックを、そのブロックを記憶するように指定されたデバイス間で一致したものに戻すことができる。修復オペレーションは、データを読み出す試みが行われた場合にのみ実行されるので、本発明のこの態様では、その後に必要とされないデータを修復する等の不必要なオペレーションが回避される。
【００５６】
要約すると、修復オペレーションは２つのフェーズで実行される。初期化フェーズでは、修復オペレーションのコーディネータが、指定されたデバイスのいずれがデータブロックの最も新しいバージョンを有するかを判断する。第２フェーズでは、コーディネータが、データの最も新しいバージョンをデバイスに書き込む。その上、指定されたデバイスにおけるブロックのタイムスタンプも更新される。
【００５７】
図５は、本発明の一実施の形態による、修復オペレーションを実行するための例示のタイミング図５００を示している。複数のストレージデバイス１０２を含めて、図１のストレージシステム１００のオペレーションは、図５のタイミング図に従って制御することができる。
【００５８】
図５の３つの縦線５０２、５０４、及び５０６のそれぞれは、図１の３つのストレージデバイス１０２のそれぞれを表している。これらのうち、左端の縦線５０２は、修復オペレーションのコーディネータとして動作しているストレージデバイスを表し、他の線５０４及び５０６は、他の指定されたデバイスを表している。
【００５９】
図５の例では、修復オペレーションを実行する前に、３つのストレージデバイスの第１のもの（すなわち、コーディネータ）は、書き込まれるロケーションのデータについての自身の現在の値としてｖａｌ１＝「ｖ」を有し、自身のタイムスタンプｖａｌＴＳ１及びｌｏｇＴＳ１は同じであり、「５」に等しい。これに加えて、３つのストレージデバイスの第２のものは、書き込まれるロケーションのデータについての自身の値としてｖａｌ２＝「ｘ」を有し、自身のタイムスタンプｖａｌＴＳ２及びｌｏｇＴＳ２は同じであり、「４」に等しい。ストレージデバイスの第３のものでは、データについての自身の値はｖａｌ３＝「ｖ」であり、自身のタイムスタンプｖａｌＴＳ３及びｌｏｇＴＳ３は同じであり、「５」に等しい。
【００６０】
修復オペレーションは、コーディネータデバイスが、失敗した読み出しオペレーションを検出した時に開始することができる。図３を参照して、例えば、メッセージ３１４が喪失された場合、コーディネータは、過半数の確認応答を受信しないことになる。このことは、図５では、コーディネータデバイスの時間表５０２の始点の近くにある表記「失敗した読み出し」によって示されている。コーディネータデバイスは、修復開始メッセージ５０８及び修復開始メッセージ５１０を他の指定されたデバイスへ送信することによって修復オペレーションを開始する。図５に示すように、これらの修復開始メッセージ５０８及び修復開始メッセージ５１０は、修復オペレーションを示すタイプ「ＲＯｒｄｅｒ」を有し、新しいタイムスタンプ値「８」のｎｅｗＴＳを含む。この新しいタイムスタンプ値は、好ましくは、修復オペレーションが開始された現在の時刻を表す。
【００６１】
他の指定されたストレージデバイスのそれぞれは、修復開始メッセージ５０８及び修復開始メッセージ５１０に応答して、自身のローカルなｌｏｇＴＳタイムスタンプの現在の値及び自身のローカルなｖａｌＴＳタイムスタンプの値を、コーディネータストレージデバイスから受信した新しいタイムスタンプ値ｎｅｗＴＳと比較する。ローカルなｌｏｇＴＳタイムスタンプ及びローカルなｖａｌＴＳタイムスタンプの双方が、コーディネータデバイスから受信したｎｅｗＴＳタイムスタンプよりも小さい場合、このことは、それより後のタイムスタンプを有する保留中の書き込みオペレーション又は完了した書き込みオペレーションが現在存在しないことを示す。この場合、ストレージデバイスは、自身のローカルなｌｏｇＴＳタイムスタンプをｎｅｗＴＳタイムスタンプの値に更新し、肯定応答メッセージ又は「イエス」応答メッセージをコーディネータに返す。これに加えて、各ストレージデバイスは、訂正されるデータブロックの現在のバージョン、及び、自身のｖａｌＴＳタイムスタンプも返す。
【００６２】
そうでなく、進行中の近時の書き込みオペレーションが存在する場合、ストレージデバイスは、否定応答又は「ノー」応答で応答する。指定されたデバイスの過半数が、それらデバイスのタイムスタンプのいずれかについてより大きい値を有する場合、このことは、修復オペレーションがそれより後に発生する書き込みオペレーションを優先して中止されるべきであることを示す。その理由は、それより後の書き込みオペレーションのデータが、より最新である可能性があるからである。この場合、コーディネータは過半数の「ノー」応答を受信し、現在の書き込みオペレーションは中止される（ただし、元の読み出しオペレーションは再試行することができる）。
【００６３】
上記は、以下の式によって表すことができる。
【００６４】
Ｉｆ，
ｖａｌＴＳ（ローカル）＜ｎｅｗＴＳ，且つ、
ｌｏｇＴＳ（ローカル）＜ｎｅｗＴＳ，
ｔｈｅｎ，「イエス」を応答し、ｌｏｇＴＳ（ローカル）＝ｎｅｗＴＳに設定する；
ｏｔｈｅｒｗｉｓｅ，「ノー」を応答する                            （４）
【００６５】
したがって、図５に示すように、第２の指定されたストレージデバイスはメッセージ５１２で応答し、このメッセージ５１２は、「ｙｅｓ」応答、データコンテンツ「ｘ」、及び第２の指定されたストレージデバイスのｖａｌＴＳ２タイムスタンプ「４」を含む。これに加えて、第３の指定されたストレージデバイスは、メッセージ５１４で応答し、このメッセージ５１４は、「ｙｅｓ」応答、データコンテンツ「ｖ」、及びｖａｌＴＳ３タイムスタンプ「５」を含む。その一方で、コーディネータは、自身のデータをチェックし、自身も「イエス」回答を有すると判断する（ただし、この回答は転送される必要はない）。コーディネータのデータのバージョンｖａｌ１は「ｖ」であり、コーディネータのｖａｌＴＳ１タイムスタンプは「５」に等しい。デバイスのすべてが「イエス」回答を返したので、各デバイスは、好ましくは、自身のｌｏｇＴＳタイムスタンプをｎｅｗＴＳ値に設定する。このｎｅｗＴＳ値は、この例では「８」である。
【００６６】
次に、コーディネータは、どのストレージデバイスがデータの最新バージョンを有するかを判断する。これは、好ましくは、コーディネータが、他のデバイスから受信したｖａｌＴＳタイムスタンプ及び自身のｖａｌＴＳタイムスタンプを比較して、どのｖａｌＴＳタイムスタンプが最新であるかを判断することによって行われる。次に、コーディネータは書き込みオペレーションを開始する。この書き込みオペレーションでは、データの最新バージョンが、一致しないあらゆるバージョンに取って代わる。この例では、最新のｖａｌＴＳタイムスタンプは「５」であり、このタイムスタンプは、コーディネータ及び第３のストレージデバイスのｖａｌＴＳタイムスタンプである。第２のデバイスは、古いタイムスタンプ「４」及びデータの異なるバージョン「ｘ」を有する。ｖａｌＴＳタイムスタンプ「５」に関連したデータのバージョンは「ｖ」である。したがって、バージョン「ｖ」は、好ましくは、コーディネータによって選択されて、第２のストレージデバイスのバージョン「ｘ」に取って代わる。
【００６７】
この書き込みオペレーションは、コーディネータデバイスがメッセージタイプ「Ｗｒｉｔｅ」を他の指定されたデバイスのそれぞれへ送信することによって行われる。このメッセージタイプ「Ｗｒｉｔｅ」は、データの新しいバージョン及びタイムスタンプｎｅｗＴＳを含む。これらのメッセージは、図５では、メッセージ５１６及びメッセージ５１８によってそれぞれ示されている。メッセージ５１６及びメッセージ５１８のそれぞれは、メッセージタイプ「Ｗｒｉｔｅ」、データの新しいバージョン「ｖ」、及び新しいタイムスタンプ「８」を含む。メッセージ５１６及びメッセージ５１８は、フォーマットが、書き込みオペレーションの第２フェーズを実行するために送信されたメッセージ４２０及びメッセージ４２２（図４）と同一にできることに留意されたい。
【００６８】
次に、図４の書き込みオペレーションの第２フェーズと同様に、他の指定されたストレージデバイスのそれぞれは、メッセージ５１６及びメッセージ５１８に応答して、好ましくは、自身のローカルなｌｏｇＴＳタイムスタンプの現在の値及び自身のローカルなｖａｌＴＳタイムスタンプの値を、コーディネータストレージデバイスからの「Ｗｒｉｔｅ」メッセージで受信したｎｅｗＴＳタイムスタンプ値と比較する。この比較によって、現在の修復オペレーションの完了前に書き込みオペレーションが開始された場合に発生し得るように、それより後のタイムスタンプを有する別の保留中の書き込みオペレーション又は完了した書き込みオペレーションが現在存在しないことが確保される。そうでなく、進行中の近時の書き込みオペレーションが存在する場合、ストレージデバイスは、「ノー」応答で応答する。修復オペレーションの第２フェーズのこの評価は、上記式（３）によって表すことができる。これに加えて、デバイスは、それらのローカルなｌｏｇＴＳタイムスタンプであるｌｏｇＴＳ２及びｌｏｇＴＳ３をｎｅｗＴＳ値「８」に更新する。
【００６９】
図５の例を参照して、（縦線５０４によって表された）第３のストレージデバイスは、メッセージ５２０を介して「イエス」応答を返し、（縦線５０６によって表された）第２のストレージデバイスも、メッセージ５２２を介して「イエス」を返す。したがって、これらのデバイスは、ｖａｌＴＳ２タイムスタンプ及びｖａｌＴＳ３タイムスタンプをｎｅｗＴＳ値「８」に設定し、自身のデータのバージョンｖａｌ２及びｖａｌ３を「ｖ」に更新する。その一方で、コーディネータデバイスも、自身のタイムスタンプｖａｌＴＳ１及びｌｏｇＴＳ１をタイムスタンプｎｅｗＴＳと比較する。コーディネータデバイスも、「イエス」の回答を有し（ただし、この回答は転送される必要はない）、自身のｖａｌＴＳ１タイムスタンプを「８」に等しく設定し、自身のデータのバージョンｖａｌ１を「ｖ」に設定する。
【００７０】
コーディネータは、ストレージデバイスの過半数が修復オペレーションの第２フェーズについて「イエス」回答を返したと判断すると、データ値「ｖ」を含むリプライメッセージ５２４を要求者に送信することができる。このリプライは、好ましくは、修復オペレーションが、失敗した読み出しオペレーションに応答して開始された場合に送信される。したがって、リプライ５２４は、読み出しオペレーションによって要求されたデータを返す。コーディネータ及び第３のデバイス、したがって過半数が、修復オペレーションの第２フェーズを確認しているので、図５に示すように、コーディネータが第３のデバイスからメッセージ５２０を受信するとすぐにメッセージ５２４を送信することができる。この場合、メッセージ５２２がたとえ「ノー」回答を含んでいたとしても、過半数は、オペレーションが成功したことを示す「イエス」回答を返したので、第２のデバイスからのメッセージ５２２を無視することができる。
【００７１】
２つのタイムスタンプｖａｌＴＳ及びｌｏｇＴＳが各データブロックに関連付けられ、これらのタイムスタンプのそれぞれが１２バイト長であると仮定する。上述したように、各タイムスタンプは、現在の時刻を示す値、及び、同一のタイムスタンプが生成されることを回避するための、各デバイス１０２に一意の識別子を含むことができる。また、各データブロックは１ＫＢ（１キロバイト）であり、図１のストレージシステム１００は１ＴＢ（１テラバイト）の容量を有するものと仮定する。これらの数字は、タイムスタンプを記憶するのに、最大１２ＧＢ（１２ギガバイト）の容量が必要される場合があることを意味する。タイムスタンプは、好ましくは、高速で永続的なストレージに保持されるので、不揮発性メモリ（ＮＶ−ＲＡＭ）が望ましい。しかしながら、十分な容量のＮＶ−ＲＡＭを提供することは多額の費用を要する。
【００７２】
このように、本発明の一態様によれば、タイムスタンプに必要なストレージ容量を削減するようにタイムスタンプを管理するための技法が提供される。より詳細には、上述した読み出しオペレーション、書き込みオペレーション、及び修復オペレーションについて、タイムスタンプは、（ｌｏｇＴＳの場合のように）データに対する同時更新のあいまいさをなくすのに使用され、（ｖａｌＴＳの場合のように）失敗の結果を検出して修復するのに使用されることに注目することができる。したがって、一態様では、データブロックの複製のすべてが機能している場合、そのデータの複製を保持する各デバイス１０２が更新の事実を確認した後は、タイムスタンプは廃棄することができる。したがって、書き込みオペレーション及び修復オペレーションの場合、指定されたデバイスのすべてがリプライした後、コーディネータが、指定されたデバイスにデータブロックのタイムスタンプを廃棄するように指示する第３フェーズを実行することができる。代替的に、各デバイス１０２は、自身のｖａｌＴＳタイムスタンプが自身のｌｏｇＴＳタイムスタンプと等しいかどうかを判断し、等しい場合には、それらタイムスタンプの一方（例えば、ｌｏｇＴＳタイムスタンプ）を削除することができる。
【００７３】
このように、各ストレージデバイス１０２は、アクティブに更新されているデータブロックのタイムスタンプを保持することのみ必要である。或る失敗が１つ又は複数の複製に影響を与える場合、データが修復されるか、又は、その失敗がその他の方法で対処される（例えば、システム１００が再構成される）まで、他のデバイス１０２は、そのデータについての自身のタイムスタンプを保持する。
【００７４】
別の態様では、単一の書き込み要求は、通常、複数のデータブロックを更新するので、これらのデータブロックのそれぞれは、同じタイムスタンプを有する。したがって、タイムスタンプは、各データブロックについてではなく、或る範囲のデータブロックについて保持することができる。例えば、８つの連続したデータブロック「Ｂｌｏｃｋ１」から「Ｂｌｏｃｋ８」が同じ書き込み要求によって更新される場合、各ブロックにつき１つの計８つのタイムスタンプエントリを保持するのではなく、８つのブロックすべてについて単一のタイムスタンプエントリを保持することができる。タイムスタンプは、データ構造体のエントリとして保持することができる。各エントリは以下のフォームを有することができる。
【００７５】
［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］                （５）
【００７６】
ここで、ｓｔａｒｔ（スタート）はこの範囲の始点を特定し、ｅｎｄ（エンド）はこの範囲の終点を特定し、ｔｉｍｅｓｔａｍｐ（ｓ）（タイムスタンプ）は、この範囲のブロックのすべてに適用される。この例では、２つのタイムスタンプについての単一のエントリは、以下のフォームを取ることができる。
【００７７】
［Ｂｌｏｃｋ１，Ｂｌｏｃｋ９，ｖａｌＴＳ１−９，ｌｏｇＴＳ１−９］                                                                   （６）
【００７８】
この場合、ｖａｌＴＳタイムスタンプ及びｌｏｇＴＳタイムスタンプの双方について、単一のデータ構造体を保持することができる。代替的に、２つのタイムスタンプのそれぞれにつき１つの計２つのエントリを保持することもできる。この場合、２つのタイムスタンプのそれぞれにつき１つの計２つのデータ構造体を保持することができる。この例では、これら２つのエントリは次のフォームを取ることができる。
【００７９】
［Ｂｌｏｃｋ１，Ｂｌｏｃｋ９，ｖａｌＴＳ１−９］              （７）
及び
［Ｂｌｏｃｋ１，Ｂｌｏｃｋ９，ｌｏｇＴＳ１−９］              （８）
【００８０】
上記例示のエントリの範囲のｅｎｄは、その範囲内にある８つのブロックの後の次のブロックによって特定されることに留意されたい。したがって、上記エントリ（６）は、９番目のブロックを示すＢｌｏｃｋ９を含むのに対して、関連付けられたタイムスタンプの範囲内には８つのブロックのみがある。エントリに含まれるｅｎｄがその範囲内の最後のブロックである等の代替的な規約も使用することができる。例えば、上記エントリ（６）は、代わりに次のフォームを取る。
【００８１】
［Ｂｌｏｃｋ１，Ｂｌｏｃｋ８，ｖａｌＴＳ１−８，ｌｏｇＴＳ１−８］                                                                    （９）
【００８２】
ここで、「Ｂｌｏｃｋ８」は、この範囲の最後のブロックである８番目のブロックを示す。
【００８３】
好ましい実施の形態では、上記タイムスタンプエントリは、区間木のようなデータ構造に保持され、詳細には、Ｂ木データ構造体に保持される。図６は、本発明の一態様による、タイムスタンプを保持するためのＢ木データ構造体６００を示している。図６に示すように、データ構造体６００は複数のキー値対を含む。ここで、キーは昇順に配列され、各キーは、上記フォーム［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］のタイムスタンプエントリに対応する値又はエントリに関連付けられる。各エントリは、好ましくは、或る範囲のデータブロックをカバーする。この範囲は他のどのエントリの範囲とも重ならない。したがって、図６では、ｓｔａｒｔ１及びｅｎｄ１によって特定された範囲は、ｓｔａｒｔ２及びｅｎｄ２によって特定された範囲とは重ならない。さらに、エントリは、好ましくは、ｓｔａｒｔの値の昇順で配列され、ここで、ｓｔａｒｔ値はキーとしても働く。
【００８４】
データ構造体６００は、好ましくは、ストレージデバイス１０２によって記憶されたデータブロックのタイムスタンプを保持するために、各ストレージデバイス１０２によって保持される。データ構造体６００は、好ましくは、ＮＶ−ＲＡＭ１１６（図２）に記憶される。
【００８５】
以下のオペレーションは、データ構造体６００を操作するのに使用することができる。
【００８６】
ｆｉｎｄ−ｌａｒｇｅｓｔ（ｂａｓｅ）：ｂａｓｅ（ベース）の値が与えられると、データ構造体において、ｋｅｙ（キー）≦ｂａｓｅとなるような最大のｋｅｙを有するエントリが返される。このようなエントリがデータ構造体に存在しない場合、オペレーションは、ｂａｓｅよりも大きな最小のｋｅｙを有するエントリを返すことができる。本発明によれば、ｓｔａｒｔをこのオペレーションのｂａｓｅとして使用して、等しいｓｔａｒｔ又は次の最も低いｓｔａｒｔを有するタイムスタンプエントリを突き止めることができ、このようなエントリがデータ構造体に存在しない場合には、次の最も高いｓｔａｒｔを有するタイムスタンプエントリを突き止めることができる。このようなエントリは、データ構造体に挿入される新しいエントリと重なる可能性がある。エントリがデータ構造体に記憶されていない場合、このオペレーションは、好ましくは、リスト終了指示子を返す。
【００８７】
ｆｉｎｄ−ｎｅｘｔ（ｂａｓｅ）：ｂａｓｅの値が与えられると、ｋｅｙが、ｋｅｙ＞ｂａｓｅとなるような最小のｋｅｙであるエントリが返される。本発明によれば、ｓｔａｒｔをこのオペレーションのｂａｓｅとして使用して、次の最も高いｓｔａｒｔを有するタイムスタンプエントリを突き止めることができる。このようなエントリがデータ構造体に存在しない場合、このオペレーションは、好ましくは、リスト終了指示子を返す。
【００８８】
ｉｎｓｅｒｔ（ｅｎｔｒｙ）：データ構造体における、ｋｅｙによって特定されたロケーションにｅｎｔｒｙ（エントリ）が挿入される。本発明によれば、このオペレーションは、フォーム［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ］のエントリをデータ構造体に挿入するのに使用することができる。
【００８９】
ｒｅｐｌａｃｅ（ｅｎｔｒｙ）：キーによって特定されたエントリがｅｎｔｒｙと取り替えられる。本発明によれば、このオペレーションは、フォーム［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ］のエントリを異なるｅｎｄ及び／又はｔｉｍｅｓｔａｍｐを有するエントリと取り替えるのに使用することができる。
【００９０】
図７は、本発明の一実施の形態による、図６のデータ構造体を保持するための方法７００のフロー図を示している。この方法７００は、好ましくは、各ストレージデバイス１０２（図１〜図２）に含まれて、各ストレージデバイス１０２の関連したデータ構造体を保持するためのハードウェア及び／又はソフトウェアによって実施される。方法７００は、データ構造体６００をタイムスタンプに関して現在に維持するように、データ構造体６００のエントリを変更又は追加すると同時に、タイムスタンプは、本明細書で説明したように、書き込みオペレーション及び修復オペレーションを実行することに応答等して変更される。
【００９１】
書き込みオペレーション又は修復オペレーションが実行されると、一般に、データ構造体６００における或る範囲のデータブロックのタイムスタンプを更新して、データ構造体６００を現在に維持する必要がある。方法７００は、好ましくは、或るデータブロック又は或る範囲のデータブロックのタイムスタンプが更新されるごとに実行される。例えば、図４に関して上述したような書き込みオペレーションの初期化フェーズは、或る範囲のデータブロックのｌｏｇＴＳタイムスタンプの更新を必要とすることがある。したがって、フォーム［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］のエントリが、データ構造体６００に追加されることになる。ここで、ｓｔａｒｔは、影響を受けたブロックの範囲の開始を特定し、ｅｎｄは、その範囲の終了を特定し、ｔｉｍｅｓｔａｍｐはその範囲のデータブロックのｌｏｇＴＳタイムスタンプの新しい値を表す（これらブロックのｖａｌＴＳタイムスタンプの古い値もエントリに含めることができる）。したがって、図７を参照して、このフォームの新しいエントリが、例えば、書き込みオペレーションの第１フェーズの期間中にステップ７０２で生成される。この新しいエントリによって特定された範囲のブロックは、データ構造体６００にすでにある範囲のエントリの一部と重なる場合がある。したがって、この方法は、新しいタイムスタンプをデータ構造体６００に追加すると同時に、データ構造体６００のこれらエントリが、確実に、重なる範囲を有しないようにする。
【００９２】
ステップ７０４において、ステップ７０２で生成された新しいエントリからのｓｔａｒｔをｂａｓｅとして使用して、ｆｉｎｄ−ｌａｒｇｅｓｔ（ｂａｓｅ）オペレーションを実行することができる。上述したように、ｆｉｎｄ−ｌａｒｇｅｓｔ（ｂａｓｅ）オペレーションは、データ構造体において、等しいｓｔａｒｔ又は次の最も低いｓｔａｒｔを有するエントリを突き止め、そのようなエントリがデータ構造体にない場合には、このオペレーションは、次の最も高いｓｔａｒｔを有するタイムスタンプエントリを突き止める。エントリがステップ７０４で突き止められた場合、そのエントリは、本明細書では、「カレントエントリ（current entry）」と呼ばれ、［ｃｕｒ＿ｓｔａｒｔ，ｃｕｒ＿ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］として与えることができる。
【００９３】
図８Ａは、エントリがデータ構造体６００に追加される範囲８０２と、ステップ７０４で特定されたカレントエントリの範囲８０４との間に起こり得る関係を示している。図８の略図は、データブロックのすべてが、連続した順序で配列されているものと仮定する。追加されるエントリ［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］のデータブロックの範囲８０２は、図８Ａでは、位置「Ｓ」で開始し、位置「Ｅ」で終了するものとして示されている。ステップ７０４で特定されたカレントエントリ［ｃｕｒ＿ｓｔａｒｔ，ｃｕｒ＿ｅｎｄ，ｔｉｍｅｓｔａｍｐｓ（ｓ）］のデータブロックの範囲８０４は、図８Ａでは、位置「ＣＳ」で開始し、位置「ＣＥ」で終了するものとして示されている。図８Ａは、範囲８０２が範囲８０４よりも前にあり、それら範囲の間に重なりがないことを示している。範囲８０２と範囲８０４との間に起こり得る他の関係は、図８Ａ〜図８Ｈに示されている。
【００９４】
ステップ７０６において、カレントエントリがデータ構造体６００の最後のエントリであるかどうかについての判断を行うことができる。この判断は、例えば、カレントスタート（すなわち、「ｃｕｒ＿ｓｔａｒｔ」又は「ＣＳ」）が、データ構造体６００のリスト終了指示子に関連付けられているかどうかをチェックすることによって行うことができる。カレントエントリがデータ構造体６００の最後のエントリである場合、これは、この方法の停止条件に到達したことを示す。この停止条件は、データ構造体６００が最初にエントリを有しない場合に、ステップ７０６を最初に通過する間に起こり得る。この場合、ｆｉｎｄ−ｌａｒｇｅｓｔ（ｂａｓｅ）オペレーションは、リスト終了指示子を返す。そうでない場合、この停止条件は、その後にステップ７０６を通過する際に起こり得る。この場合、プログラムフローは、ステップ７４８で終了することができる。
【００９５】
これに加えて、ステップ７０６において、データ構造体６００に追加されるエントリのｓｔａｒｔが、その追加されるエントリのｅｎｄよりも小さいかどうかについての判断を行うことができる。これは、一般に、ステップ７０６を最初に通過する場合である。一方、その後にステップ７０６を通過する際には、方法７００の他のステップに従って実行された挿入オペレーション又は取り替えオペレーションが、ｓｔａｒｔがｅｎｄに等しくなるように範囲８０２を縮小させている場合がある（すなわち、すべてのデータブロックは処理されてデータ構造体に追加されている）。
【００９６】
ステップ７０６を最初に通過する際、データ構造体６００が、最初にエントリを有しない場合、プログラムフローはステップ７０８に移動する。ステップ７０８において、新しいエントリ［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］が木に挿入される。これは、ｉｎｓｅｒｔ（ｂａｓｅ）オペレーションを使用して行うことができる。次に、プログラムフローは、ステップ７１０で終了することができる。
【００９７】
一方、ステップ７０６を最初に通過する際に、データ構造体が１つ又は複数のエントリを有する場合、プログラムフローはステップ７１２に移動する。ステップ７１２において、ｃｕｒ＿ｓｔａｒｔがｓｔａｒｔよりも大きいかどうかについての判断が行われる。図８Ａ、図８Ｂ、及び図８Ｃは、この条件を満たす、範囲８０２と範囲８０４との間の関係を示している。この条件が満たされる場合、プログラムフローはステップ７１４に移動する。ステップ７１４において、ｅｎｄがｃｕｒ＿ｓｔａｒｔ以下であるかどうかについての判断が行われる。この条件は図８Ａによって満たされる。したがって、範囲８０２及び範囲８０４は、図８Ａに示すようなものとなり、それらの範囲の間に重なりはなく、新しいエントリは、ステップ７１６で、フォーム：ｉｎｓｅｒｔ［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］のｉｎｓｅｒｔオペレーションを使用して木６００に挿入することができる。次に、プログラムフローは、ステップ７１８で終了することができる。
【００９８】
ステップ７１４の条件が満たされない場合、範囲８０２と範囲８０４との間の関係は図８Ｂ又は図８Ｃに示すようなものとなる。この場合、範囲８０２と範囲８０４との間に重なりがある。図８Ｂ及び図８Ｃでは、「Ｓ」と「ＣＳ」との間に、新しいタイムスタンプが入ることになる範囲が存在することに留意されたい。したがって、ステップ７２０において、この範囲は、フォーム：ｉｎｓｅｒｔ［ｓｔａｒｔ，ｃｕｒ＿ｓｔａｒｔ，ｔｉｍｅｓｔａｍｐ（ｓ）］のｉｎｓｅｒｔオペレーションを使用してデータ構造体６００に挿入することができる。この場合、「Ｓ」から「ＣＳ」までの範囲はデータ構造体６００に入れられているので、ｓｔａｒｔは、ステップ７２２において、ｃｕｒ＿ｓｔａｒｔに等しく設定することができる。したがって、ステップ７２０及びステップ７２２を実行した後、図８Ｂに示す関係は、図８Ｅに示す関係に変換される。同様に、図８Ｃに示す関係も、図８Ｄに示す関係に変換される。
【００９９】
ステップ７１２において、ｃｕｒ＿ｓｔａｒｔがｓｔａｒｔよりも大きいかどうかについての判断が行われたことを思い出されたい。この条件が満たされない場合、範囲８０２と範囲８０４との間の関係は、図８Ｄ〜図８Ｈの１つのように示すことができる。したがって、ステップ７１２又はステップ７２２から、プログラムフローはステップ７２４に移動し、ステップ７２４において、ｃｕｒ＿ｓｔａｒｔがｓｔａｒｔに等しいかどうかについての判断を行うことができる。この条件は、図８Ｄ及び図８Ｅでは満たされる。この場合、プログラムフローは状態７２６に移動することができ、状態７２６において、ｅｎｄがｃｕｒ＿ｅｎｄ以上であるかどうかについてのさらなる判断を行うことができる。ｅｎｄがｃｕｒ＿ｅｎｄよりも小さい場合、この状況は、図８Ｅのように示すことができる。この場合、「Ｓ」と「Ｅ」との間の範囲のタイムスタンプは、ステップ７２８において、フォーム：ｒｅｐｌａｃｅ［ｃｕｒ＿ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］のｒｅｐｌａｃｅオペレーションを使用することにより取り替えることができる。この場合、ｓｔａｒｔがｃｕｒ＿ｓｔａｒｔに等しいので、代替的に、次のフォーム：ｒｅｐｌａｃｅ［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］も使用することができる。次に、ステップ７３０において、フォーム：ｉｎｓｅｒｔ［ｅｎｄ，ｃｕｒ＿ｅｎｄ，ｃｕｒ＿ｔｉｍｅｓｔａｍｐ（ｓ）］のｉｎｓｅｒｔオペレーションを使用して、ステップ７３２において、「Ｅ」と「ＣＥ」との間の範囲をデータ構造体６００に挿入することができる。次に、プログラムフローは、ステップ７３２で終了することができる。
【０１００】
ステップ７２４において、ｃｕｒ＿ｓｔａｒｔがｓｔａｒｔに等しいかどうかについての判断が行われたことを思い出されたい。この条件が満たされない場合、範囲８０２と範囲８０４との間の関係は、図８Ｆ、図８Ｇ、又は図８Ｈのように示すことができる。次に、ステップ７３４において、ｃｕｒ＿ｅｎｄがｓｔａｒｔ以下であるかどうかについての判断を行うことができる。この条件が満たされる場合、範囲８０２と範囲８０４との間の関係は、図８Ｇ又は図８Ｈのように示すことができる。次に、ステップ７３６において、ｅｎｄがｃｕｒ＿ｅｎｄ以上であるかどうかについての判断を行うことができる。この条件が満たされない場合、範囲８０２と範囲８０４との間の関係は、図８Ｈにように示すことができる。この場合、「ＣＳ」と「Ｓ」との間の範囲のタイムスタンプは、ステップ７３８において、フォーム：ｒｅｐｌａｃｅ［ｃｕｒ＿ｓｔａｒｔ，ｓｔａｒｔ，ｃｕｒ＿ｔｉｍｅｓｔａｍｐ（ｓ）］のｒｅｐｌａｃｅオペレーションを使用して更新することができる。そして、「Ｅ」と「ＣＥ」との間の範囲のタイムスタンプは、ステップ７４０において、フォーム：ｉｎｓｅｒｔ［ｅｎｄ，ｃｕｒ＿ｅｎｄ，ｃｕｒ＿ｔｉｍｅｓｔａｍｐ（ｓ）］のｒｅｐｌａｃｅオペレーションを使用して更新することができる。「Ｓ」と「Ｅ」との間の範囲については、フォーム：ｉｎｓｅｒｔ［ｓｔａｒｔ，ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］のｒｅｐｌａｃｅオペレーションをステップ７４２で実行することができる。次に、プログラムフローは、ステップ７４４で終了することができる。
【０１０１】
ステップ７３４において、ｃｕｒ＿ｅｎｄがｓｔａｒｔ以下であるかどうかについての判断が行われたことを思い出されたい。この条件が満たされる場合、範囲８０２と範囲８０４との間の関係は、図８Ｆのように示すことができる。この場合、データ構造体６００の別の既存のエントリが範囲８０２と重なる可能性がある。より詳細には、ｃｕｒ＿ｅｎｄがｅｎｄの前に現れるので、別のエントリがｓｔａｒｔの後に開始して範囲８０２と重なる範囲を有する可能性がある。このようなエントリは、ステップ７０４のｆｉｎｄ−ｌａｒｇｅｓｔ（ｂａｓｅ）オペレーションを使用して見つけられていないことになる。例えば、このようなエントリは、図８Ｂ又は図８Ｃに示すような範囲８０４を有する場合がある。したがって、このようなエントリを特定するために、ステップ７４６において、ｂａｓｅとしてｓｔａｒｔを使用してｆｉｎｄ−ｎｅｘｔ（ｂａｓｅ）オペレーションを実行することができる。この新しいエントリは、その後、［ｃｕｒ＿ｓｔａｒｔ，ｃｕｒ＿ｅｎｄ，ｃｕｒ＿ｔｉｍｅｓｔａｍｐ（ｓ）］の代わりとなってさらに処理される。ステップ７４６から、プログラムフローはステップ７０６に戻り、ステップ７０６において、方法７００は、基本的には、この新しく特定されたエントリに対して繰り返される。ステップ７０６において、リスト終了指示子が返される場合、このことは、リストの終了（「もはやデータは存在しない」状況）に到達しており、このような重なるエントリが存在しないことを示すことに留意されたい。したがって、プログラムフローは、ステップ７４８で終了することができる。
【０１０２】
また、ステップ７２６において、ｅｎｄがｃｕｒ＿ｅｎｄ以上であるかどうかについての判断が行われたことも思い出されたい。この条件が満たされる場合、範囲８０２及び範囲８０４は、図８Ｄのように示すことができる。この場合、「ＣＥ」から「Ｅ」への範囲のタイムスタンプは、ステップ７５０において、フォーム：ｒｅｐｌａｃｅ［ｃｕｒ＿ｓｔａｒｔ，ｃｕｒ＿ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］のｒｅｐａｌｃｅオペレーションを実行することにより更新することができる。次に、「ＣＥ」から「Ｅ」への範囲が残っているので、ｓｔａｒｔは、ステップ７５２でｃｕｒ＿ｅｎｄに等しく設定することができる。次に、プログラムフローは、ステップ７４６に移動することができる。ステップ７４６において、ｆｉｎｄ−ｎｅｘｔ（ｂａｓｅ）オペレーションを使用して、他のいずれかのエントリが、ｓｔａｒｔとｅｎｄとの間に残っている範囲と重なるかどうかを判断することができる。
【０１０３】
また、ステップ７３６において、ｃｕｒ＿ｅｎｄがｓｔａｒｔ以下であるかどうかについての判断が行われたことを思い出されたい。この条件が満たされる場合、範囲８０２及び範囲８０４は、図８Ｇのように示すことができる。この場合、「ＣＳ」から「Ｓ」への範囲のタイムスタンプは、ステップ７５４において、フォーム：ｒｅｐｌａｃｅ［ｃｕｒ＿ｓｔａｒｔ，ｓｔａｒｔ，ｃｕｒ＿ｔｉｍｅｓｔａｍｐ（ｓ）］のｒｅｐｌａｃｅオペレーションを実行することにより更新することができる。「Ｓ」から「ＣＥ」への範囲のタイムスタンプは、ステップ７５６において、フォーム：ｉｎｓｅｒｔ［ｓｔａｒｔ，ｃｕｒ＿ｅｎｄ，ｔｉｍｅｓｔａｍｐ（ｓ）］のｉｎｓｅｒｔオペレーションを実行することにより更新することができる。次に、「ＣＥ」から「Ｅ」への範囲が残っているので、ｓｔａｒｔは、ステップ７５８でｃｕｒ＿ｅｎｄに等しく設定することができる。次に、プログラムフローは、ステップ７４６に移動することができ、ステップ７４６において、ｆｉｎｄ−ｎｅｘｔ（ｂａｓｅ）オペレーションを使用して、他のいずれかのエントリが、ｓｔａｒｔとｅｎｄとの間に残っている範囲と重なるかどうかを判断することができる。
【０１０４】
このプロセスは、プログラムが終了状態７１０、７１８、７３２、７４４、又は７４８の１つで終了するまで続く。要約すると、図７の方法は、追加されるエントリと重なる可能性のある、データ構造体のすべての既存のレコードを特定する。重なりがある場合、更新されたデータブロックの新しいタイムスタンプが記録され、既存のデータブロックの既存のタイムスタンプが維持されるように、既存のレコードが分割される。このプロセスは、データブロックの範囲が重ならないようにデータ構造体６００のエントリを維持する。
【０１０５】
このように、冗長データを記憶するための複数のストレージデバイスを有するコンピュータシステムのタイムスタンプを管理するための技法が説明された。
【０１０６】
図１のデバイス１０２等のストレージデバイスにデータを割り当てることが望まれる場合がある。したがって、本発明の別の態様によれば、冗長データを記憶するための複数のストレージデバイスを有するコンピュータシステムにおいてデータを割り当てるための技法が提供される。本明細書では、データ「ストア」は、アプリケーション（例えば、ソフトウェアアプリケーション）に提供される、論理的に連続したストレージブロック、ストライプ状のデータストレージ、または連鎖状のデータストレージ等のデータストレージ空間とすることができる。実際には、ストアは、データブロック等のデータ要素の挿入、除去、又は操作を行うことができる論理ボリュームとして実施することができる。
【０１０７】
図９は、本発明の一実施の形態による、ストレージデバイスノードにデータストアを割り当てるための方法８００のフロー図を示している。この方法８００は、図１のコンピュータシステム１００内で実施することができる。例えば、サーバ１０６は、方法８００を実行するように適切に構成されたソフトウェア及び／又はハードウェアを含むことができる。しかしながら、方法８００は、ストレージデバイス１０２又はサーバ１０６の１つ又は複数で動作する分散アプリケーションによる等、他の場所で実行することもできるし、方法８００の少なくとも一部を手動で実行することもできることは明らかであろう。さらに、サーバ１０６の１つは、方法８００を実行して、システム１００内のロケーションへのデータの割り当ても制御するメタサーバとして指定することもできる。
【０１０８】
最初に、システム１００に割り当てられるデータストアが、より小さな要素に分割される。例えば、ステップ８０２において、システム１００に割り当てられるデータストアは、それぞれ、「セグメント」と呼ばれる複数の連続した部分に分割することができる。各セグメントは、１セグメントあたり８ギガバイト等の所定のデータ容量を有することができる。ただし、別の容量又は異なる容量も選択できることは明らかであろう。
【０１０９】
次に、ステップ８０４において、セグメントをグループに配置することができる。ここで、各グループは複数のセグメントを含む。グループは、それぞれ、１つのグループあたり１２８個のセグメント等の所定の個数のセグメントを含むことができる。ただし、別の個数又は異なる個数のセグメントを各グループに割り当てることができることは明らかであろう。
【０１１０】
ステップ８０４において、セグメントを、ストア内におけるその位置に従って、順次、グループにすることができる。代替的に、負荷バランスの考慮に基づいて、セグメントをグループに割り当てることもできる。例えば、予想されたデータスループット（すなわち、単位時間あたりの総アクセス）を各ストアについて知ることができる。ストアの各セグメントは、ストア及びセグメントの相対的な容量に比例したスループットを有するものと仮定することができる。次に、各グループが他のグループのスループットと等しいスループットを有すると予想されるように、セグメントをグループに割り当てることができる。
【０１１１】
ステップ８０６において、１つのグループが選択される。順番に又はランダムにグループを選択することができる（本明細書では、「ランダム」選択は、擬似ランダム選択も包含する）。ステップ８０８において、選択されたグループに対応できるように利用可能な十分な資源を有するストレージデバイスノード１０２（図１）が特定される。少なくとも、これは、十分なストレージ容量を有するノード１０２を特定することを含むが、他のパラメータに基づくこともできる。例えば、これは、利用可能な十分な量のデータスループット容量等の性能パラメータを有するノード１０２を特定することを含むことができる。また、これは、可用性要件及び信頼性要件を満たすノードを特定することも含むことができる。例えば、仕事負荷は、Ｍ個のすべてのノードが１００万時間を超える平均故障間隔（ＭＴＴＦ）を個々に有することを必要とすることもあるし、Ｍ個のノードが物理的に別々のラックに配置されることを必要とすることもある。好ましくは、容量要件及び場合によっては追加要件を満たすこのようなすべてのデバイス１０２が、ステップ８０８で特定される。
【０１１２】
本明細書で説明したように、データは、システム１００に冗長に記憶される。例えば、複製の個数がＭに等しい場合、各データブロックの３つ又は４つ以上の複製がシステム１００に記憶される。ステップ８１０において、ステップ８０６で選択されたグループのコピーに対応できるように、少なくともＭ個のノード１０２がステップ８０８で特定されたかどうかについての判断が行われる。少なくともＭ個のノード１０２が特定されない場合、このことは、グループが小さくされない限り、グループのデータの必要なＭ個の複製をシステム１００の異なるノード１０２に割り当てることができないことを意味する。各グループは複数のセグメントを含むので、グループは、一般に、より小さなグループに分割可能である。したがって、ステップ８１０の判断が否定的である場合、グループをさらに分割して、その結果生成されたグループが前よりも低い要件を有するようにすることによって、ステップ８０４を繰り返すことができる。これは、グループを２つ又は３つ以上のより小さなグループに分割することによって行うこともできるし、グループのセグメントの１つ又は複数を異なるグループに再割り当てすることによって行うこともできる。その後、ステップ８０８の次の通過の際には、そのグループに対応できるノード１０２が前よりも多く存在することを予想することができる。このプロセスは、グループに対応できる少なくともＭ個のノード１０２が見つかるまで繰り返される。
【０１１３】
次に、ステップ８１２において、グループがＭ個のノード１０２に割り当てられる。Ｍ個よりも多くのノードがステップ８０８で特定された場合、特定されたノード１０２のサブセットがそのグループ用にステップ８１２で選択される。この選択は、好ましくは、ランダムに行われる。この選択をグループのすべてについてランダムに行うことによって、グループのすべての割り当てがデバイス１０２間でバランスされると予想され、それによって、ストレージオペレーションが少数のデバイス１０２に集中する「ホットスポット」の発生が低減される。
【０１１４】
グループが割り当てられると、好ましくは、データストアのノード１０２への割り当ての経過を追跡するためのデータロケーションテーブルへのエントリが作成される。図１０は、本発明の一実施の形態による、ストレージデバイスノード１０２へのデータの割り当てを追跡するための例示のテーブル９００を示している。このテーブル９００は、例えば、サーバ１０６の１つ又は複数によって保持することができる。
【０１１５】
図１０に示すように、テーブル９００は、（例えば、データブロックによる）データの識別情報及び（例えば、ストレージデバイスノード１０２による）そのロケーションを含む。例示のエントリ９０２は、或るグループがデータブロック＃１〜１８０を含み、ノード＃３、ノード＃７、及びノード＃１２によって冗長に記憶されるように割り当てられていることを示す。同様に、例示のエントリ９０４は、データブロック＃１８１〜２５７を含むグループがノード＃１、ノード＃４、及びノード＃９に割り当てられることを示す。このように、テーブル９００は、システム１００のデータのすべてのロケーションを示す。これらの例では、データは、そのブロック識別情報によって特定される。しかしながら、グループの識別情報又はセグメントの識別情報による等、別の方法でデータを特定できることは明らかであろう。
【０１１６】
ステップ８１４において、グループのすべてがシステム１００に割り当てられたかどうかについての判断が行われる。割り当てられていない場合、ステップ８０６に戻って、セグメントの次のグループを選択することにより、上述したプロセスが繰り返される。次に、ステップ８０８において、この次のグループに対応するためのノードが特定され、少なくともＭ個のノードがステップ８１０で特定されると、このグループが、ステップ８１２において、システム１００の選択されたノード１０２に割り当てられる。グループのすべてがこのように割り当てられると、プログラムフローは、ステップ８１６で終了することができる。
【０１１７】
このように、システム１００のストレージデバイスノード１０２にデータを割り当てるための技法が説明された。要約すると、この技法は、ノード１０２がデータの集合（例えば、セグメントのグループ）に対応できるかどうかを判断する資格を当該ノード１０２に与えること、及び、次に、資格を与えられたそれらノード１０２の中からランダムに選択を行うことを含む。この技法は、（ノードに資格を与えることによる）決定論的な割り当ての態様、及び、（資格を与えられたノードの中からランダムに選択することによる）ランダムな割り当ての態様を組み合わせたものである。この決定論的な態様によって、割り当てが行われる前に、ノードに割り当ての資格が適切に与えられることが確保され、これによって、データを再割り当てしなければならない可能性が回避される。上述したように、ランダムな態様によって、割り当てがバランスされることが予想される。本発明のこの態様は、このようにして、単に決定論的又は単にランダムのいずれかである従来の技法と対称を成す。
【０１１８】
図１１は、本発明の一実施の形態による、新しいストレージデバイスノードを追加して、この新しいノードにデータを割り当てるための方法１０００のフロー図を示している。この方法１０００は、例えば、グループが（例えば、図９の方法８００を使用して）システム１００に割り当てられた後に実行することができる。或る時点において、容量又は性能を増加させる等のために、ノード１０２をシステム１００に追加することが望まれる場合がある。図９の方法８００と同様に、方法１０００も、図１のシステム１００内においてハードウェア及び／又はソフトウェアによって実行することができる。ただし、一部は手動で実行することができる。
【０１１９】
ステップ１００２において、ストレージデバイスノード１０２が、図１のシステム１００に新しく追加される。次に、ステップ１００４において、システム１００に以前から存在する重い負荷を有するノードが選択される。例えば、ステップ１００４で選択されたノードは、ノード１０２のすべての中から最も高い利用率を有するものである場合がある。この目的のために、各ノード１０２の利用率が、そのノードにおける特定のパラメータの利用可能な総レベルと比較した、当該特定のパラメータの量の比として求められ、この利用率が、ノードに現在割り当てられているデータにサービスを提供するための仕事負荷によって消費される。例えば、ノードが合計１００単位のストレージ容量を有し、そのノードへのデータの現在の割り当てがそのストレージ容量の９０単位を消費している場合、そのノードは、９０パーセント（９０％）の利用率を有すると言うことができる。システム１００の他のノード１０２が、９０パーセントよりも大きな容量利用率を有しない場合、９０パーセントの利用率を有するノードがステップ１００６で選択される。しかしながら、各ノードの負荷の量は、容量以外のパラメータ（例えば、スループット）に基づいて求めることもでき、負荷の量は、複数のパラメータの組み合わせ（例えば、複数のパラメータの利用率を統計的に平均化することにより）に基づくこともできることは明らかであろう。
【０１２０】
ステップ１００８において、ステップ１００６で選択された既存のノードに割り当てられたセグメントのグループが選択されて、新しく追加されたノードに再割り当てされる。これは、例えば、既存のノードに割り当てられた最も大きなグループを選択することによって行うことができる。ただし、別の判定基準に基づいてグループを選択することもでき、スループット等の、最も高い１つ又は複数の性能要件を有するグループ等を選択することもできる。グループは、ステップ１００８において、新しく追加されたノードにおけるストレージ容量の可用性又は他の性能パラメータの可用性に基づいて選択することができる。例えば、新しく追加されたノードが５０単位のストレージ容量を有する場合、５０単位よりも少ない容量を必要とするグループがステップ１００６で選択される。これに加えて、テーブル９００（図１０）が、好ましくは、この割り当てを反映するように更新される。
【０１２１】
次に、ステップ１０１０において、新しく追加されたノードが現在十分な負荷を有するかどうかについての判断が行われる。例えば、ステップ１００４で各既存のノードについて求められた負荷の量（例えば、容量利用率又はパラメータの組み合わせの利用率）を、新しく追加されたノードについて求めることができる。次に、この負荷は、他のすべてのノードの平均（例えば、統計的平均又は中央値）の負荷と比較することができる。新しく追加されたノードの負荷が少なくとも平均の負荷と同程度の大きさである場合、ステップ１０１０において、新しく追加されたノードは、十分な負荷を有するとみなすことができる。しかしながら、新しく追加されたノードの負荷が十分であることは、他の方法で判断することもできる。例えば、その負荷は、既存のノードの最低負荷及び最高負荷によって境界が定められた範囲と比較することができ、その負荷がこの範囲内に入る場合には、その負荷が十分であるとみなされるようになる。
【０１２２】
好ましくは、既存のノードの負荷は、新しく追加されたノードのグループの再割り当てを考慮して求められる。したがって、グループが、既存のノードから再割り当てされる場合、その負荷は一般に削減される。この削減された負荷を考慮するために、次に、このノードの負荷を再計算することができる。
【０１２３】
ステップ１０１０で求められる、新しく追加されたノードの負荷が、ストレージ容量以外のパラメータに基づく場合、その総ストレージ容量の所定の部分（例えば、９０パーセント）を超える、新しく追加されたノードも、そのノードに割り当てられたデータに必要なストレージ容量の十分な負荷を有するとみなされる。
例えば、新しく追加されたノードのスループット利用率が既存のノードのいずれかよりも低いが、そのストレージ容量利用率が９０パーセントを超える場合、そのノードは、十分に負荷を有するとみなされる。
【０１２４】
新しく追加されたノードがステップ１０１０で十分に負荷を有しないと判断された場合、重い負荷を有するノードを特定するステップ（ステップ１００４）、重い負荷を有するノードにおいてデータを選択するステップ（ステップ１００６）、及び選択したデータを再割り当てするステップ（ステップ１００８）は、新しく追加されたノードが十分な負荷を有するまで繰り返される。グループが再割り当てされたどのノードの削減された負荷も、好ましくは、新しく追加されたノードにそのグループが再割り当てされた後に考慮されるので、ステップ１００４の各通過の際に特定された既存のノードは、一般に、ステップ１００４の前の通過の際に特定されたノードと異なる。
【０１２５】
新しく追加されたノードが十分な負荷を有すると、図１１の方法１０００は、ステップ１０１２で終了することができる。このように、ストレージデバイスノードをシステム１００に追加して、新しく追加されたノードにデータを再割り当てするための技法が説明された。
【０１２６】
或る時点において、システム１００のノードからデータを除去することが望まれる場合がある。例えば、ノードが障害を起こすこともあるし、時間の経過に伴い時代遅れになることもあり、したがって、ノードを休止させるか、又は、除去することが必要となる場合がある。図１２は、本発明の一実施の形態による、ストレージデバイスノードからデータを除去するための方法１１００のフロー図を示している。図９の方法８００及び図１１の方法１０００と同様に、方法１１００も、図１のシステム１００内においてハードウェア及び／又はソフトウェアによって実行することができる。ただし、一部は手動で実行することができる。
【０１２７】
ステップ１１０２において、システム１００に存在するノード１０２が除去のため選択される。ステップ１１０４において、ステップ１１０２で選択されたノードに記憶されたセグメントのグループが選択されて、別の既存のノードに再割り当てされる。次に、ステップ１１０６において、選択されたグループに対応できるストレージデバイスノード１０２が特定される。図９のステップ８０８と同様に、少なくとも、これは、十分なストレージ容量を有するノード１０２を特定することを含むが、他のパラメータが十分であることに基づくこともできる。例えば、これは、データスループット容量等の性能パラメータの利用可能な十分な量を有するノード１０２を特定することを含むことができる。好ましくは、容量要件、及び、場合によっては追加要件を満たすこのようなすべてのデバイス１０２がステップ１１０６で特定される。
【０１２８】
ステップ１１０８において、少なくとも１つのノードがステップ１１０６で特定されたかどうかについての判断が行われる。特定されていない場合、このことは、グループが小さくされない限り、グループのデータをシステム１００の既存のノード１０２に割り当てることができないことを意味する。上述したように、各グループは複数のセグメントを含むので、グループは、一般に、より小さなグループに分割可能である。したがって、ステップ１１０８の判断が否定的である場合、ステップ１１１０において、グループを２つ又は３つ以上のより小さなグループに分割することができ、その結果生成されたグループが前よりも低い要件を有するようにされる。その後、これら小さなグループのそれぞれについてのステップ１１０６の次の通過の際には、グループに対応できるノード１０２が前よりも多くなっていることを予想することができる。このプロセスは、グループに対応できる少なくとも１つのノードが見つかるまで繰り返される。
【０１２９】
次に、ステップ１１１２において、１つのノードがステップ１１０６で特定された場合、グループは、その特定されたノードに移動される。２つ以上のノードが特定された場合、特定されたノードの中からノードの１つが選択される。方法９００のステップ８１２と同様に、この選択は、好ましくは、ランダムに行われる。これに加えて、テーブル９００（図１０）が、好ましくは、この割り当てを反映するように更新される。
【０１３０】
ステップ１１１４において、除去されるノードにおけるグループのすべてが再割り当てされたかどうかについての判断が行われる。残っているグループがある場合、グループを選択するステップ（ステップ１１０４）、どのノード１０２がグループに対応できるかを特定するステップ（ステップ１１０６）、必要に応じてグループを分割するステップ（ステップ１１１０）、及びグループを再割り当てするステップ（ステップ１１１２）を、グループのすべてが再割り当てされるまで繰り返すことができる。
【０１３１】
グループのすべてが再割り当てされると、必要に応じて、ステップ１１１６でノードを除去することができる。次に、プログラムフローはステップ１１１８で終了することができる。このように、システム１００のストレージデバイスノードからデータを除去して、そのノードから既存のノードへデータを再割り当てするための技法が説明された。
【０１３２】
本明細書で説明したデータ割り当てのための技法に対して変更を行えることは明らかであろう。例えば、説明したように、図９のＭ個のノードの組及び図１２のノードを選択することは、基本的に、仕事負荷の要件を満たすすべてのノードを選択すること、次いで、これらのノードから必要な個数のノード（すなわち、図９ではＭ個のノードの組、又は、図１２ではノード）を選択することを含む。代替的に、複数のノード（必要な個数又はそれより多くの個数）をランダムに選択することもできる。次に、それらのノードがセグメントのグループの要件を満たすかどうかについての判断を行うことができる。満たす場合には、割り当てを行うことができる（２つ以上の割り当てが可能な場合には、ランダム選択を使用して、それら割り当ての中から選択することができる）。満たさない場合には、要件を満たすノードが特定されるまで、ランダムに選択するステップ、及び、判断するステップを繰り返すことができる。所定の回数のサイクルの後に成功しない場合には、グループを分割して、プロセスを繰り返すことができる。さらに、これらの技法の組み合わせを実施することもできる。例えば、要件のサブセットを満たすすべてのノードを選択することができる。次に、すべての要件を満たす組が見つかるまで、これらの中からＭ個のノードが、反復的且つランダムにこれらのノードから選択される。
【０１３３】
上記は、本発明の特定の実施の形態に関してのものであるが、本発明の原理及び精神から逸脱することなく、これらの実施の形態において変更を行えることが当業者には理解されよう。本発明の範囲は、添付の特許請求の範囲によって規定される。
【図面の簡単な説明】
【０１３４】
【図１】本発明の一実施の形態による、複数の冗長ストレージデバイスノードを含む例示のストレージシステムである。
【図２】本発明の一実施の形態による、図１のストレージシステムで使用される例示のストレージデバイスである。
【図３】本発明の一実施の形態による、読み出しオペレーションを実行するための例示のタイミング図である。
【図４】本発明の一実施の形態による、書き込みオペレーションを実行するための例示のタイミング図である。
【図５】本発明の一実施の形態による、データ修復オペレーションを実行するための例示のタイミング図である。
【図６】本発明の一実施の形態による、タイムスタンプが記憶されるデータ構造体の例示の部分である。
【図７Ａ】本発明の一実施の形態による、図６のデータ構造体を保持するための方法のフロー図である。
【図７Ｂ】本発明の一実施の形態による、図６のデータ構造体を保持するための方法のフロー図である。
【図７Ｃ】本発明の一実施の形態による、図６のデータ構造体を保持するための方法のフロー図である。
【図８Ａ】タイムスタンプエントリがデータ構造体に追加される範囲と既存のエントリの範囲との間に起こり得るさまざまな関係を示す図である。
【図８Ｂ】タイムスタンプエントリがデータ構造体に追加される範囲と既存のエントリの範囲との間に起こり得るさまざまな関係を示す図である。
【図８Ｃ】タイムスタンプエントリがデータ構造体に追加される範囲と既存のエントリの範囲との間に起こり得るさまざまな関係を示す図である。
【図８Ｄ】タイムスタンプエントリがデータ構造体に追加される範囲と既存のエントリの範囲との間に起こり得るさまざまな関係を示す図である。
【図８Ｅ】タイムスタンプエントリがデータ構造体に追加される範囲と既存のエントリの範囲との間に起こり得るさまざまな関係を示す図である。
【図８Ｆ】タイムスタンプエントリがデータ構造体に追加される範囲と既存のエントリの範囲との間に起こり得るさまざまな関係を示す図である。
【図８Ｇ】タイムスタンプエントリがデータ構造体に追加される範囲と既存のエントリの範囲との間に起こり得るさまざまな関係を示す図である。
【図８Ｈ】タイムスタンプエントリがデータ構造体に追加される範囲と既存のエントリの範囲との間に起こり得るさまざまな関係を示す図である。
【図９】本発明の一実施の形態による、ストレージデバイスノードにデータストアを割り当てるための方法のフロー図である。
【図１０】本発明の一実施の形態による、ストレージデバイスノードへのデータの割り当てを追跡するための例示のテーブルである。
【図１１】本発明の一実施の形態による、新しいストレージデバイスノードを追加して、その新しいノードにデータを割り当てるための方法のフロー図である。
【図１２】本発明の一実施の形態による、ストレージデバイスノードを除去するための方法のフロー図である。
【符号の説明】
【０１３５】
１００・・・ストレージシステム
１０２・・・ストレージデバイス
１０４，１０８・・・通信媒体
１０６・・・クライアント
１１０・・・インターフェース
１１２・・・ＣＰＵ
１１４・・・マスストレージ
１１６・・・メモリ
３０２，３０４，３０６・・・ストレージデバイス
３０８，３１０，３１２，３１４，３１６，３１８・・・メッセージ
４０２，４０４，４０６・・・ストレージデバイス
４０８，４１０，４１２，４１４，４１６，４１８，４２０，４２２，４２４，４２６・・・メッセージ
５０２，５０４，５０６・・・ストレージデバイス
５０８，５１０，５１２，５１４，５１６，５１８，５２０，５２２・・・メッセージ
６００・・・データ構造体
８０２，８０４・・・範囲
９００・・・テーブル
９０２・・・エントリ
【図１】
2007520783.tif 000003
【図２】
2007520783.tif 000004
【図３】
2007520783.tif 000005
【図４】
2007520783.tif 000006
【図５】
2007520783.tif 000007
【図６】
2007520783.tif 000008
【図７Ａ】
2007520783.tif 000009
【図７Ｂ】
2007520783.tif 000010
【図７Ｃ】
2007520783.tif 000011
【図８Ａ】
2007520783.tif 000012
【図８Ｂ】
2007520783.tif 000013
【図８Ｃ】
2007520783.tif 000014
【図８Ｄ】
2007520783.tif 000015
【図８Ｅ】
2007520783.tif 000016
【図８Ｆ】
2007520783.tif 000017
【図８Ｇ】
2007520783.tif 000018
【図８Ｈ】
2007520783.tif 000019
【図９】
2007520783.tif 000020
【図１０】
2007520783.tif 000021
【図１１】
2007520783.tif 000022
【図１２】
2007520783.tif 000023