(57)【特許請求の範囲】
【請求項１】
記憶装置に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶するデータ書き込み手段と、
前記記憶装置に記憶された同一の記憶データのうち、最新の記憶データを特定するデータ特定手段と、を備え、
前記データ書き込み手段は、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置に記憶し、
前記データ特定手段は、
前記記憶装置内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定するよう構成されると共に、
前記記憶装置内に前記更新情報が存在した最大の２ｉの値を第一更新情報とすると共に、２ｉ＋１の値を第二更新情報とし、
前記記憶装置内に、前記第一更新情報と前記第二更新情報との中間値に対応する前記更新情報が存在するか否かを調べる更新情報検索処理を行うと共に、
前記記憶装置内に、前記中間値に対応する前記更新情報が存在した場合は当該中間値を前記第一更新情報とし、前記中間値に対応する前記更新情報が存在しない場合には当該中間値を前記第二更新情報とする中間値置き換え処理を行い、
前記更新情報検索処理と前記中間値置き換え処理とを繰り返し実行して、前記記憶装置内に存在する前記更新情報の最大値を特定するよう構成されており、
さらに、
最新ではない前記記憶データを構成する前記実データ及び当該実データに関連付けられた前記更新情報を前記記憶装置内から削除するデータ削除手段を備え、
前記データ特定手段は、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報を非削除対象更新情報として特定し、
前記データ削除手段は、前記非削除対象更新情報として特定された前記更新情報を前記記憶装置内から削除する情報から除外する、
ストレージ装置。
【請求項２】
請求項１に記載のストレージ装置であって、
前記データ特定手段は、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報と、前記中間値とされた前記更新情報と、特定された最大値の前記更新情報と、を前記非削除対象更新情報として特定する、
ストレージ装置。
【請求項３】
請求項１又は２に記載のストレージ装置であって、
前記データ特定手段は、前記記憶装置内に存在する前記更新情報の最大値よりも小さい値の前記更新情報に関連付けられた前記実データにて構成される記憶データがアクセスされている場合に、当該アクセスされている記憶データを構成する前記実データに関連付けられている前記更新情報であるアクセス対象更新情報と、当該アクセス対象更新情報を前記データ特定手段にて前記更新情報の最大値として特定する場合に検索され前記非削除対象更新情報して特定される前記更新情報とを、当該非削除対象更新情報に含める、
ストレージ装置。
【請求項４】
請求項３に記載のストレージ装置であって、
前記データ特定手段は、前記記憶装置内に存在する前記更新情報の最大値よりも小さく、前記アクセス対象更新情報の値よりも大きい値の前記更新情報を、前記非削除対象更新情報に含める、
ストレージ装置。
【請求項５】
請求項１乃至４のいずれかに記載のストレージ装置であって、
前記データ削除手段は、前記非削除対象更新情報として特定された前記更新情報に関連付けられた前記実データを、前記記憶装置内から削除する、
ストレージ装置。
【請求項６】
請求項１乃至５のいずれかに記載のストレージ装置であって、
前記データ書き込み手段は、前記更新情報を、同一の前記記憶データを特定するデータ特定情報に関連付けて記憶する、
ストレージ装置。
【請求項７】
請求項６に記載のストレージ装置であって、
前記データ書き込み手段は、
前記記憶データを複数の実データに分割して前記記憶装置に記憶すると共に、当該各実データを参照する各参照データと、前記記憶データを構成する複数の実データを参照する複数の前記参照データにアクセス可能な前記データ特定情報と、を記憶し、
前記記憶データを更新する際に、前記記憶装置に既に記憶されている実データと同一内容の他の実データを記憶装置に記憶する場合には、当該記憶装置に既に記憶されている実データを、当該実データを参照する前記参照データを用いて前記他の実データとして参照させて当該他の実データを記憶し、前記記憶装置に記憶されていない実データを記憶する場合には、当該実データを記憶装置に新たに記憶し、
前記記憶データが更新される度に、当該更新された記憶データを構成する複数の実データを参照する複数の前記参照データにアクセス可能な前記データ特定情報を新たに生成して記憶する、
ストレージ装置。
【請求項８】
情報処理装置に、
記憶装置に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶するデータ書き込み手段と、
前記記憶装置に記憶された同一の記憶データのうち、最新の記憶データを特定するデータ特定手段と、を実現させると共に、
前記データ書き込み手段は、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置に記憶し、
前記データ特定手段は、
前記記憶装置内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定するよう構成されると共に、
前記記憶装置内に前記更新情報が存在した最大の２ｉの値を第一更新情報とすると共に、２ｉ＋１の値を第二更新情報とし、
前記記憶装置内に、前記第一更新情報と前記第二更新情報との中間値に対応する前記更新情報が存在するか否かを調べる更新情報検索処理を行うと共に、
前記記憶装置内に、前記中間値に対応する前記更新情報が存在した場合は当該中間値を前記第一更新情報とし、前記中間値に対応する前記更新情報が存在しない場合には当該中間値を前記第二更新情報とする中間値置き換え処理を行い、
前記更新情報検索処理と前記中間値置き換え処理とを繰り返し実行して、前記記憶装置内に存在する前記更新情報の最大値を特定するよう構成されており、
さらに、前記情報処理装置に、最新ではない前記記憶データを構成する前記実データ及び当該実データに関連付けられた前記更新情報を前記記憶装置内から削除するデータ削除手段を実現させ、
前記データ特定手段は、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報を非削除対象更新情報として特定するよう構成され、
前記データ削除手段は、前記非削除対象更新情報として特定された前記更新情報を前記記憶装置内から削除する情報から除外するように構成された、
プログラム。
【請求項９】
請求項８に記載のプログラムであって、
前記データ特定手段は、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報と、前記中間値とされた前記更新情報と、特定された最大値の前記更新情報と、を前記非削除対象更新情報として特定する、
プログラム。
【請求項１０】
記憶装置に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶してデータを書き込み、このとき、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置に記憶し、
前記記憶装置に記憶された同一の記憶データのうち、最新の記憶データを特定する際に、前記記憶装置内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定し、
前記最新の記憶データを特定する際に、
前記記憶装置内に前記更新情報が存在した最大の２ｉの値を第一更新情報とすると共に、２ｉ＋１の値を第二更新情報とし、
前記記憶装置内に、前記第一更新情報と前記第二更新情報との中間値に対応する前記更新情報が存在するか否かを調べる更新情報検索処理を行うと共に、
前記記憶装置内に、前記中間値に対応する前記更新情報が存在した場合は当該中間値を前記第一更新情報とし、前記中間値に対応する前記更新情報が存在しない場合には当該中間値を前記第二更新情報とする中間値置き換え処理を行い、
前記更新情報検索処理と前記中間値置き換え処理とを繰り返し実行して、前記記憶装置内に存在する前記更新情報の最大値を特定し、
さらに、前記最新の記憶データを特定する際に、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報を非削除対象更新情報として特定し、
最新ではない前記記憶データを構成する前記実データ及び当該実データに関連付けられた前記更新情報を前記記憶装置内から削除する際に、前記非削除対象更新情報として特定された前記更新情報を前記記憶装置内から削除する情報から除外する、
情報処理方法。
【請求項１１】
請求項１０に記載の情報処理方法であって、
前記最新のデータを特定する際に、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報と、前記中間値とされた前記更新情報と、特定された最大値の前記更新情報と、を前記非削除対象更新情報として特定する、
情報処理方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ストレージ装置にかかり、特に、同一内容のデータの重複記憶を排除するストレージ装置に関する。
【背景技術】
【０００２】
近年、コンピュータの発達及び普及に伴い、種々の情報がデジタルデータ化されている。このようなデジタルデータを保存しておく装置として、磁気テープや磁気ディスクなどの記憶装置がある。そして、保存すべきデータは日々増大し、膨大な量となるため、大容量なストレージシステムが必要となっている。また、記憶装置に費やすコストを削減しつつ、信頼性も必要とされる。これに加えて、後にデータを容易に取り出すことが可能であることも必要である。その結果、自動的に記憶容量や性能の増大を実現できると共に、重複記憶を排除して記憶コストを削減し、さらには、冗長性の高いストレージシステムが望まれている。
【０００３】
このような状況に応じて、近年では、特許文献１に示すように、コンテンツアドレスストレージシステムが開発されている。このコンテンツアドレスストレージシステムは、データを分散して複数の記憶装置に記憶すると共に、このデータの内容に応じて特定される固有のコンテンツアドレスによって、当該データを格納した格納位置が特定される。具体的に、コンテンツアドレスストレージシステムでは、所定のデータを複数のフラグメントに分割すると共に、冗長データとなるフラグメントをさらに付加して、これら複数のフラグメントをそれぞれ複数の記憶装置にそれぞれ格納している。
【０００４】
そして、後に、コンテンツアドレスを指定することにより、当該コンテンツアドレスにて特定される格納位置に格納されているデータつまりフラグメントを読み出し、複数のフラグメントから分割前の所定のデータを復元することができる。
【０００５】
また、上記コンテンツアドレスとして、データの内容に応じて固有となるよう生成される例えばデータのハッシュ値を用いる。このため、重複データであれば同じ格納位置のデータを参照することで、同一内容のデータを取得することができる。従って、重複データを別々に格納する必要がなく、重複記録を排除し、データ容量の削減を図ることができる。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２００５−２３５１７１号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
ここで、上述したコンテンツアドレスストレージシステムでは、記憶されているデータの内容が変更された場合には、変更後のデータが新たに記憶装置に書き込まれ、この新たに書き込まれたデータの内容に応じたコンテンツアドレスを生成する。このコンテンツアドレスにて、新たに書き込まれたデータの格納位置を参照し、一方で、変更前のデータに対するコンテンツアドレスは参照しないように設定することで、変更したデータの記憶処理が完了する。
【０００８】
そして、上述したように変更が行われたデータにアクセスする場合には、当然、最新のデータにアクセスする必要がある。このため、記憶装置内に記憶されている最新のデータを特定する必要が生じる。また、変更前のデータは、記憶装置に記憶されたまま残ることとなるが、以後、使用されないデータもある。すると、使用されないデータが増加することによって記憶容量の無駄が生じる。このため、使用されないデータを記憶装置内から削除する必要があり、その場合にも、最新のデータを特定する必要が生じる。
【０００９】
しかしながら、更新の頻度が多いデータの場合には、変更前の古いデータの数が膨大となり、最新のデータを特定する処理に時間がかかる場合がある。すると、書き込みや読み取りの処理の遅延が生じる、という問題が生じる。特に、書込みデータの管理を行う上位ホストやアプリケーションが複数存在し、それぞれが独立してデータの書込みや読み取りを制御している場合には、最新のデータの管理が困難であり、その特定に時間がかかる、という問題が生じる。
【００１０】
このため、本発明の目的は、最新のデータを特定する処理に時間がかかること、を改善することができるストレージ装置を提供することにある。
【課題を解決するための手段】
【００１１】
本発明の一形態であるストレージ装置は、
記憶装置に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶するデータ書き込み手段と、
前記記憶装置に記憶された同一の記憶データのうち、最新の記憶データを特定するデータ特定手段と、を備え、
前記データ書き込み手段は、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置に記憶し、
前記データ特定手段は、前記記憶装置内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定する、
という構成をとる。
【００１２】
また、本発明の他の形態であるプログラムは、
情報処理装置に、
記憶装置に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶するデータ書き込み手段と、
前記記憶装置に記憶された同一の記憶データのうち、最新の記憶データを特定するデータ特定手段と、を実現させると共に、
前記データ書き込み手段は、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置に記憶し、
前記データ特定手段は、前記記憶装置内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定する、
ことを実現させるためのプログラムである。
【００１３】
また、本発明の他の形態である情報処理方法は、
記憶装置に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶してデータを書き込み、このとき、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置に記憶し、
前記記憶装置に記憶された同一の記憶データのうち、最新の記憶データを特定する際に、前記記憶装置内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定する、
という構成をとる。
【発明の効果】
【００１４】
本発明は、以上のように構成されるため、最新のデータを特定する処理にかかる時間を短縮することができるストレージ装置を提供することができる。
【図面の簡単な説明】
【００１５】
【図１】本発明の実施形態１におけるストレージシステムを含むシステム全体の構成を示すブロック図である。
【図２】本発明の実施形態１におけるストレージシステムの構成の概略を示すブロック図である。
【図３】本発明の実施形態１におけるストレージシステムの構成を示す機能ブロック図である。
【図４】図３に開示したストレージシステムにおけるデータ書き込み処理の様子を説明するための説明図である。
【図５】図３に開示したストレージシステムにおけるデータ書き込み処理の様子を説明する説明図である。
【図６】図３に開示したストレージシステムにおけるデータ検索処理の様子を説明する説明図である。
【図７】図３に開示したストレージシステムにおけるデータ検索処理の様子を説明する説明図である。
【図８】図３に開示したストレージシステムにおけるデータ検索処理の様子を説明する説明図である。
【図９】図３に開示したストレージシステムにおけるデータ検索処理の様子を説明する説明図である。
【図１０】図３に開示したストレージシステムにおけるデータ検索処理の様子を説明する説明図である。
【図１１】図３に開示したストレージシステムにおけるデータ検索処理の様子を説明する説明図である。
【図１２】本発明の実施形態２で説明する論文で参照する図である。
【図１３】本発明の実施形態２で説明する論文で参照する図である。
【図１４】本発明の実施形態２で説明する論文で参照する図である。
【図１５】本発明の実施形態２で説明する論文で参照する図である。
【図１６ａ】本発明の実施形態２で説明する論文で参照する図である。
【図１６ｂ】本発明の実施形態２で説明する論文で参照する図である。
【図１６ｃ】本発明の実施形態２で説明する論文で参照する図である。
【図１６ｄ】本発明の実施形態２で説明する論文で参照する図である。
【図１７】本発明の実施形態２で説明する論文で参照する図である。
【図１８】本発明の実施形態２で説明する論文で参照する図である。
【図１９ａ】本発明の実施形態２で説明する論文で参照する図である。
【図１９ｂ】本発明の実施形態２で説明する論文で参照する図である。
【図２０ａ】本発明の実施形態２で説明する論文で参照する図である。
【図２０ｂ】本発明の実施形態２で説明する論文で参照する図である。
【図２０ｃ】本発明の実施形態２で説明する論文で参照する図である。
【図２１ａ】本発明の実施形態２で説明する論文で参照する図である。
【図２１ｂ】本発明の実施形態２で説明する論文で参照する図である。
【図２２】本発明の実施形態２で説明する論文で参照する図である。
【図２３】本発明の実施形態２で説明する論文で参照する図である。
【図２４】本発明の実施形態２で説明する論文で参照する図である。
【図２５】本発明の実施形態２で説明する論文で参照する図である。
【図２６】本発明の実施形態２で説明する論文で参照する図である。
【図２７】本発明の実施形態２で説明する論文で参照する図である。
【図２８】本発明の実施形態２で説明する論文で参照する図である。
【図２９】本発明の実施形態２で説明する論文で参照する図である。
【図３０】本発明の実施形態２で説明する論文で参照する図である。
【図３１】本発明の付記１におけるストレージ装置の構成を示すブロック図である。
【発明を実施するための形態】
【００１６】
＜実施形態１＞
本発明の第１の実施形態を、図１乃至図１１を参照して説明する。図１は、システム全体の構成を示すブロック図である。図２は、ストレージシステムの概略を示すブロック図であり、図３は、ストレージシステムの構成を示す機能ブロック図である。図４乃至図５は、ストレージシステムにおけるデータ書き込み処理の動作を説明するための説明図である。図６乃至図１１は、ストレージシステムにおけるデータ検索処理の様子を説明するための説明図である。
【００１７】
ここで、本実施形態は、後述する付記に記載のストレージ装置等の具体的な一例を示すものである。そして、以下では、ストレージシステムが、複数台のサーバコンピュータが接続されて構成されている場合を説明する。但し、本発明におけるストレージシステムは、複数台のコンピュータにて構成されることに限定されず、１台のコンピュータで構成されていてもよい。
【００１８】
図１に示すように、本発明におけるストレージシステム１は、ネットワークＮを介してバックアップ処理を制御するバックアップシステム４に接続している。そして、バックアップシステム４は、ネットワークＮを介して接続されたバックアップ対象装置５に格納されているバックアップ対象データ（書き込み対象となるデータ）を取得し、ストレージシステム１に対して記憶するよう要求する。これにより、ストレージシステム１は、記憶要求されたバックアップ対象データをバックアップ用に記憶する。
【００１９】
そして、図２に示すように、本実施形態におけるストレージシステム１は、複数のサーバコンピュータが接続された構成を採っている。具体的に、ストレージシステム１は、ストレージシステム１自体における記憶再生動作を制御するサーバコンピュータであるアクセラレータノード２と、データを格納する記憶装置を備えたサーバコンピュータであるストレージノード３と、を備えている。なお、アクセラレータノード２の数とストレージノード３の数は、図２に示したものに限定されず、さらに多くの各ノード２，３が接続されて構成されていてもよい。
【００２０】
ここで、本実施形態におけるアクセラレータノード２には、それぞれが独立してデータの記録再生処理を行う複数のアプリケーションが装備されている。つまり、あるアプリケーションは、他のアプリケーションの動作に関係なく、ストレージノード３に記憶されているデータを読み出す処理や、当該読み出したデータを変更して書き込む更新処理を行うよう作動する。
【００２１】
さらに、本実施形態におけるストレージシステム１は、データを分割及び冗長化し、分散して複数の記憶装置に記憶すると共に、記憶するデータの内容に応じて設定される固有のコンテンツアドレスによって、当該データを格納した格納位置を特定するコンテンツアドレスストレージシステムである。このコンテンツアドレスストレージシステムについては後に詳述する。
【００２２】
なお、以下では、ストレージシステム１が１つのシステムであるとして、当該ストレージシステム１が備えている構成及び機能を説明する。つまり、以下に説明するストレージシステム１が有する構成及び機能は、アクセラレータノード２あるいはストレージノード３のいずれに備えられていてもよい。なお、ストレージシステム１は、図２に示すように、必ずしもアクセラレータノード２とストレージノード３とを備えていることに限定されず、いかなる構成であってもよく、例えば、１台のコンピュータにて構成されていてもよい。さらには、ストレージシステム１は、コンテンツアドレスストレージシステムであることにも限定されず、重複排除機能を有しているストレージシステムであればよい。
【００２３】
図３に、本実施形態におけるストレージシステム１の構成を示す。この図に示すように、ストレージシステム１は、サーバコンピュータにて構成され、上述したアプリケーション３０と、記憶装置２０と、を備える。また、ストレージシステム１は、当該ストレージシステム１を構成するコンピュータにプログラムが組み込まれることで構築された、データ書き込み部１１と、データ読み出し部１２と、データ特定部１３と、データ削除部１４と、を備えている。そして、ストレージシステム１は、アプリケーション３０からの要求に応じて、記憶装置２０に対するデータの更新を含む書き込み処理及び読み出し処理を行う。
【００２４】
上記データ書き込み部１１によるデータの書き込み処理について詳述する。データ書き込み部１１は、アプリケーション３０から所定のデータ、例えば、所定の容量を有する１つのファイルの書き込み要求があると、まず、コンテンツアドレスストレージシステムの特性により、ファイルを所定容量の複数の実データである複数のブロックＢ１に分割する。そして、当該ブロックＢ１を、図４（ａ）に示すように、ストレージシステム１内に装備されたメモリ内に一時的に記憶する。メモリ内のサイズがある限度を超えると、図４（ｂ）に示すように、メモリ内のブロックＢ１が記憶装置２０内の所定領域に書き込まれる。そして、かかる書き込みに応じて、ブロックＢ１の格納位置を特定して参照するデータ（参照データ）である、ブロックＢ１の内容に応じたコンテンツアドレスＣＡ１が返却されるため、このコンテンツアドレスＣＡ１をメモリ内に一時的に記憶する。なお、このアドレスを「レベル−０アドレス」ＣＡ１と呼ぶ。
【００２５】
その後、上述したブロックＢ１（実データ）の書き込みが継続され、いくつかの「レベル−０アドレス」ＣＡ１が集められると、図４（ｃ）に示すように、これらのコンテンツアドレスＣＡ１を含む中間ブロックＢ２が、記憶装置２０内の所定領域に書き込まれる。そして、この中間ブロックＢ２のデータ内容に応じて当該中間ブロックＢ２の格納位置を特定して参照するコンテンツアドレスＣＡ２が、図４（ｃ）に示すように、「レベル−１アドレス」ＣＡ２として記憶される。最終的に、書込み要求されたファイルは、図５に示すように、３階層のツリー構造にて記憶装置２０に格納されることとなる。
【００２６】
なお、データ書き込み部１１は、ファイルを上述したように３階層のツリー構造で記憶装置２０に格納する際には、アプリケーション３０が当該ファイルにアクセスできるよう確定処理（commit）を行う。この確定処理により、アプリケーション３０は最上位層にアクセスでき、当該最上位層から最下位層の実データまでのルートが形成され、いわゆるスナップショットツリーが構成される。例えば、図５に示すようなスナップショットツリーの確定処理を行う場合には、まず、符号Ｗ１で、ファイルの一部を構成するブロックが書き込まれ、当該書き込みが終了した後に、ブロックの格納位置を参照する「レベル−０アドレス」を提供する（矢印Ａ０）。その後、符号Ｗ２で複数の「レベル−０アドレス」の格納位置を参照する「レベル−１アドレス」が書き込まれる（矢印Ａ１）。最後に、「レベル−１アドレス」へのルートであるリテンションルートが、符号Ｗ３で書き込まれる。
【００２７】
このとき、このスナップショット、つまり、ファイルを特定するサーチキー「file Sk」が、最上位層のリテンションルートに含まれる。なお、上記サーチキー「file Sk」には、同一のファイルを特定するファイル特定情報（データ特定情報）と、ファイルのバージョンを表すバージョン情報（更新情報）と、が含められる。
【００２８】
さらに、データ書き込み部１１は、ファイルの内容を変更して更新記憶する際には、変更された実データに相当するブロックを、記憶装置２０に新たに記憶する。一方、既に記憶装置２０に記憶されているブロックを更新後のファイルの実データとして記憶する場合には、当該実データを新たに記憶することなく、既に記憶されているブロックのコンテンツアドレスＣＡ１を参照して、当該コンテンツアドレスＣＡ１にて参照される既存のブロックを、新たに記憶する実データとして利用する。これにより、同一内容のブロック（実データ）を重複して記憶することはない。
【００２９】
但し、上述したように、ファイルが更新されると、変更された実データであるブロックが新たに記憶されるため、当該ブロックを参照するコンテンツアドレスＣＡ１が新たに記憶される。従って、上述した中間ブロックに格納される「レベル−０アドレス」が変更され、この中間ブロックのコンテンツアドレスを含む「レベル−１アドレス」も変更されるため、スナップショットが新たに作成されることとなる。つまり、データ書き込み部１１は、ファイルが更新される度に、当該ファイルの各更新バージョンに対応するスナップショットをその都度作成する。
【００３０】
このため、データ書き込み部１１は、スナップショットを作成するたびに、当該スナップショットにアクセスするリテンションルートに含まれる上記「サーチキー」を生成する。このとき、「サーチキー」に含まれるファイル特定情報は、同一のファイルであれば同一の情報となり、バージョン情報は、更新される度に「１」ずつ増加する数値にて表される。例えば、「サーチキー」は、ファイル特定情報である「S」と、バージョン情報である「1」などの数値が組み合わせられた情報であり、ファイルが更新される毎に、「S1」，「S2」，「S3」・・・「Sk」というように、バージョン情報部分が初期値「１」の値から、１ずつ増加して生成される。
【００３１】
以上のように、ストレージシステム１には、１つのファイルについて何度も更新があると、当該ファイルの新旧バージョンに対応する複数のスナップショットが記憶されることとなる。
【００３２】
また、データ読み出し部１２は、上記サーチキーに基づいて、アプリケーション３０から読み出し要求のあったファイルの最新バージョンを、記憶装置２０から読み出す。このとき、データ特定部１３にて、「サーチキー」のバージョン情報の値を参照して、ファイルの最新バージョンを検索する。
【００３３】
具体的に、データ特定部１３は、まず、読み出し要求されたファイルを特定するファイル特定情報を含むサーチキーを対象に、「２ｉ」（ｉは、０以上の整数）の値のバージョン情報を含むサーチキーが記憶装置２０内に存在するか否かを、上記ｉの値が小さい順に調べる。つまり、ｉの値を「０」，「１」，「２」，「３」，「４」・・・・と順に増加させることで、「２ｉ」の値がとる「１」，「２」，「４」，「８」，「１６」・・・・の値と一致するバージョン情報を含むサーチキーが、存在するかを調べる。
【００３４】
ここで、例えば、図６（ａ）に示すように、バージョン情報が、ｉ＝４に対応する「１６」まで存在し、ｉ＝５に対応する「３２」は存在しなかったとする。すると、データ特定部１３は、続いて、バージョン情報が存在していた最大の２ｉの値を第一バージョン情報（第一更新情報）とし、２ｉ＋１の値を第二バージョン情報（第二更新情報）として設定する。この場合は、「１６」を第一バージョン情報とし、「３２」を第二バージョン情報として設定する。そして、データ特定部１３は、設定した第一バージョン情報「１６」と第二バージョン情報「３２」との中間値を算出し、当該中間値である「２４」が、バージョン情報として存在するか否かを調べる更新情報検索処理を行う。
【００３５】
その後、データ特定部１３は、上記中間値「２４」が存在している場合には、当該中間値「２４」を新たな第一バージョン情報として設定する中間値置き換え処理を行う。そして、新たな第一バージョン情報「２４」と第二バージョン情報「３２」との中間値を算出し、当該中間値である「２８」が、バージョン情報として存在するか否かを調べる上記「更新情報検索処理」を行う。一方、上記中間値「２４」が存在していない場合には、当該中間値「２４」を新たな第二バージョン情報として設定する「中間値置き換え処理」を行う。そして、第一バージョン情報「１６」と新たな第二バージョン情報「２４」との中間値を算出し、当該中間値である「２０」が、バージョン情報として存在するか否かを調べる上記「更新情報検索処理」を行う。
【００３６】
上記データ特定部１３は、上述した更新情報検索処理と中間値置き換え処理とを繰り返し行うことで、最初に設定した第一バージョン情報と第二バージョン情報との間の値から、記憶装置２０に存在するバージョン情報の最大値を特定することができる。例えば、図６（ｂ）の矢印に示すようバージョン情報の値を辿っていくことで、各バージョン情報の値を検索することができる。
【００３７】
ここで、データ特定部１３によるバージョン情報の最大値を検索する処理の一例を、図７を参照して説明する。図７（ａ）は、バージョン情報の最大値が「２７」である場合を示している。なお、この図において、点線の四角内にあるバージョン情報の値は、記憶装置２０内に存在していないことを意味している。図７（ａ）の例では、まず、２ｉの値を検索すると、「１６」が存在し、「３２」が存在していないことがわかる。続いて、「１６」と「３２」の中間値「２４」が検索され、当該「２４」が存在するため、「２４」と「３２」の中間値「２８」を検索する。このとき、「２８」が存在しないため、「２４」と「２８」の中間値「２６」を検索し、「２６」が存在するため、「２６」と「２８」の中間値「２７」を検索する。この「２７」が存在するため、バージョン情報の最大値は「２７」であるとして特定される。
【００３８】
また、図７（ｂ）は、バージョン情報の最大値が「２４」である場合を示している。この例では、まず、２ｉの値を検索することで、「１６」が存在し、「３２」が存在していないことがわかる。続いて、「１６」と「３２」の中間値「２４」を検索し、当該「２４」が存在するため、「２４」と「３２」の中間値「２８」を検索する。このとき、「２８」が存在しないため、「２４」と「２８」の中間値「２６」を検索し、「２６」が存在しないため、「２４」と「２６」の中間値「２５」を検索する。さらに「２５」が存在しないため、これまでたどってきた値の中で最後に存在していた「２４」を、バージョン情報の最大値として特定する。
【００３９】
以上のようにしてバージョン情報の最大値を特定することで、当該特定した値のサーチキーに対応するスナップショットを最新バージョンのスナップショットとして特定することができる。そして、データ読み出し部１２は、特定した最新バージョンのスナップショットから参照できる実データにより構成されるファイルを読み出すことができる。
【００４０】
また、ストレージシステム１が装備する上記データ削除部１４は、任意のタイミングで作動し、記憶装置２０内に記憶されているスナップショットのうち、古いバージョンで使用されなくなったスナップショットを削除する。このデータ削除部１４は、本発明におけるコンテンツアドレス方式のストレージシステム１ではファイルが更新されると次々に新たにデータが記憶されるため、記憶容量を節約するために設けられている。
【００４１】
そして、上記データ特定部１３は、上記データ削除部１４にて削除する古いバージョンのファイル、つまり、削除対象となる古いバージョンのスナップショットを特定する処理も行う。具体的に、上記データ特定部１３は、まず、上述したようにバージョン情報の最大値を特定する際に、２ｉの値のバージョン情報が存在するか否かを検索するが、記憶装置内に存在した２ｉの値のバージョン情報を、非削除対象バージョン情報（非削除対象更新情報）として特定する。
【００４２】
上記非削除対象バージョン情報を特定する処理の一例を、図８を参照して説明する。図８（ａ）は、バージョン情報の最大値が「１１」である場合の例を示している。この場合、まず、２ｉの値は、小さい順から「１」，「２」，「４」，「８」という値をとり、かかる値のバージョン情報が存在している。このため、これらの値のバージョン情報「１」，「２」，「４」，「８」に対応するスナップショットを、「Landmarkスナップショット」とし、図８（ａ）では符号Ｌを付加している。また、上述したようにバージョン情報の最大値を検索すると、中間値「１２」，「１０」を経た後、最終的にバージョン情報「１１」が最大値として検索されるが、上記中間値「１２」，「１０」のうち、「１０」は存在するため、かかるバージョン情報「１０」に対応するスナップショットを、「Guidingスナップショット」とし、図８（ａ）では符号Ｇ１を付加している。また、データ特定部１３は、バージョン情報の最大値である「１１」のスナップショットを、「The most recentスナップショット」とし、図８（ａ）では符号Ｍｒを付加している。
【００４３】
データ特定部１３は、以上のようにして特定した「Landmarkスナップショット」、「Guidingスナップショット」、「The most recentスナップショット」に対応するバージョン情報「１」，「２」，「４」，「８」，「１０」，「１１」を、上記非削除対象バージョン情報として特定する。一方、これら以外のバージョン情報「３」，「５」，「６」，「７」，「９」に対応するスナップショットを、「Uninterestingスナップショット」とし、図８（ａ）では符号Ｕを付加している。
【００４４】
同様に、バージョン情報の最大値が「１５」である図８（ｂ）の例を説明する。この場合は、まず、バージョン情報「１」，「２」，「４」，「８」に対応するスナップショットを、「Landmarkスナップショット」とし、符号Ｌが付加される。また、上述したようにバージョン情報の最大値を検索する際に経由した中間値「１２」，「１４」に対応するスナップショットを、「Guidingスナップショット」とし、符号Ｇ１，Ｇ２が付加される。さらに、バージョン情報の最大値である「１５」のスナップショットを、「The most recentスナップショット」とし、符号Ｍｒが付加される。これにより、「Landmarkスナップショット」、「Guidingスナップショット」、「The most recentスナップショット」に対応するバージョン情報「１」，「２」，「４」，「８」，「１２」，「１４」，「１５」を、上記非削除対象バージョン情報として特定する。一方、これら以外のバージョン情報「３」，「５」，「６」，「７」，「９」，「１０」，「１１」，「１３」に対応するスナップショットを、「Uninterestingスナップショット」とし、符号Ｕを付加する。
【００４５】
データ特定部１３は、以上のようにして特定した非削除対象バージョン情報を、データ削除部１４に通知する。そして、データ削除部１４は、上記非削除対象バージョン情報として特定されたバージョン情報（例えば、図８で符号Ｌ，Ｇ１，Ｇ２，Ｍｒ）に対応するスナップショットは、削除対象から除外する。つまり、古いバージョンのスナップショットであっても、上記スナップショットは削除せずに記憶装置２０に残したままとする。これは、データ特定部１３にて今後もバージョン情報の最大値を検索する際に使用するバージョン情報を記憶装置２０内に残すためである。
【００４６】
なお、上述したようにデータ特定部１３にて、バージョン情報の最大値を検索する際に、「Landmarkスナップショット」、「Guidingスナップショット」とされたスナップショットは、検索されたバージョン情報の最大値の「パススナップショット」とされる。つまり、データ特定部１３による上述した方法により、最大値となる各バージョン情報を検索する際に経由するバージョン情報のスナップショットを、「パススナップショット」と称する。図９に、最大値となる各バージョン情報の値を検索する際に経由するバージョン情報、つまり、「パススナップショット」の一例を示す。
【００４７】
また、データ特定部１３は、さらに、最新のスナップショットよりも古いスナップショットのうち、他のアプリケーション３０によってアクセスされているスナップショット及びこれに関連するスナップショットを、データ削除部１４による非削除対象となる「reclamation tail」として特定する機能を有する。この方法は、データ書き込み部１１による処理を利用する。
【００４８】
ここで、データ書き込み部１１がさらに有する機能について説明する。データ書き込み部１１は、最新のスナップショットの書き込み時に、例えばデータ読み出し部１２と協働して、古いバージョンのスナップショットのうちアクセスされているもののバージョン情報を特定する。そして、データ書き込み部１１は、最新のスナップショットからいくつ前のバージョンのスナップショットがアクセスされているかを表す情報である「reclamation tail長さ」を算出する。その後、データ書き込み部１１は、「reclamation tail長さ」を、新たに書き込む最新のスナップショットのリテンションルート内に格納する。
【００４９】
そして、上記データ特定部１３は、最新のスナップショットのリテンションルートに格納されている「reclamation tail長さ」を読み出し、最新のスナップショットのバージョン情報の値から、「reclamation tail長さ」の値だけ小さい値までの間のバージョン情報を、アクセス対象バージョン情報（アクセス対象更新情報）として特定し、当該バージョン情報に対応するスナップショットを「reclamation tail」とする。そして、データ特定部１３は、「reclamation tail」に対応するバージョン情報を、上記非削除対象バージョン情報に含める。さらに、データ特定部１３は、上記「reclamation tail」のパススナップショットも「reclamation tail」に含め、これらのバージョン情報も、上記非削除対象バージョン情報に含める。
【００５０】
ここで、上述したデータ特定部１３による処理の一例を、図１０及び図１１を参照して説明する。図１０の例は、最新のスナップショットのバージョン情報が「２８」であり、そのスナップショットのリテンションルートに格納されている「reclamation tail長さ」が「３」である場合を示している。この場合、データ特定部１３は、スナップショット「２８」から３つ古いスナップショット「２５」，「２６」，「２７」を、「reclamation tail」として特定する。さらに、これらスナップショット「２５」，「２６」，「２７」のパススナップショットである、スナップショット「１」，「２」，「４」，「８」，「１６」，「２４」，「２６」を選択する。但し、これらのうち、スナップショット「１」，「２」，「４」，「８」，「１６」，「２４」は、最新のスナップショット「２８」のパススナップショットであるため、スナップショット「２５」，「２６」，「２７」のみが「reclamation tail」として特定される。
換言すると、「reclamation tail」は以下のように計算される。
−まず、スナップショット「２８」に対する「reclamation tail長さ」が「３」から、スナップショット「２５」，「２６」，「２７」を選択する。
−スナップショット「２５」，「２６」，「２７」のパススナップショット「１」，「２」，「４」，「８」，「１６」，「２４」，「２６」を足す。
−最新のスナップショット「２８」のパススナップショット「１」，「２」，「４」，「８」，「１６」，「２４」を引く。
結果として、上述した場合の「reclamation tail」は、「２５」，「２６」，「２７」となる。
そして、データ特定部１３は、このように「reclamation tail」として特定されたスナップショット「２５」，「２６」，「２７」のバージョン情報を、非削除対象バージョン情報に含める。これにより、これら「reclamation tail」のスナップショットも、データ削除部１４による削除対象から除外される。
【００５１】
また、図１１の例は、最新のスナップショットのバージョン情報が「２６」であり、そのスナップショットのリテンションルートに格納されている「reclamation tail長さ」が「７」である場合を示している。この場合、データ特定部１３は、スナップショット「２６」から７つ古いスナップショット「１９」−「２５」を、「reclamation tail」として特定する。さらに、これらスナップショット「１９」−「２５」のパススナップショットである、スナップショット「１」，「２」，「４」，「８」，「１６」，「１８」，「２０」，「２２」，「２４」を選択する。但し、これらのうち、スナップショット「１」，「２」，「４」，「８」，「１６」，「２４」は、最新のスナップショット「２６」のパススナップショットであるため、スナップショット「１８」−「２３」，「２５」のみが「reclamation tail」として特定される。
換言すると、「reclamation tail」は以下のように計算される。
−まず、スナップショット「２６」に対する「reclamation tail長さ」が「６」から、スナップショット「１９」−「２５」を選択する。
−スナップショット「１９」−「２５」のパススナップショット「１」，「２」，「４」，「８」，「１６」，「１８」，「２０」，「２２」，「２４」を足す。
−最新のスナップショット「２６」のパススナップショット「１」，「２」，「４」，「８」，「１６」，「２４」を引く。
結果として、上述した場合の「reclamation tail」は、「１８」−「２３」，「２５」となる。
そして、データ特定部１３は、このように「reclamation tail」として特定されたスナップショット「１８」−「２３」，「２５」のバージョン情報を、非削除対象バージョン情報に含める。これにより、これら「reclamation tail」のスナップショットも、データ削除部１４による削除対象から除外される。
【００５２】
なお、データ削除部１４は、非削除対象バージョン情報として特定されたバージョン情報に対応するスナップショットのうち、実データに相当する最下層のブロックは削除してもよい。つまり、データ削除部１４は、非削除対象バージョン情報として特定されたスナップショットのバージョン情報さえわかる情報のみを削除せずに残しておけばよく、例えば、スナップショットの最上層のリテンションルートの情報のみを残して、他の情報は削除してもよい。
【００５３】
ここで、本実施形態では、１つのスナップショットで１つのファイルが構成されている場合を例示するが、１つのスナップショットが、１つのファイルの一部のデータ（記憶データ）を構成していてもよい。また、１つのスナップショットは、３階層のツリー構造に形成されていることに限定されず、いかなるデータ構造であってもよい。
【００５４】
＜実施形態２＞
本発明の第２の実施形態を、以下の論文形式にて説明する。
【００５５】
＜第１章＞
（イントロダクション）
コンテンツアドレスストレージシステム（ＣＡＳ）は、不変のデータブロックがそれらのデータ内容から生成されたアドレスによって復元可能であり、永続的に保存可能なストレージモデルである。ブロックがそれらの位置にアドレス指定されるＣＡＳは、ハードディスク・ドライブ（ＨＤＤ）のような、これまでのブロック格納方法とは対照的である。ＣＡＳにおけるコンテンツベースのブロックアドレスは、「MD5」あるいは「SHA-1」のような、典型的な暗号ハッシュ関数で生成される。それらの機能は、効率的に数バイトにブロックの内容を要約した値を生成し、高い確率で、２つの異なるブロックでは、異なる要約の値を生成する。その結果、コンテンツベースのアドレスにより、高い確率で、固有のブロックを特定することができる。
【００５６】
上述したような手法の主な利点のうちの１つは、重複排除である。ブロックの書き込みが要求されるとき、コンテンツアドレスは、システムに同一のブロックが既に記憶されているかどうかを調べることを可能とする。仮に、同一のブロックがシステムに既に存在する場合には、データを記憶しない。これにより、相当な量のディスクスペースを節約することができる。この特徴は、バックアップや保存といったアプリケーションの特別な機能にとって、ＣＡＳを魅力的なものとしている。
【００５７】
バックアップでＣＡＳを使用し、アプリケーションを保存することは、分散装置である"HYDRA09"、"Venti"、"Centera"、"DeepStore"に示すように、ＣＡＳシステムが効果的に拡張して構築されている、という事実によってさらに動機づけられる。多くの装置を使用することができるので、相当な量のディスクスペースを有するシステムが、そのような方法で製造することができる。さらに、主に書き込み処理能力によって測定される性能は、新しいノードの追加によって増加する。最後に、分散システムは、集中システムと比較して、障害に対してより強い。
【００５８】
いくつかのＣＡＳシステムは開発されているが、それらのための標準化されたＡＰＩは存在しない。その上、これらは、一般的に、効果的にユーザデータを格納し管理する方法をプログラムするために多くの努力を必要とするローレベルブロックインタフェースだけしか提供していない。従って、抽象化レイヤー、便利なインターフェースを提供するために主に導入される。直観的な抽象化は、プログラマーによってよく理解され、既存のアプリケーションで広く使用されるファイルシステムで行われている。そのようなファイルシステムの一例は、NEC HYDRAstor system "HYDRA09"上で作動するHydraFS"HFS"である。
【００５９】
既存のＣＡＳベースのファイルシステムの主な用途は、データのバックアップと保存であり、また、それらファイルシステムの根本的なブロック記憶が、膨大なデータスペース、高機能および信頼度を提案しているため、ファイルシステムは、主に、それらの根本的なブロック記憶の性能を完全に活用することに集中しなければならない。言い換えれば、それらシステムの目的は、バックアップとデータ読み出しの処理時間を最小化するよう、読み書き性能を最大化することである。
【００６０】
しかしながら、別のタイプのファイルシステムにとって必要なことは、高い可用性を提供するトランザクション処理である。そのようなファイルシステムは、信頼性のある方法で永続的なデータを格納する必要のある、分離可能である様々な分散アプリケーションによって要求される。例えば、ＣＡＳシステムに記憶されたデータ上でいくつかのオペレーションを行なうアプリケーションは、そのメタデータを永続的に格納する必要があるかもしれず、また、常に利用可能なこのメタデータを必要とするかもしれない。
【００６１】
そのようなトランザクションファイルシステムは、互いに知らない異なるアプリケーション間における永続的な通信手段として用いられてもよい。例えば、分散された資源の所有権を決定し移転するために使用されてもよい。
【００６２】
（１．１．貢献）
この論文は、HYDRAstor "HYDRA09"といった分散ＣＡＳシステム上で作動する高い可用性を有するトランザクションファイルシステムである、「Hydra トランザクションファイルシステム」（「Hydra TFS」と訳す）、と称する。ファイルシステムオペレーションにおけるトランザクションの方法は、ファイル内容の修正から、メタデータの構造を変更すること（例えば、ファイルやディレクトリを作成したり移動すること）まで、広くカバーしている。トランザクションが中断される場合は、常に、他のユーザに意識させずに、自動的にロールバックという結果となる。さらに、失敗したトランザクションを実行したアプリケーションは、再び作動しないかもしれず、そのような状況であっても、ロールバックは実行される。この特性は、基本的なＣＡＳシステムの特性である故障に対するロバスト性、原子性、ガベージコレクションによって達成される。
【００６３】
HydraTFSが可用性と原子性を中心に扱う基本的な前提は、HydraTFSは比較的めったに使用されず、その使用法は、アプリケーションのクリティカルパスに位置していない、ということによる。従って、HydraTFSのオペレーションの待ち時間に関する特定の要件は無い。しかしながら、HydraTFSのファイルは、大容量（つまり、１００ギガバイト以上）のデータで構成されうるため、ファイルオペレーションの処理能力は重要な問題である。
【００６４】
（１．２．論文の概要）
以降の章の構成は、以下のとおりである。
第２章では、HYDRAstorブロックストレージシステムの一般的な概要、および、HydraTFSにとって不可欠な構成について説明する。第３章では、HydraTFSの必要条件の概要について説明する。第４章では、HydraTFSの概要を説明する。後の３つの章では、HydraTFSがどのように作動するかを詳細に説明する。第５章では、クライアントによる分離された方法で準備されたファイルの単一バージョンであるスナップショット内のクライアントデータの構造について説明する。第６章では、スナップショットのコレクションとしてファイルを示す。この章では、スナップショットがファイルの有力なバージョンにどのように原子性によって進められるか、ということと、有力なファイルバージョンがどのように検索されるか、ということを説明する。
【００６５】
そして、第７章では、ファイルがファイルシステムの階層的構造へどのように整理されるかを説明する。第８章では、組み込まれたHydraTFSプロトタイプの評価を説明する。第９章では、関連する研究について議論する。最後に、第１０章では、本論文の結論を示す。
【００６６】
＜第２章＞
（HYDRAstorシステム）
この章では、HydraTFSにおいてブロック記憶の際に用いられるHYDRAstorの一般的な概要を説明する。
【００６７】
（２．１．システムモデル）
システムは、２層で構成されている（図１２を参照）。（図１２は、HYDRAstorのレイアウトを示す。アクセスノードとストレージノードの２つの層が設けられている。データは、ストレージノードに装備されたディスクに記憶される。）
【００６８】
クライアントデータは、ユーザから直接アクセス可能ではないストレージノード（ＳＮ）のグリッドに記憶される。その上層には、データアクセスＡＰＩを提供する１つ以上のアクセスノード（ＡＮ）が設けられている。ユーザ、アクセスノードホストドライバ、及びHYDRAstor上で作動するアプリケーションにとって、HYDRAstorアクセスポイントであることに加えて、特に、HYDRAstorは、１台以上のそのようなマシンで作動する。
【００６９】
（２．２．データ構成）
HYDRAstorにおけるデータは、不変で、可変サイズであり、コンテンツアドレス指定されるブロックに記憶される。そして、３つのタイプのブロックが存在する（図１３を参照）。
−レギュラーブロック
−リテンションルート
−デリーションルート
（図１３：HYDRAstorにおけるデータ構造。影のついた矩形は、データブロックである。破線の四角はブロックポインタ（それらが参照するブロックのコンテンツアドレス）である。）
【００７０】
レギュラーブロックは、基本ブロックであり、ユーザによって提供される実データ（例えば、図１３におけるブロックＤ，Ｊ，Ｉ）を記憶する。レギュラーブロックは、さらにデータ（例えば、図１３のブロックＡ，Ｂ，Ｆ）と共に（あるいは、その代わりに）、既に書き込まれているレギュラーブロックへのポインタ群（これは、これらのブロックのコンテンツアドレスである）を含んでいる。これは、単に無閉路有向グラフ（DAGs）によりブロックをまとめている。データには同様に、記憶されたアドレスが、ブロックアドレス計算の過程で含まれる。言い換えれば、ブロックのアドレスは、ブロック中のデータ、およびブロックに格納された他のブロックへのポインタの両方に依存する。
【００７１】
リテンションルートは、データとコンテンツアドレスに加えて、固有でユーザ指定のサーチキーを含んでいる。サーチキーは、ブロックを検索するために使用される。従って、リテンションルートは、よくサーチャブルキーと呼ばれる。レギュラーブロックのアドレスと異なり、各リテンションルートのコンテンツアドレスは、ユーザには示されない。言いかえれば、リテンションルートは、他のブロックによって参照されない。リテンションルートの目的は、レギュラーブロックのDAGのアクセスポイントになることと、ユーザーフレンドリーな方法でDAGを調べる手段になること、である。
【００７２】
（２．３．ブロックの削除）
HYDRAstorにおける重要な問題は、単一ブロックが直ちに削除されないということである。その代わり、領域再生プロセスと呼ばれるガベージコレクターが定期的に実行される。そのタスクは、以下のブロックを削除するよう作動する。
−同じサーチキーを有し、デリーションルートと呼ばれる、特別なブロックが書き込まれることによって削除用にマークされたリテンションルート
−削除用にマークされておらず、存続しているリテンションルートから到達できないレギュラーブロック
【００７３】
デリーションルートは、削除されるブロックに対するマーカーである。図１３に示す例では、ブロックＡ，Ｄ，Ｅ，Ｊ，Ｋは、存続しているリテンションルートｓｋ１から到達可能であるため、削除後もそのまま残る。一致するデリーションルートがないため、ｓｋ１は、それ自身も存続する。残りのブロックは次には削除される。
ブロックＣ，Ｉ，Ｈ，Ｎは、いずれのリテンションルートからも到達可能ではないため、削除されなければならない。リテンションルートｓｋ２は、デリーションルートが存在しているため、削除される。
【００７４】
その結果、ブロックＢは、存続するリテンションルートから到達不可能となるため、削除される。従って、ブロックＢ，Ｃと共に、ブロックＦ，Ｇもまた、いずれのブロックから参照されず、いずれのリテンションルートからも参照されていないため、削除される。同様の理由で、ブロックＬ，Ｍも削除される。なお、削除の詳細やこれに関係することについては、この論文の範囲外である。
【００７５】
（２．４．インターフェース）
HYDRAstorは専用ライブラリを使用して、アクセスノードからアクセスされる。HYDRAstorは分散型であるが、そのことはクライアントには見えない。インターフェースは以下のとおりである。
【００７６】
（２．４．１．レギュラーブロックの書き込み）
HYDRAstorは、実データあるいはユーザによって提供されるポインタのベクトル（あるいは、データとポインタの両方）を書き込む。代わりに、別のレギュラーブロックあるいはリテンションルートに格納されたポインタとして使用される、書き込まれたブロックのコンテンツアドレスを提供する。また、ブロックは、実際に書き込まれる必要はない。同一のブロックがHYDRAstorの中に既に存在する場合には、重複排除される。すなわち、ブロックは全く記憶されず、また、その代用として、既に書き込まれている同一のブロックのコンテンツアドレスが、ユーザに返される。このような処理は保障されないため、システムでは２つの同一ブロックが存在することも起こりうる。しかしながら、このことは、クライアントからはわからず、たいした問題ではない。
【００７７】
（２．４．２．レギュラーブロックの読み出し）
ユーザは、読み出すブロックのコンテンツアドレスを提供する。返答として、HYDRAstorは、データとポインタであるブロックコンテンツを返す。
【００７８】
（２．４．３．リテンションルートの書き込み）
ユーザは、実データおよびコンテンツアドレスとは別に、書き込むブロックのサーチキーを提供する。そのようなキーを有するリテンションルートがHYDRAstorに既に存在する場合には、内容が同じかどうか関係なく、エラーが返される。レギュラーブロックとは対照的に、リテンションルートを書き込むことは原子的である。すなわち、同じサーチキーだが異なる内容のブロックの２つ以上の書き込みが同時に起こる場合、一の書き込みが成功し、他はブロックが既に存在するという情報を得る。
【００７９】
（２．４．４．リテンションルートの読み出し）
ユーザはサーチキーを提供し、返答としてブロックコンテンツを受け取る。要求されたブロックが存在しないか、削除のためにマークされている（すなわち、デリーションルートによって指示されている）とき、エラー（それぞれ「存在しない」、「削除マークされている」）が返される。
【００８０】
（２．４．５．削除対象のリテンションルートをマークする）
リテンションルートを指すデリーションルートが書き込まれる。ユーザは、単一のリテンションルートを指す１つを超えるデリーションルートを書き込んでもよい。そのような状況で、デリーションルートは、重複排除されうる。削除用にマークされたリテンションルートを読み出すあるいは書き込むことは、ブロックが削除のためにマークされるという情報を返す。
【００８１】
（２．５．特性と制限）
HYDRAstorは、バックアップおよびデータ保存のために設計されているので、その主な特徴は、高い書き込み処理能力である。４つのＳＮ及び４つのＡＮのHYDRAstorにおける圧縮されていないデータの書き込み処理能力は、450MB/s "HYDRA09"に達する。この値は、重複していないデータと、アクセスノードのすべてから実行された書き込み、による。書き込みストリームにおいて重複するブロック割合が増加すると、処理能力は徐々に増加し、重複ブロックが１００％のときに900MB/sに達する。
【００８２】
圧縮されたデータを書き込むことで、さらによい結果となる。33%の圧縮率では、0%および100%に重複したストリームに対する処理能力は、それぞれ610MB/および1150MB/sに達する。
読み出し処理性能は、それよりもわずかに低い。HYDRAstorにとって極めて早く読み出すことは、それほど重要ではない。従って、それは特に最適化されていない。
読み出し待ち時間は、150msである。書き込みオペレーションの待ち時間は、約1500msに達する。書き込み待ち時間は、重複ブロックの割合に依存しない。このような動作は、おそらく利用された処理能力を増加あるいは減少させて、一定のレベルの待ち時間を維持するために動作するHYDRAstorのフロー制御によっておこる。
【００８３】
ブロックサイズは、１バイトで0コンテンツアドレスから65536バイトおよび5120コンテンツアドレスまで変化しうる。
HYDRAstorの総容積は、インストールされたストレージノードおよびディスクの数に依存する。顧客に利用可能である２つのアクセスノード及び４つのストレージノードで構成された中型システムは、24テラバイトと48テラバイト両方の重複排除されたデータを記憶することが可能である"HydraModels"。
最大の利用可能なシステム（５５個のアクセスノードおよび１１０ストレージノード）は、1.3PBの容量を有する。
【００８４】
＜第３章＞
［HydraTFSの必要条件］
HydraTFSは、HYDRAstorのために構築されたアプリケーションの具体的な目標に向かうことを予定しており、HYDRAstorの既存のファイルシステムによって扱われていない。従って、設計は、これらアプリケーションの要求に主に適用するよう調整される。HydraTFSの必要条件について説明するために、これらアプリケーションについて議論する。
【００８５】
（３．１．概要）
アプリケーションは、複数のアクセスノードで作動しうる。異なるマシン上で機能するアプリケーションの実体は分離することができ、それらは連携する必要はない。さらに、アクセスノード間の物理的な接続が有効でなくても、アプリケーションは機能すべきである。
【００８６】
（３．２．ユースケース）
既存のアプリケーションは、メタデータ用のデータベースとして、及び、チェックポイントと回復を可能とするために部分的な結果を記憶する方法として、２つの方法でHydraTFSを使用する。
【００８７】
（３．２．１．メタデータ用のＤＢ）
第１のユースケースでは、HydraTFSは、数キロバイトのデータレコードを格納するために使用される。各レコードは、アプリケーションのそれぞれ独立したタスクに対応し、このため、レコードは、それら自身独立している。あるレコードは、メモリの中に保持され、修正された時、永続的になるようHYDRAstorに保存されなければならない。
【００８８】
（３．２．２．部分的ストレージが結果として実行）
第２のユースケースでは、長期間作動するバッチ処理が、停止するか、あるいは、クラッシュ後に、回復することができるよう永続的な方法で、チェックポイントに定期的に結果を必要とする。格納された部分的な結果は、任意サイズのデータストリームである。データは、タスクが進むとともに、ストリームの終わりに追加される。タスクが再開されると、ストリーム全体が始めから読み取られ、その後、さらにチェックポイントの追加が生じる。
ストリームに付加されるデータの一部は、HYDRAstorに永続的に格納されなければならない。
【００８９】
（３．２．３．格納されたデータ項目のリストおよび削除）
上記のアプリケーションは、それらが格納したデータ項目（ＤＢレコードと部分機能ストリームの両方）の全てをリストアップする。例えば、これはアプリケーションのスタートアップ中に必要とされる。さらに、アプリケーションの実体によって別のアクセスノードから保存されたデータ項目をリストアップするために、必要性が発生するかもしれない。また、クラッシュしたアクセスノードの処理が別のアクセスノードによって引き継がれる時に必要とされるかもしれない。さらに、アプリケーションの実体がクラッシュし、特別のアクセスノード上に再び到着しないようになる状況で、引き継がれなかったとしても、アプリケーションによって格納されたデータ項目は削除されなければならない。従って、削除されるために、最初にリストアップされなければならない。
【００９０】
（３．３．必要条件）
（３．３．１．待ち時間と処理能力）
HydraTFS上でのオペレーションは、比較的例外的に行なわれ、アプリケーションのクリティカルパス上にない。従って、低い待ち時間は、主な条件ではない。しかしながら、アプリケーションが数百ギガバイトのような膨大な量のデータを書き込むかもしれないため、高処理能力が必要とされうる。
【００９１】
（３．３．２．同時）
セクション３．２．１およびセクション３．２．２で述べたユースケースでは、ＤＢレコードあるいはデータストリームは、通常、単一のプロセスによって用いられる。しかしながら、プロセスが衝突したと考えられる場合、同時にアクセスが生じるかもしれない。同時アクセスの発生は２つの原因による。
【００９２】
第１に、衝突したプロセスは、HYDRAstorに、引き続き正常に処理され続けるいくつかの要求を残すかもしれない。それらは、衝突したプロセスの処理を引き継ぎ、別のプロセスの要求を妨げるかもしれない。
第２に、例えば、ネットワーク障害のため、アクセスノード上で作動するプロセスが間違って衝突したと考えられるかもしれない。しかしながら、それは、まだストレージノードと接続され、うまくHYDRAstorで作動するかもしれない。
もし、適切に作動しない場合には、同時アクセスはデータ不整合となるかもしれず、システムの信頼性を低下させる。このことは、HYDRAstorのような商品において容認できない。従って、HydraTFSの設計では、同時の問題に取り組まなければならない。
【００９３】
＜第４章＞
（HydraTFSの概要）
（４．１．HYDRAstorシステムの配置）
HYDRAstorシステムでは、HydraTFSプロセスは、そのために設計されたアプリケーションのプロセスと共に、アクセスノード上で実行される。それは任意の数のアクセスノードで、同時に実行されうる。
HYDRAstorシステムでの全てのHydraTFSプロセスは、単一のファイルシステム上で作動する。ファイルシステムの全体は、HYDRAstorに永続的に格納され、すべてのアクセスノードからの平等な権利を持ってアクセス可能である。さらに、HydraTFSのアーキテクチャは、一致を扱うことはアクセスノード間で同時を扱うことために接続することは要求していない。言い換えれば、内部プロセス通信全体は、永続的なブロック格納を介して実行される。従って、要求される接続は、各アクセスノードとストレージノードとのネットワークの間だけである。
【００９４】
（４．２．ファイルシステム構造）
このセクションは、HydraTFSの構造のボトムアップ記述について説明する。
【００９５】
（４．２．１．レコード）
ユーザ供給データに対して、単一の原子性構造を定義することで始める。バイトストリーム上で動作する古典的なファイルシステムインターフェースとは対照的に、HydraTFSは、分割不可能なデータチャンクに対して作動するよう設計されている。すなわち、既に書き込まれたデータのフラグメントは、全体として読み出されるだけである。そのようなフラグメントをレコードと呼ぶ。これは、単にオブジェクト（バイトの系列によって表わされた）と、コンテンツアドレス（ブロックポインタ）とを含む構造体である。
【００９６】
レコードは、HYDRAstorのレギュラーブロックに似ている。しかしながら、単一のレコードは、単一ブロックと等価ではない。これに反して、単一のHYDRAstorブロックには多数のレコードを維持させ、多くのHYDRAstorブロックをまとめた１つの大きなレコードに広げさせることができる。従って、単一のレコードのサイズに下限はなく、理論上、単一のレコードはファイル全体をカバーしうる。例えば、セクション３．２．１で説明したユースケースでは、データベースレコード全体は、単一のレコードに入れられ、さらに、全体として読み取られうる。
【００９７】
（４．２．２．ファイルスナップショット）
ファイルスナップショット（あるいは、略して、スナップショット）は、単一のクライアントプロセスによって作成されたレコードの一貫したシーケンスである。実際、HYDRAstorでは、それはレギュラーブロックのDAGを指しており、リテンションルートによって表わされる。ファイルが小さい場合、リテンションルートのみで表される。
単一のスナップショット内におけるレコードの構成は、第５章で詳細に説明する。スナップショットで許可されたI/Oオペレーションは、連続してレコードを読み出しており、終わりで新レコードを追加し、これにより、新しいスナップショットを形成している。
【００９８】
そのような新しいスナップショットは、永続的となるようにコミットされる。このオペレーションは、次のセクション４．２．３で再び言及する。しかしながら、コミットが成功する前に、スナップショット上のI/Oオペレーションは、独立した方法でユーザによって実行される。構築中のスナップショットは、いかなる方法による他のスナップショットや書き込まれたいかなる他のHYDRAstorブロックとも衝突しない。実際には、コミットされるまで、他のプロセスによって顕著ではない。HYDRAstorシステムではブロックが不変であるため、既にコミットされたスナップショットは修正することができない。同じ理由が、構築中のスナップショットに属するすべてのブロックに当てはまる。スナップショットの作成がスナップショットをコミットする前に衝突する時、スナップショットの構築中に書かれたレギュラーブロックはHYDRAstorに残るであろう。
【００９９】
しかしながら、重複排除のためどこからも参照されない限り、それらはHYDRAstorのガーベジコレクションプロセス中に削除されるであろう。単一のスナップショットあたりのデータ量は、数百ギガバイトまでは重要かもしれない。従って、読み取りと追加の両方は、高処理能力を可能とすることが必要とされる。
【０１００】
（４．２．３．ファイル）
HydraTFSの中のファイルは、スナップショットの集合である。それらの１つである最も最近のスナップショットは、最後にコミットされたスナップショップであり、ファイルの最新バージョンである。すなわち、ファイルがアクセスされる場合、最も最近のスナップショットがユーザによって読まれることが可能となる。他のスナップショットは古いスナップショットとされる。しかしながら、それらのうちのいくつかは、別のスナップショットが最新となる前に読み始められたユーザによってまだアクセスされるかもしれない。他方、ユーザがファイルにアクセスし始めるときは、最新のスナップショットだけが利用可能となる。
【０１０１】
新しいスナップショットのコミットにより、最も最近のスナップショットが新しいスナップショットへ原子的に置換される。それはトランザクション処理であり、すなわち、多くのユーザが最も最近のスナップショットを読み、その後、ユーザの全てが新しいコミットを試みる場合には、１つだけが成功する。残りのものは、既に新しい最も最近のスナップショットを読み取り、再び試みなければならない。これにより、データ衝突を解決するためのアプリケーションに至る。
コミットの原子性は、原則的に、HYDRAstorにおけるリテンションルート書き込みの事実からなる。従って、矛盾しない状態となり、最新のスナップショットを構成する、あるいは、失敗した場合には何も書き込まれない、といういずれかのブロックの書き込みが成功する。
【０１０２】
（４．２．４．ファイルシステム）
HydraTFSは、ファイルとディレクトリで作られていた構造で構成されている。このファイルシステムレイアウトは、HydraTFSの使用法をユーザにより便利にしている。各ディレクトリは、それぞれ無制限の量の他のディレクトリを格納することができる。ファイルシステムツリーの深さも制限されていない。言いかえれば、ファイルシステム構造は自由に拡大してもよい。
ディレクトリは、レギュラーファイルに内部で類似しているが、特別のコンテンツである。レギュラーファイルへの類似性や、そのコンテンツの修正は、トランザクションである。従って、ディレクトリ構造（つまり、ファイルシステムツリー全体）は、常に一貫性のある状態である。
【０１０３】
各ディレクトリのコンテンツは、ユーザに隠されている。その代わりに、例えば、新しいファイルを作成する、ファイルを削除する、あるいは、ディレクトリをリストアップするように、典型的なファイルシステムオペレーションが示される。
ファイルシステム構造は、ファイルを拡張可能な方法で、効率的に構造化することを可能とする。例えば、しばしばアクセスされるディレクトリは、いくつかのより小さなディレクトリと取り替えることができる。結果として、ディレクトリコンテンツの新バージョンをコミットすることに伴って、ファイルシステムオペレーション中に現れる同時の問題は減少する。異なるレギュラーファイルあるいはディレクトリは、同時の観点からは別である。
【０１０４】
（４．３．要約）
要約すると、グローバルなネームスペースとトランザクションオペレーションといった、２つの主な必要条件にどのように設計が対応しているかということに焦点を当てる。
【０１０５】
（４．３．１．グローバルなネームスペース）
「グローバルなネームスペース」という用語は、すべてのアクセスノードが平等な権利を持ってファイルシステム上で作動し、ファイルシステムの同じ「バージョン」にアクセスする、ことを意味する。アクセスノードのうちの１つから作られたファイルシステムにおけるオペレーションの結果は、コミットした後の他のすべてのマシンからわかる。しかしながら、オペレーションは、いかなるグローバルリーダーによっても調整されない。各アクセスノードはそれぞれ独立して作動し、他のアクセスノードを備えたネットワーク接続を要求しない。
グローバルなネームスペースのそのような特徴は、HYDRAstorからHydraFSで機能する別のファイルシステムによって、現在は提供されていない。ファイルシステムは、一度に単一のアクセスノードからのみアクセス可能である。
【０１０６】
（４．３．２．トランザクションオペレーション）
HydraTFSでは、レギュラーファイル又はディレクトリのコンテンツを修正するオペレーションが、トランザクション処理である。データベースのように、信頼できるトランザクションは、原子性、一貫性、独立性、耐久性といった４つの特性を保証しなければならない。これらの特性がHydraTFSでどのように達成されるかについて着目する。
【０１０７】
「独立性」：新しいスナップショットが作成されるとき、コミットの前には、レギュラーブロックの構造としてHYDRAstorに原則的に表わされる。これらブロックは、他のいかなるプロセスによっても到達可能ではない。それらは書き込みプロセスのメモリの中に保持されるが、それらを参照するただ一つの方法は、固有のコンテンツアドレスを提供することである。別のプロセスはコンテンツアドレスを得ることができるが、それらがすべて重複排除される状況のみで、同一のブロック構造を書き込むことによりのみ、それは達成される。ブロックは不変であり、重複して書き込むプロセスは、トランザクションを準備する別のプロセスに影響を及ぼすことはないため、これは問題ではない。また、重複ブロックを書くプロセスは、別のプロセスがスナップショットを準備し、システムの中に既に同じブロックが存在していることに気がつかない。したがって、この状況は、どんな問題にも結びつかない。
【０１０８】
「原子性および耐久性」：コミットオペレーションは、基本的には、既に説明したように、スナップショットを構成するブロックの構造における最終的なブロックであるリテンションルートを書き込む。原子性と耐久性は、HYDRAstorによって直接保証される。リテンションルートは、コミットを成功させて保存するか、あるいは、リテンションルートによって参照されないレギュラーブロックを残して失敗させる。失敗の後、レギュラーブロックは、ガーベジコレクションプロセス中にHYDRAstorから削除されるであろう。言いかえれば、コミットが失敗すると、データは自動的にロールバックされる。それは、HydraTFSからの参加を必要としない。
【０１０９】
「一貫性」：多くのユーザが最も最近のスナップショットを読み、ファイルの新バージョンを準備し、それをコミットしようとするとき、セクション４．２．３で説明したように、その実行は成功して保証されるであろう。スナップショットをコミットするため、最新のスナップショットを最初に検索しなければならないので、これはデータの一貫性を保証する。言いかえれば、ファイルを修正するプロセスは、最新バージョン中の修正を読まずに、古いバージョンの変形の結果である新バージョンをコミットすることができない。しかしながら、アプリケーションによってデータ矛盾を解決しなければならない。
【０１１０】
＜第５章＞
（スナップショット）
既にセクション４．２．２で説明したファイルのスナップショットは、クライアントによって独立して作成されたレコードの集合である。コミットされた時、この集合はファイルの有力なバージョンになる。コミットオペレーションは、次の章で詳細に議論する。本章では、レコードを読むことと、スナップショットに書き込むことに着目する。
【０１１１】
スナップショットの終わりにレコードを追加し、これらレコードを連続して読み込むことを可能にする方法を提供することを目標とする。新しい空のスナップショットといくつかレコードを既に含むスナップショットに、レコードを追加することは可能である。単一のスナップショットあたりのデータ量は、何百ギガバイトに至るまで大きいかもしれない。従って、読み取りと追加の両方は、高い処理性能を可能とすることが必要となる。
コミットオペレーションの前から、スナップショットはそこで作動するクライアントのみに見え、追加オペレーションはどのような同時処理も引き合わせない。
【０１１２】
（５．１．スナップショットへの書き込み）
最初に、スナップショットが空であり、クライアントがある最初の書き込みの実行を試みている、と仮定する。クライアントは、あるレコードを書くことをHydraTFSに要求する。これらはメモリ内にバッファされる（図１４（ａ））。メモリバッファのサイズがある限度を越えると、バッファされたコンテンツを含む新しいレギュラーブロックはHYDRAstorに書き込まれる。このような書き込みによって返されたコンテンツアドレスが記憶される。このようなアドレスを、「レベル-0アドレス」と呼ぶ。
【０１１３】
その後、クライアントの書き込みが継続され、結果として、より多くの「レベル-0アドレス」が集められる（図１４（ｂ））。
記憶されたレベル-0アドレスの数が、単一ブロック内においてコンテンツアドレスの最大値以上となると、これらのコンテンツアドレスを含む中間ブロックが、HYDRAstorに書き込まれる。再び、このブロックのコンテンツアドレスが、「レベル-1アドレス」として記憶される（図１４（ｃ））。結果として、HYDRAstorに格納された「レベル-0アドレス」はメモリから除去することができる。このようにして、クライアントのレコードを含むリーフノードと、下位のレベルノードへのポインタを含む中間ノードを有する、３階層ツリーを得る。さらに高いレベルツリーは、簡素化のためサポートされない。
【０１１４】
図１４は、スナップショットのツリー構造の構築を示す。破線ブロックは、まだHYDRAstorに保存されておらず、それらの内容はメモリ内にだけある。影が付されたブロックは、クライアントレコードのブロックであり、それぞれデータ及び／又はポインタを含む。
【０１１５】
（５．２．スナップショットのコンテンツコミット）
前のセクションで説明したアルゴリズム、つまり、ユーザによって追加されたレコードがHYDRAstorに物理的に格納されることが保証されない、ことに注意すべきである。これに対して、ユーザのレコードのうちのいくつかは、まだバッファされるかもしれず、いくつかのコンテンツアドレス（レベル-0あるいはレベル-1）は、メモリの中にまだ保持されるかもしれない。さらに、その構造は、どんなリテンションルートによっても参照されていない。この状況では、最も近いガーベジコレクション中に、スナップショットのコンテンツ全体の削除となるであろう。
【０１１６】
HYDRAstorに格納されたデータが永続的であることを保証するために、スナップショットをコミットしなければならない。これは、その結果として、HYDRAstorにバッファをフラッシュさせなければならないことを意味し、リテンションルートによってスナップショット構造の全体を参照しなければならない。具体的に、コミットは以下のように作動する。
【０１１７】
−ツリーの現在の高さが「０」である場合（すなわち、ブロックはまだ格納されていない）、メモリバッファのコンテンツは、新しいリテンションルートとしてHYDRAstorに保存される。
−ツリーの現在の高さが「１」であり（少なくとも１つの「レベル-0」アドレスが記憶されている）、あるユーザデータがメモリバッファに存在する場合、バッファを含むブロックはHYDRAstorに書か込まれ、そのコンテンツアドレスは後の「レベル-0」アドレスとして記憶される。その後、記憶された「レベル-0」アドレスはすべて、リテンションルートの一部としてHYDRAstorに書き込まれる。
−ツリーの現在の高さが「２」である場合（少なくとも１つの「レベル-1」アドレスが記憶されている）、オペレーションは再帰的に作動する。最初に、バッファはレベル-0ブロック内に書き込まれ、その後、中間レベル-1ブロックが書き込まれる。最後に、記憶されたレベル-1はアドレス指定され、メタデータがリテンションルートとして保存される。各レベルで、多くて１つの永続的なブロックがあることに着目すべきである。
【０１１８】
図１５は、高さが「２」であるスナップショットツリーをコミットするプロセスを示している。「write 1」は、クライアントレコードを有するバッファのコンテンツのためである。上述した書き込みが終了した後に、レベル-0アドレスを提供して、「write 2」でレベル-0アドレスのレベル-1ブロックが書き込まれる。
最後に、ブロックへのレベル-1アドレスがHYDRAstorから到着すると、スナップショットのサーチキーを備えたリテンションルートが、「write 3」で書き込まれる。
図１５は、高さ２のスナップショットツリーのコミットを示す。破線ブロックはメモリ内にあり、書き込まれなければならない。残りのブロックは、既にHYDRAstorに書き込まれている。
【０１１９】
スナップショットのバッファをコミットした後に、クライアントはレコードを追加し続けることができる。論理上、新しいデータアイテムは、コミットされたデータと一緒に、次のスナップショットを構成する。次のスナップショットを永続的にするために、次のコミット（新しいリテンションルートのサーチキーと共に）が行われなければならない。従って、クライアントは、コミットを、フラッシュオペレーション（fflush()に似ている）として考える。
【０１２０】
コミットの成功の前にスナップショットが構築されたプロセスがクラッシュした場合、あるいは、コミットが失敗してクライアントが再試行しなかった場合に、完成していないスナップショットはロールバックされる。すなわち、HYDRAstorに既に格納されているレコードは、最も近いガーベジコレクション中に自動的に回収される。これは、これらのレコードを含むレギュラーブロックがいかなるリテンションルートにも参照されていないからである。
【０１２１】
（５．３．スナップショットのリーフブロックの構造）
上述したように、レコードは、実データ（バイト）とコンテンツアドレス（ポインタ）の両方から成る。スナップショットに全てを追加中に、１バイトあるいは１つのコンテンツアドレスをはじめとして、たくさんのデータ／アドレスが保存される。追加後に、クライアントはコミットすることが可能となる。そのようなコミットの後に、次の新しいHYDRAstorブロックにレコードを追加すると、最終的には、１つのブロックに１つのレコードように、少量のレコードを含んだ過剰な数のブロックで作られたスナップショットで終わる。そのようなスナップショットは、必要であるというよりはるかに多くのスペースの占領することの他に、読み取りの時間消費と資源消費に至るであろう。
【０１２２】
従って、ブロックを横切ってレコードを構成するための方法が導入されている。その詳細は、この論文の範囲外であるが、その目的は、最終的には、全ての連続したブロックにレコードを格納して、それらの容量を満たすことである（64kBのデータ又は5120のアドレス）。
【０１２３】
（５．４．スナップショットの読み取り）
読み取りプロセスは、適切なリテンションルート、すなわち、スナップショットのツリー構造のルートを読み取ることで始まる。その後、最初のリーフブロックは順番に見つかり、レコードの読み取りが始まる。スナップショット読み取りオペレーションは、単に、順次ツリーリーフを読むことに他ならない。
読み取りの間、最後のプロセスのリーフブロックと、ルートまでのスナップショットツリーの親の全ては、メモリ中でキャッシュされるべきである。これは多くの量のメモリを必要しない（３つのブロックまで）。そうでなければ、ツリーに位置だけを維持すれば、それがHYDRAstorからの３つまでの連続する読み取りから構成される、その後の読み取りはそれぞれかなりの時間続くであろう。
【０１２４】
（５．５．要約）
示された設計は、著しいデータのオーバーヘッド無しに、大きなスナップショットを作成し、有効な方法で、順次、スナップショットを読み取り、書き込むことができる。
【０１２５】
（５．５．１．書き込み性能）
追加オペレーションは、高いHYDRAstor活用に導くことができる方法で実行される。たとえ、クライアントが非常に小さいレコードの追加を発行続けたとしても、準備ができている場合、後のブロックに対する候補がバッファされ、HYDRAstorに書き込まれる。従って、HYDRAstorへの書き込みは、大きなサイズのチャンクで行なわれる。それとは別に、HYDRAstorへの書き込みは、どんな方法でもさらなる追加プロセスを中断せず、その後の準備ブロックのさらなる書き込みを可能とする。上記内容は、さらに中間のレベル-1ブロックを書くことに当てはまる。もしメモリバッファが十分に大きければ、追加プロセスはHYDRAstorによって提供される処理能力を完全に利用することができる。
【０１２６】
（５．５．２．読み出し性能）
レコードの読み出し性能は、書き込み性能よりも著しく低いかもしれない。主な理由は、レコードがツリーにおけるリーフブロックを占め、前のリーフブロックを読むことが必要かどうか、をチェックするためである。従って、HYDRAstorにおけるブロック読み取りの高い待ち時間のため、設計では、ブロックが１つずつ読み出される仮定し、処理能力が減少する。読み出し処理能力は、先読みによって改善され、あるいは、中間ツリーノードに追加のメタデータを格納することにより改善される。
【０１２７】
＜第６章＞
（スナップショットのシーケンスとしてのファイル）
第５章で説明したように、スナップショットを構築することは、各クライアントプロセスによって分離されたやり方で実行される。リテンションルートである最上層のブロックの書き込みは、最後にグローバルネームスペースに触れ、他のクライアントと衝突するかもしれない。従って、前の章に定義された方法を使用して行なわれたリテンションルートのコンテンツを準備することと、ここで議論されるHYDRAstorへの実際の書き込みとの間の境界線を導入する。リテンションルートの書き込みが新しいスナップショットを他のクライアントに見えるようにするときのオペレーションを、「WriteSnapshot」と呼ぶ。ファイルが複数回（１、あるいは、多くのクライアントプロセスのいずれかによる）コミットされると、多数のスナップショットがHYDRAstorに生成される。
【０１２８】
各ファイルについては多数のスナップショットがHYDRAstorに存在するので、クライアントがファイルを読むことを望むときに、最も最近のものを選択する、ということが問題の１つとなる。なお、このオペレーションを、「GetMostRecentSnapshot」と呼ぶ。「WriteSnapshot」に対して、「GetMostRecentSnapshot」は、適切なリテンションルートを選択して読み出し、続いて、前の章で説明したように、コンテンツが単一のスナップショットを読むことを引き起こす手順に渡される。そのときは、ファイルの削除は考慮しないが、これは次の章で議論する。
【０１２９】
「WriteSnapshot/GetMostRecentSnapshot」オペレーションにとって主に必要なものは、ファイルを修正するトランザクションの方法である。すなわち、「GetMostRecentSnapshot」を使用して、多くのクライアントが同じスナップショットを読み、各々が新しいスナップショットを生成して、すべてが「WriteSnapshot」を行うとすると、オペレーションの１つが成功することとなる。残りのクライアントは、コミットを成功させるために、オペレーションを繰り返さなければならない。すなわち、データをリフレッシュする「MostRecentSnapshot」を実行し、これにより矛盾の可能性を解決し、もう一度試みる。この特徴により、データの一貫性が保証される。コミットすることが失敗したスナップショット内のレギュラーブロックは、存在するいかなるリテンションルートからも参照されていないブロックとして、最も近いHYDRAstorのガーベジコレクションで自動的に削除される。
セクション６．１では、その問題への基本的なアプローチを説明する。その後のセクションでは、このソリューションを徐々に改良していく。
【０１３０】
（６．１．基礎的なアプローチ：スナップショットの線形的順序）
基本的なアプローチでは、ファイルをスナップショットの順序で表わす。最初に、ファイルは、「０」しかスナップショットがなく、その後、最初のコミットスナップショット「１」が作成される。続くコミットでは、スナップショット「２」，［３］等というように作成される。単に、最も最近のスナップショットは、最も高い数を有するものである。以後、「ｉ番目」のスナップショットを「Si」と呼ぶ。
「GetMostRecentSnapshot」は、単にスナップショット上で繰り返し（HYDRAstorで読まれたリテンションルートを実行する）、存在する最新のスナップショットのコンテンツを返す。存在するスナップショットをチェックするためには、リテンションルートを読むべきである。
【０１３１】
スナップショットSiを読んだ後に可能な次の「WriteSnapshot」は、Si+1を書くことである。たった１つのクライアントからの「WriteSnapshot」オペレーションは成功する（セクション２．４．３）。Si+1を書き込む他のクライアントに対しては、リテンションルートの書き込みは成功しない。要求されたサーチキーを有するリテンションルートが既に存在することを示して、HYDRAstorによってエラー状態が返される。このような状況で、エラー状態は、読まれたスナップショット（この場合、Si）は既に古いことを示して、クライアントに返される。クライアントは、一致矛盾を解決するためにオペレーションのシーケンスを繰り返す。次の「GetMostRecentSnapshot」は、新しく保存されたスナップショットルートSi+1（他の誰かがコミットして提供された）を返す。その後、読み取ったスナップショットの修正を行った後、クライアントは新しいスナップショットSi+2をコミットする。
【０１３２】
コミット成功後に、クライアントは、再び「GetMostRecentSnapshot」を行う必要はない。これに対して、スナップショットSi+1がコミットされている場合、クライアントはさらにコミットを実行でき、それらはスナップショットSi+2、Si+3などとして書き込まれる。
一致書き込みがある状態で、返された最も最近のスナップショットは、実際の最も最近のスナップショットより実は古いかもしれない。しかしながら、クライアントが、古いスナップショットに基づいてコミットする（「WriteSnapshot」を行う）場合、古いスナップショットに基づいて、それが既に述べられたように、オペレーションは失敗するため、これは問題ではない。このように、クライアントは、どんな矛盾も解決し、かつオペレーションをやり直す機会を得る。
【０１３３】
（６．２．改良：デュアルバイナリサーチアルゴリズム）
ここでは、「GetMostRecentSnapshot」オペレーションのタスクに着目し、それを改善することを試みる。HYDRAstorの中で保存されているスナップショットS1、S2の，・・・，Snのシーケンスを与えられるが、このようなシーケンスの最後を効率的に見つける必要がある。
【０１３４】
気がついたかもしれないが、前のセクションに述べられていた基本的なアプローチの中で示された反復は、最適な解決方法ではない。O(n)を読み出すことを必要としている。読み取りの数を改善する最初のステップとして、最も最近のスナップショットの連続番号における上界を効率的に見つけることを行う。スナップショットルート上に一つずつ繰り返す代わりに、スナップショットルートS20 , S21 , . . . S2kの存在をチェックする。従って、S2k−1 が存在し、S2kが存在しない場合には、2kの数が上界となる。例えば、図16aでは、最初にシーケンス1 ,2 ,4 ,…のスナップショットが存在し、スナップショット32でスナップショットが存在せず、繰り返しが終了する。したがって、「32」が見つかった上界となる。（図１６は、デュアルバイナリサーチアルゴリズムを示す。）
【０１３５】
境界を見つけた後、(2k−1, 2k)の範囲中でシーケンスの最後をバイナリサーチする（図16b参照）。
図16cで、サンプルアルゴリズム実行を示す。結果は「27」である。リーフスナップショットに到達し、それが存在しない場合には（図16d）、最も最近遭遇したスナップショットが結果となる。言いかえれば、結果となるスナップショットが存在するかもしれない連続の範囲は、以下のとおりである。
【０１３６】
- (16,32)  上界が見つかった後。
- (24,32)  スナップショット24は存在する。
- (24,28)  スナップショット28は存在しない。
- (24,26)  スナップショット26は存在しない。
- (24,25)  スナップショット25は存在しない。従って、結果は24。
【０１３７】
上述したバイナリサーチでは、O(n)からO(log(n))まで、シーケンス(Sn)の最後を見つけるために必要なオペレーションの数を減らすことができる。
上記のデュアルバイナリサーチアルゴリズムは、より大きな母数で検索することによって改善されうる。例えば、64の母数では、64個のリテンションルートを並行して読むことになる。最も最近のスナップショット番号が264未満であるとすると、一度の並列読み出しにより、最後のスナップショットの番号のための上界を見つけることができる。アルゴリズムの第２のステップは、一度にサーチツリーの６レベルを進むので、オリジナルのバイナリサーチよりも６倍速く行うことができる（64=26）。この単純な最適化は、「GetMostRecentSnapshot」の待ち時間を相当短縮する。
【０１３８】
（６．３．不必要なスナップショットの削除）
全てのシーケンス、つまり、ファイルの一生で作成された全てのスナップショットを格納することは、特にファイルサイズ（及び、スナップショットのサイズ）が何百ものギガバイトに達するかもしれないので、記憶装置を浪費する。さらに、各スナップショット中のクライアントレコードは、クライアントによってもはや必要でなく、HYDRAstorによって回収できるブロックへのポインタを含むことができる。スナップショットによって占められる実際の量は、さらに大きいかもしれない。従って、単一ファイル用に保存されたデータの量を減らす方法が要求されている。
【０１３９】
（６．３．１．削除するスナップショットの選択）
上述した考察の時に、ファイルは変わらないと仮定し、すなわち、新しいスナップショットは書かれないとした。
「GetMostRecentSnapshot」オペレーション中に、デュアルバイナリサーチアルゴリズムは、スナップショットの小さな部分集合だけにアクセスする（ここでは、存在のためのチェック）。残されたものは、同様に削除される。それらの存在か欠如かは、「GetMostRecentSnapshot」の視点から見て違いはない。
形式的に無用のスナップショットを削除する方法を定義するために、スナップショットシーケンスを構築するスナップショットをグループ化する。初めに、次の記法を導入する。
【０１４０】
- M -  最も最近のスナップショットのシーケンス番号。
- N -  2N =< M < 2N+1を満たす定数。
スナップショットを、以下のカテゴリーに分類する。
"the most recent スナップショット"  スナップショットSM
"nonexisting スナップショット"  次の全てのスナップショット Si（i > M）
"landmark スナップショット"  次の全てのスナップショットS2i（0 =<i =< N）
"guiding スナップショット"  このグループは、再帰的に定義される。
【数１】
0005500309.tif 000002
"uninteresting snapshots"  他の全てのスナップショット
【０１４１】
スナップショットの分類を、図１７に示す。（図１７は、スナップショットの分類を示す。Ｌ−landmarkスナップショット、Ｇｋ−guiding スナップショット、Ｍｒ−the most recentスナップショット、Ｕ−uninterestingスナップショット）。
直観的に、上記の用語によると、デュアルバイナリサーチの考えは、landmark スナップショット上に繰り返すことによって、最初に上記Nを識別し、次に、guiding スナップショット上に繰り返すことにより、上記Mを見つける。
このようにすることで、サーチアルゴリズムで使用されないuninteresting スナップショットを安全に削除することができる。さらに、スナップショットがuninteresting スナップショットとなると、それはシーケンス成長にかかわらずuninteresting スナップショットのままであることが分かる。O(log(n))だけuninteresting スナップショットがあるので、uninteresting スナップショットを削除することで、多くの領域を節約する。
【０１４２】
"パススナップショット"
SMをサーチする間にシステムに存在するスナップショット（すなわち、guidingスナップショットと、landmarkスナップショット）を、SMのパススナップショットと呼ぶ。「AはBのパススナップショットである」という関係を、図１８に示す。この関係は、過渡的であるため、各スナップショットの最も高いパススナップショットだけがマークされる。（図１８は、パススナップショットを示す。スナップショットから最も高い値のパススナップショットへの矢印を破線で示す。）
【０１４３】
（６．３．２．reclamation tail）
ファイルが変更されないと仮定して、新しいスナップショットが書かれたときに何が起きているかを分析する。
Skで終了するスナップショットのシーケンスがあると仮定する。新しいSk+1を書いた後に、それがuninterestingスナップショットになっても、単に削除のために直ちにSkをマークすることはできない。新しいスナップショットを書くにもかかわらず、１つあるいは多くの古いものが、それらが最も最近のスナップショットだったときに、過去に読み取りを始めた人によってまだ読まれているかもしれない。もし、削除用にそれらをマークし、ガーベジコレクションがHYDRAstorで続行されると、nonexistingスナップショットを読むこととなり、リードエラーで終わる。従って、すべてのユーザに影響なしに読み終えることを望む。
【０１４４】
同じことは、最も最近のスナップショットをサーチすることにも当てはまる。バイナリサーチの最中で、パス上のいくつかのスナップショットルートが削除用にマークされることが起きてほしくはない。そのような状況では、サーチ結果は異常となる。
スナップショットの積極的な削除は、偽陽性のコミットを引き起こすかもしれない。クライアントによって読まれたスナップショットと次のものの両方がuninterestingとなり（別のクライアントのオペレーションの結果）、削除のためにマークされることと仮定してみる。その後、HYDRAstorの中のガーベジコレクションが実行され、後で、クライアントがコミットする。新しくコミットした場所にはこれ以上スナップショットがないが、コミットは成功するであろう。
【０１４５】
クライアントによってどのスナップショットが使用されるかされないか、結論付けることが確立されなければならない。最も悲観的なもので、スナップショットの全てが誰かにまだ必要とされているかもしれない、ということが想定される。実際、現在のルールでは、長い間、最も最近のスナップショットでなくても、クライアントは、あるスナップショットを読み始めるかもしれないし、読み終わらないかもしれない。
【０１４６】
明らかにこれは承諾しがたいが、誰からもアクセスされないスナップショットを決定する方法を提供しなければならない。この目的のために、クライアントが「GetMostRecentSnapshot」でスナップショットを探索して管理し、それを読み、（臨むのであれば）新しいものをコミットしなければならないことに、タイムリミットTrが導入される。タイムリミットは、「GetMostRecentSnapshot」がいつ始まるかカウントし始める。従って、削除することができるスナップショットは、Trよりも前にuninterestingスナップショットとなった全てのスナップショットである。
【０１４７】
「GetMostRecentSnapshot」を読み取り実行することが機能してその後良好であり、オペレーションが続いて、もしタイムリミットを超過していないなら、これらの方法の実行をコントロールすることが提供される。コミットオペレーションの正確さは、クライアントによってまだ考慮されている最も最近のものの後に続く、次のスナップショットの存在に依存する。もし、SiがTr時間が経過する前に最も最近のスナップショットではなくなった場合、その後、Si+1も、Tr時間も前に、Siより後の最も最近のスナップショットではなくなる、ということがわかる。
【０１４８】
あるファイルについてオペレーションを実行する各クライアントは、uninterestingスナップショットのいわゆる「reclamation tail」に関するインメモリ情報を記憶する。つまり、そのスナップショットは、オペレーションを終了するために他の潜在的なクライアントに十分な時間を与えることを守るが、削除のためにマークされたスナップショットである。
【０１４９】
さらに具体的には、スナップショットSMが書かれているときにスナップショットSiがuninterestingスナップショットになると、Siは削除のために直ちにマークされない、とみなす。それは、コミットが終了する瞬間から2Trの後にだけ削除のためにマークされる。言いかえれば、スナップショットは、保留のクライアントオペレーションの全てが完了するまでに十分な長さの「reclamation tail」の間、残るであろう。理論上、Trを待つことは十分であるが、その２倍の長さを待つことが行われる。これは、アクセスノードのクロック速度が歪むからである。待ち時間を延ばすことによって、厳しい時間測定が不正確となすことさえ許容されうる。
【０１５０】
”Reclamation tail長さ”
ファイルを使用し、reclamation tailのトラックも維持しているクライアントが衝突する状況に着目する。これがHYDRAstorにおける記憶の激しい漏れを引き起こすので、reclamation tailのスナップショットは忘れてはならない。他方で、チェックするスナップショットの数が潜在的に膨大であるため、スナップショット１から最も最近のスナップショットで終わる全てのスナップショットの存在をチェックできない。したがって、衝突の後にreclamation tailに関する情報を再構築するソリューションを示す。
【０１５１】
reclamation tailを取り出すために必要な情報であるreclamation tail長さは、スナップショットつまりリテンションルートのデータ部分に、常に書き込まれる。これにより、衝突の後に、後方にあるスナップショットはまだ再生することができる。最も最近のスナップショットがSMであるとすると、reclamation
tail長さは、最低の値kとして与えられているとき、スナップショットSM−1, SM−2, ..... , SM−kがそれらのパススナップショットと共に、現在のreclamation tailの上位集合を構成する。
【０１５２】
従って、永続的にreclamation tail長さを維持することによって、reclamation tailは、最も最近のスナップショットよりもkだけ前のスナップショットをとり、それらのパススナップショットを生成し、最も最近のスナップショットのパススナップショットを取り除くことにより、容易に検索できる。結果として生じる集合は、実際、既に取り戻されたスナップショットを含んでいるかもしれない。しかしながら、これはガーベジコレクション段階の問題であり、考慮されなければならない。
【０１５３】
図１９ａで、reclamation tailは、スナップショット25、26、27から成る。このとき、reclamation tail長さは、「３」である。reclamation tailを再構築する場合には、スナップショット25-27のパススナップショットが計算される。スナップショット25、26、27のパススナップショットは、26、24、16、8、および、図の中で示されないスナップショット4、2、1である。さらに、スナップショット1、2、4、8、16、24は、最も最近のスナップショットのパススナップショットである。従って、それらはreclamation tailには加えられない。その結果、reclamation tailは、スナップショット25-27からのみ成る。
【０１５４】
図１９ｂでは、reclamation tail長さは「７」である（reclamation tailは、スナップショット19-25によって生成される）。スナップショット24は、reclamation tail長さへ数えられる。しかし、それは、最も最近のスナップショットのパススナップショットとしてreclamation tailから除外される。スナップショット18は、reclamation tail長さには数えられない。しかし、それは、reclamation tail長さに数えられるスナップショット19のパススナップショットとしてreclamation tailに含まれている。スナップショット16、8、4、2および1は、前の例と同様に、それらが最も最近のスナップショットのパススナップショットであるので、reclamation tailの一部ではない。一般に、上述したlandmarkスナップショットは、reclamation tailの一部ではなく、それらは上述したuninterestingスナップショットにはならない。（図１９は、reclamation tailを示す。四角の数字は、存在するスナップショットを示す。太線四角と矢印は、最も最近のスナップショットとそのパススナップショットを示す。破線の四角は、reclamation tail のパススナップショットであるが、reclamation tail長さにカウントされない。）
【０１５５】
”uninterestingスナップショットの軌跡を維持”
上述したように、与えられたファイルを使用する各クライアントは、まだ未開拓のuninterestingスナップショットについての情報を維持し、可能ならいつでも、それらを削除のためマークする。スナップショットがuninterestingスナップショットと認められる場合は、常に、現在時刻に2Trを加算した終了時刻で収集に加えられる。期間が経過したスナップショットは、まず削除用にマークされ（すなわち、そのスナップショットルートに対応するデリーションルートがHYDRAstorの中で書かれる）、成功した後に、収集から取り除かれる。
【０１５６】
”スナップショットオペレーションのコンテキストへの挿入”
「WriteSnapshot」オペレーション中に、reclamation tail長さは計算される。この計算は、収集に保持されたスナップショット、および、追加された最も最近のスナップショットに基づき、「WriteSnapshot」が成功すると、それがuninterestingスナップショットになる。その後、reclamation tail長さは、新しいスナップショットのスナップショットルートの始めであるリテンションルート内に書かれる。コミットが成功すると、既に前の最も最近のスナップショットが収集に加えられる。スナップショットに加えて、コミットされたスナップショットのパススナップショットではない、パススナップショットのパスが、uninterestingスナップショットの収集に加えられる。
【０１５７】
「GetMostRecentSnapshot」中に、uninterestingスナップショットの収集が、最も最近のスナップショットの読み取りから取り出されたreclamation tail長さに基づいて更新される。このクライアントによってファイル上で行なわれた最初のオペレーションである場合、収集が初期化される。次に、ファイルに関する情報が既に記憶されているとき、１つ以上のコミットが、最後の更新以来、他のクライアントによって行われると、更新されうる。そのような場合では、コミットがいくつかのスナップショットをuninteresting スナップショットにするので、いくつか新しいスナップショットはreclamation tailに到達する。他方で、同時に処理するクライアントがあるスナップショットを以前に削除用にマークしており、それらが収集から取り除かれるかもしれないため、reclamation tailが減少するかもしれない。そのようなreclamation tailの更新例を、図２０（２０ａ，２０ｂ，２０ｃ）に示す。
【０１５８】
図２０は、GetMostRecentSnapshotの後の更新を示す。reclamation tail長さに基づいて更新されるものは、reclamation tail長さとreclamation tail自身である。太線で示すスナップショットは、存在する最も最近のスナップショットとそのパススナップショットである。枠で囲ったスナップショットは、おそらく存在するスナップショットである。破線で囲ったスナップショットは、おそらく存在するが、reclamation tail長さに含まれていないスナップショットである。
【０１５９】
（６．３．３．マーカーブロック）
最も最近のスナップショットのパススナップショットであるlandmarkスナップショットとguidingスナップショットは、かなりの時間（landmarkスナップショットの場合、ファイル自体の一生に等しい）、システム内に存続する。それらの存在中に、それらは、まだファイルのいくつかのより古いバージョンを含んでおり、それは相当なサイズになる。しかしながら、議論されたスナップショットについては、最も最近のスナップショットであることをやめた瞬間からのTr時間後に、その役割は、最も最近のスナップショットへのパスを決定するために縮小される。これは、マーカーブロックを導入する動機づけである。
【０１６０】
マーカーブロックは、コンテンツがないリテンションルートである。最適化の基本的概念は、リテンションルートのミラーシーケンスを作る標準スナップショットと共にそれらが保存されることである。このシーケンスは、標準スナップショットルートの代わりに、GetMostRecentSnapshotオペレーションで使用されるかもしれない。今、全てのlandmarkスナップショット及びguidingスナップショットは、Tr時間の後に、まるでunintrestingスナップショットであったかのように、reclamation tailの一部でない限り、取り戻されうる。マーカーブロック最適化の詳細は、この論文の範囲外である。
【０１６１】
＜第７章＞
（ファイルシステム内でのファイルの配置）
HydraTFS中におけるファイルは、ファイルシステムのようなディレクトリ構造へ整理される。これにより、クライアントによる使用がより便利となる。さらに、これにより、ファイルを効率的に、かつ、拡張可能に整理できる。例えば、クライアントがシステムに個人的なファイルを格納したい場合はいつでも、個別のディレクトリ（他のいかなるクライアントによってもアクセスされない）を作成し、その結果、ファイルを追加したり削除する間における同時問題を最小化することできる。他の誰も（セクション７．３．２で説明したガベージコレクションを除いて）、ディレクトリに触れず、矛盾する変更を加えることはできない。
【０１６２】
（７．１．ファイルおよびディレクトリ）
ディレクトリは、特別なコンテンツを除いて、ユーザから見えないようファイルとして導入される。従って、この章で「ファイル」について説明するときは常に、通常のファイルあるいはディレクトリのいずれかに言及している。ディレクトリは、それぞれ、ファイルシステムツリーの子たちである、ファイルとサブディレクトリに対応するエントリのリストを含んでいる。エントリは、それぞれレコードに相当し、次のものを含んでいる。
【０１６３】
−ファイルのクライアントに定義された名前。
−ファイルタイプ：エントリが通常のファイルあるいはディレクトリに一致するかどうかを示す。
−ファイルID。
ファイルIDは、従来のファイルシステムにおけるinodeナンバーとして考えられる識別子である。それは、作成される場所や時間に関係なく、常に固有となるよう生成される。この識別子（スナップショットの連続番号と共に接尾に付けられる）は、スナップショットツリー構造のルートのために設定される各リテンションルートに対するサーチキーとして使用される。
【０１６４】
（７．１．１．ファイルオペレーション）
次のオペレーションは、ファイルシステム上で可能である。
”既存のファイルを開く”  OpenFileオペレーションは、ファイルパスを与え、既存ファイルへのとっかかりとなるFileHandleを返す。そのようなハンドルは、すべてのさらなるオペレーションを行うために要求される。ファイルパスは、従来のファイルシステムにおけるパスと非常に似ている（例えば「/aDirectory/aSubdirectory/aFile」）。
【０１６５】
オープンオペレーション中に、ファイルパスを解決しなければならない。すなわち、ルートディレクトリから始まるすべての親ディレクトリは開かれなければならず、それらのエントリが読まれなければならない。例えば、ファイルIDを得るパス「/a/b/c/file」を持つことは、ディレクトリcのエントリを読みために必要とされる。しかし、ディレクトリcを読むために、そのファイルIDを持つことも必要とされる。それはファイルシステムルートまでディレクトリbのエントリなどを読むことが必要とされる。ファイルシステムのルートファイルファイルIDは一定である。従って、いかなる場所からもそれを検索する必要はない。
【０１６６】
”ファイルを作成する”  ファイルシステム構造中の親ディレクトリのFileHandleを与えられたCreateFileオペレーションは、親ディレクトリで要求された名前を持つ通常ファイルかディレクトリを作成する。
”通常ファイルのアクセスコンテンツ”  通常ファイルのFileHandleを与えられたReadFileオペレーションは、ファイルの最も最近のスナップショットを検索するためにGetMostRecentSnapshotを実行し、ファイルコンテンツにReadオペレーションとAppendオペレーションを可能とするインターフェースを提供する。これらは、第５章で説明したものと同じオペレーションである。上記インターフェースは、CommitFileオペレーションも提供し、それは、ファイルコンテンツに対するCommitオペレーションを実行し、その後、新しい通常ファイルのスナップショットを作成するためにdoesWriteSnapshotを実行する。
【０１６７】
”ディレクトリのリスト”  ListDirectoryオペレーションは、FileHandleによって指定されたディレクトリに存在する通常ファイルとディレクトリのリストを返す。
”ファイルの削除”  RemoveFileオペレーションは、削除するファイルとディレクトリを永続的にマークする。ファイル削除の方法はここでは省略する。より複雑であるので、後に別々に説明する。
【０１６８】
（７．１．２．ファイルシステムオペレーションの原子性）
ファイルシステムつまり全てのファイルは、異なるアクセスノードから並列にアクセスされる。特に、ディレクトリコンテンツを修正するオペレーション（CreateFileとRemoveFile）が同時に行われるかもしれない。
【０１６９】
常にディレクトリエントリは一貫していてほしいので、それらの修正を行う間は、前章で説明したトランザクションのメカニズムを用いる。トランザクションが失敗すると、単にオペレーションを繰り返す。すなわち、ディレクトリコンテンツを読み取り、必要な修正を行なって、ディレクトリエントリと共に新しいスナップショットを書き込む。この繰り返しは内部で行われるため、クライアントには見えない。
ディレクトリオペレーションの再開は、様々なクライアントによって頻繁に修正されるディレクトリにとって、比較的大きいオペレーション待ち時間を引き起こす。従って、クライアントが頻繁に同時に修正するようなディレクトリを保持しないようにする。ファイルシステムの構造は、多くのディレクトリを生成させる。従って、単一のクライアントによってのみ修正されるディレクトリを持つよう、できるだけ同時にアクセスされた構造を広げるほうがよい。
【０１７０】
（７．２．ファイルの削除）
HydraTFSにおけるファイルの削除は、２つの個別の段階に分離されている。第１段階では、削除するファイルをマークする。このオペレーションの後、ファイルはもはや見えずアクセスできない。ディレクトリエントリとしてクライアントに見えず、開くことができない。内部では、削除のためにマークされたファイルは、まだディレクトリエントリとして存在する。しかし、それは、既存ファイルのリストの代わりに削除のためにマークされた子のリストに置かれる。
【０１７１】
次のセクションで詳細に説明するが、第２段階ではファイルを物理的に削除する。つまり、HYDRAstor内の削除用のファイルを構成するスナップショットおよびマーカブロックのすべてをマークする。ディレクトリの場合には、子がみな同様に削除され、ディレクトリ削除が繰り返される。その後、エントリは、削除のためにマークされた子のリストから一掃される。
アルゴリズムが第２の段階に進む前、つまり、削除のためにスナップショットをマークとき、誰も削除ファイルを使用することができないようにする。ここで、関連するメカニズムについて簡単に説明する。
第１のステージは、実際にユーザによって実行されたRemoveFileオペレーションである。次に、第２のステージは、ガーベジコレクションルーチンで行われる。
【０１７２】
（７．３．マークされたファイルの削除）
ファイルが削除のためにマークされるとき、それはそれがもはや読み出されないか書き込まれないことを確実にする必要がある。簡単に言うと、メカニズムは、クライアントによって保持されたFileHandlesが、当該handleがまだ存在する（すなわち、削除のためにマークされていない）ファイルを保障するために、定期的にリフレッシュさせなければならない（Thとして期間を定義する）。ファイルが削除用にマークされると、クライアントはもはやそれを操作することができない。ファイルが操作されないことを保証するために、FileHandleリフレッシュ期間より長い期間の待機が実行される。待機持続は、2Thとして確立される。
【０１７３】
ファイルがもはや作動されない（つまり、読み書きされない）ことを保証した後に、それを削除することが行われるかもしれない。すなわち、その既存のスナップショットおよびすべてのマーカブロックのスナップショットルートの全てに、デリーションルートを書き込む。ファイルがディレクトリ、エントリが削除される前に、また、全ての子通常ファイル及びディレクトリである場合、さらにすべての子通常ファイルおよびディレクトリを、再帰的に削除しなければならない。たとえファイルがもはや読み書きできなくても、多くのプロセスによって同時に削除されているかもしれないことに注意すべきである。
はじめに、与えられたファイルのスナップショットおよびマーカブロックのすべてを削除するためにマークするアルゴリズムに着目する。その後、ファイルシステムの範囲で、削除プロセスの説明へと進む。
【０１７４】
（７．３．１．単一ファイルの削除）
単一のファイルの削除は、一般的な削除ルーチンのように、多くのプロセスによって同時に行われる。さらに、HydraTFSのすべてのオペレーションと同様に、それはいつでも中断されるかもしれない。そのような状況でであっても、HYDRAstorブロックの漏れは容認されない。他方、存在しないリテンションルートにデリーションルートを書き、リテンションルートに複数のデリーションルートを書くことは許容される。
ファイル削除の方法は、３つのステップで作動する。初めは、reclamation tail全体が削除用にマークされる。reclamation tailの長さは、通常、最も最近のスナップショットのスナップショットルートに格納されたreclamation tail長さの値から取り出す。
【０１７５】
reclamation tail全体が、HYDRAstor内で削除用にマークされているとき、残されたブロックは、最も最近のスナップショットへのパス上のマーカブロック、および、そのマーカブロックと共に最も最近のスナップショット自体である。第２のステップは、最も最近のスナップショットの削除用マークをすることです。
最後に、第３のステップでは、第１のステップでreclamation tailスナップショットとマーカブロックに削除用マークすることとは対照的に、全てのデリーションルートの書き込み要求が並列に発行され、削除用のマーカブロックの特別なオーダーが必要となる。一つずつ、すべての最も最近のスナップショットのパススナップショットがマークされ、最も最近書かれたスナップショット（最も高い番号）から始まり、１番目のスナップショットで終わる。
【０１７６】
図２１に、３つステップを示す。示されたファイルの最も最近のスナップショットが２６番であり、reclamation tailは、スナップショット１９−２３及び２５から成る。図２１ａの中で示される第１のステップでは、reclamation tail：19、20、21、22、23、25が削除のためにマークされる。その後、第２と第３のステップ（図２１ｂ）で、最も最近のスナップショット２６と、次にそのパススナップショット（24、16、8、4、2、1）が、削除のためにマークされる。（図２１は、ファイル削除中にスナップショットを削除するためのマークの順序を示す。）
【０１７７】
”削除中のクラッシュ”
ファイルを削除するプロセスは、実行の次のステップのうちの１つの間に、クラッシュするかもしれない。
−reclamation tailを削除するためにマークしている間。
−最も最近のスナップショットを削除するためにマークしている間。
−マーカーブロックを削除のためにマークしている間。
【０１７８】
第１のステップ中にクラッシュが生じると、再始動の後、最も最近のスナップショットに格納されたreclamation tail長さに基づいて、一致するreclamation tailが計算される。従って、ステップ１は、悪影響なく始めから繰り返される。
最も最近のスナップショットを指すデリーションルートの書き込みが成功する前にクラッシュが生じると、ステップ１と同じ原理が当てはまる。従って、不運にも再始動後に、ステップ１全体が必要以上に繰り返えされる。次に、クラッシュがデリーションルートを書いた後に生じると、再始動の後のプロセスは直ちにステップ３に移行する。
【０１７９】
ステップ３で、残された唯一のブロックはマーカブロックである。ブロックが削除のためにデュアルバイナリサーチで最後に探索されたものから最初に探索されたものまで順番にマークされるとき、削除のためにそれらをマークすることが中間で中断されると、削除が停止する前に、ブロックは返される。従って、削除は安全に再開する。
GetMostRecentSnapshot手段は、（セクション２．４．４で説明したように）削除のためにマークされたリテンションルートの存在を考慮しなければならない、ことに着目する。リテンションルートが削除用にマークされたことを表すエラー状態が読み出しの間にHYDRAstorによって返されると、アルゴリズムは存在しないブロックと同じ方法でそれを処理する。
【０１８０】
”同時”
削除用の単一ファイルのスナップショットとマーカブロックをマークすることは、複数のプロセスによって並列に実行される。そのような状況で、クラッシュに類似することが起こる。GetMostRecentSnapshotを実行することによって、削除をマークするブロックのセットし、それがまだ存在する場合には、最も最近のスナップショットからreclamation tail長さを読んだあとに、プロセスは、単に指定された順にデリーションルートを書き込む。唯一の欠点は、デリーションルートが、存在していないリテンションルートあるいは既にデリーションルートに対応するリテンションルートの両方に、同時プロセスによって書かれることである。しかしながら、HYDRAstorでは、それは耐えられる振る舞いである。
【０１８１】
（７．３．２．ファイルシステムレベルでのファイルの削除）
ファイルシステムの範囲におけるファイルの削除は、与えられたディレクトリのために、削除のためにマークされたすべての子を削除する、基本的なオペレーションである。後に、削除されたファイルは、ディレクトリエントリリストから除かれる。RemoveFileオペレーションが成功するとき、このオペレーションが引き起こされるか、あるいは、定期的なファイルシステム走査で実行される。しかしながら、両方の方法の組み合わせが望ましい。オペレーションが引き起こされると、削除のためにマークされたファイルは、すぐに削除される。次に、ファイルシステム全体の定期的な走査は、削除されないファイルを永続的に保証する。プロセスが削除用のファイルをマークした時に可能であるが、実際にそれらを削除する前に衝突する。
【０１８２】
このオペレーションの詳細を説明する。ディレクトリで削除用にマークされたファイルの削除は、以下のように行われる。
１．ディレクトリエントリが読まれる。
２．削除する子のセットCは、削除のためにマークされたディレクトリの子のリストに初期化される。
３．削除プロセスは、時間2Thの間、C内のファイルがユーザによってアクセスされないことを保証するのを待つ。
４．Cの各ファイルに対して、セクション７．３．１で説明したスナップショットの削除が実行される（おそらく並列に）。
５．ディレクトリが削除のためにマークされない、あるいは、一時的に削除されない（処理が終了して）ことが保証される。これは、ディレクトリを再び開くことにより行なわれる。
６．ディレクトリはもう一度読まれる。Cに含まれ、削除のためにマークされた子どものリスト中のエントリは撤去され、ディレクトリエントリの新しいスナップショットはトランザクション処理としてコミットされる。kのステップは、コミットが成功するまで繰り返される。
【０１８３】
ディレクトリが別のプロセスによってその間に削除されることがあるため、上記ステップ５で実行されるreopenは必要である。そのような状況で、ディレクトリのエントリの新しいスナップショットをコミットすることは、コミットされたスナップショットの漏れを引き起こす。
ステップ４で削除された子供が通常ファイルでななくディレクトリである場合、そのスナップショットが削除のためにマークされる前に、含まれたファイルを削除しなければならない。従って、ディレクトリのスナップショットが削除のためにマークされる前に、次のステップが行なわれる。
【０１８４】
１．ディレクトリエントリが読まれる（別の例では、削除のためのディレクトリのスナップショットを既にマークしている。そのような場合には、この読み取りは成功しないが、これは問題ではない。単に、削除のためのディレクトリのスナップショットをマークすることに移ってもよい）。
２．各子供cに対して、存在して削除用にマークされることに関係なく、cの削除が行なわれる（さらに、cがディレクトリである場合、このオペレーションは再帰的に実行される）。
【０１８５】
＜第８章＞
（予備的評価）
本章は、HydraTFSで行なわれた実験の結果を示す。その実行は、実験中に完全には終わっていない。重要なことは、全てのファイルシステムの性能に、大きな影響を有する最適化が不足したことである。しかしながら、実験では、様々なセッティングでHydraTFSの振る舞いをよく反映している。
【０１８６】
（８．１．実行）
（８．１．１．現在の特徴）
実験が行われたとき、コア機能のほとんどが実行されていた。ただ、まだ開発中であった削除用のスナップショットをマークすることを除外している。従って、reclamation tail削除もファイル削除オペレーションも評価することができない。削除が機能しないにもかかわらず、セクション６．３．３で説明したマーカーブロックは既に存在していた。
評価する実験は、いくつかの主な最適化を行っていないが、HYDRAstorリクエストは集められたバンドルに送られていない。代わりに、それらは次々に処理され、性能、特にデータ伝送性能が著しく減少した。GetMostRecentSnapshotオペレーションについては、セクション６．１で説明した線形アルゴリズムが実行された。
【０１８７】
（８．１．２．技術）
上記実施は、C++環境で開発された。テストで使用されたバイナリサーチ機能は、GCCコンパイラー（最も高い最適化レベル(-O3)を備えたバージョン4.1.2)でコンパイルされた。その実施は、バージョン1.33.1のBoost libraryが利用された。
HydraTFSは、通信手段としてメッセージパスインターフェースを使用するマルチスレッドアプリケーションで、シングルスレッドモジュールとして実施された。HYDRAstorとの通信は、同じアプリケーションの別のモジュールで実行されるプロキシーによって実行される。両モジュールとも、すなわちプロキシーモジュールとHydraTFSは、並列に作動し、メッセージの受け渡しによって通信する。プロキシーとHYDRAstorの間の通信は、別の専用スレッドによってホストされたネットワークソケットを介している。
【０１８８】
（８．２．テスト環境）
実験装置は、１つのアクセスノードおよび２つのストレージノードからなる単一のHYDRAstorで構成される。各ノードは、それぞれ２つのクワッドコアと、64ビット、3.0GHzのインテルXeonプロセッサを有する。アクセスノードは、8GBのメモリを装備し、ストレージノードは24GBのメモリを装備する。アクセスノードは、ハードウェアRAIDを用いる２つの15K RPM SASハードディスクを装備している。これらのディスクは、テスト中に記録するために使用された。コンピュータはすべて、2.6.18-128 Linuxを実行していた。
【０１８９】
（８．３．実験）
実験は、ロードされたユーザデータがないクリーンなHYDRAstorシステム上で行なわれた。テスト中にHYDRAstorを使用する他のプロセスはない。
HYDRAstorに保存された各レコードは、ランダムデータで満たされた。これは、HYDRAstorに既に存在する同一のデータを備えたレギュラーブロックの数を最小化させるためである。そのような場合では、書き込みオペレーションは重複排除のため著しく早く終了するかもしれず、その結果を変えることはできる。
【０１９０】
（８．３．１．ファイルに追加するレコードの処理性能）
この実験では、レコードを追加する性能を計測する。128MBのデータを含む単一のレギュラーファイルは、各テストケースに応じて作成された。最後に、単一のコミットにより、一連の書き込みが行われる。
図２２に示すケースは、ファイルシステムに書かれたレコードのサイズが異なる。しかしながら、レギュラーブロック全体が満たされるまでリクエストがHYDRAstorに送信されないので、性能に違いはほとんどない。言いかえれば、性能に影響を及ぼす主な要因であるHYDRAstorリクエストの量およびサイズは、すべての場合に同じである。（図２２は、ファイルにレコードを追加したときの性能を示す。）
約6MB/sという性能の結果は、100MB/sを超えるHYDRAstorシステムでの単一のアクセスノードの性能と比較して非常に低く、このことには何も価値がない。見つからないリクエスト集合の導入後に改善するべきである（セクション８．１．１を参照）。
【０１９１】
（８．３．２．レコード追加とコミットの性能）
この実験は、各追加後に変更内容がコミットされる（CommitFileが実行される）が、上記のものに類似する。8MBのデータを含む単一のレギュラーファイルは、テストケース毎に作成された。
図２３を見ると、性能は、追加されたレコードのサイズ、従って、コミットオペレーションの数、に関係することがわかる。より大きなレコード、より小さなコミットが作られる。変更されたファイルに関連するHYDRAstorの書き込みレギュラーブロックリクエストの全ての保留を待つことを意味するため、コミットは、コストのかかるオペレーションである。（図２３は、コミットと伴うレコード追加の性能を示す。）
【０１９２】
それとは別に、あるデータは、HYDRAstorに複数回書かれるかもしれない。最大のレギュラーブロックサイズ（64kB）より小さいレコードを考慮することとする。コミットを行なわなければならない場合、HYDRAstorにそれを保存しなければならない。しかしながら、さらなる追加が生じると、あるデータ（１つあるいは多くのレコード、あるいは、レコードの一部）は、このレコードと共にブロックに置かれるかもしれない。その後、別のコミットが生じると、同じレコードは、新しいレギュラーブロックで再びHYDRAstorに書かれる。このような状況は、ブロックがレコードで完全に満たされるまで、複数回繰り返される。
【０１９３】
（８．３．３．読み取りの性能）
HydraTFSで、レギュラーファイルを開いた後に、ファイル上で読み取りを実行することができる。ユーザは、それらのすべてが読み取られると、直ちに読み取るレコードの数を指定し、単一の返答でそれらのコンテンツを受け取る。続くリクエストは、連続するレコードを返す。すなわち、ファイルは連続して読まれる。スナップショットの構造は、一度に１つのレギュラーブロックに関して繰り返される。先読みも他の最適化も使用されない。
この実験では、単一のリクエストで読まれる様々な数のレコードで読み取り性能が測定される。4096のレコードから成る128MBのファイルや、32kBの各々および単一のスナップショットが読まれる。
【０１９４】
結果は、性能はリクエストサイズの増加とともに著しく変化しない。より大きなリクエストが送信される場合、それはわずかに増加し、これは、より少ない数のHydraTFSリクエストに関連するプロセッサ使用の減少と関係がある。しかしながら、HYDRAstorレギュラーブロック読み取りリクエストの数は同じままである。追加のケースと同様に、読み取り性能は、見当たらないリクエスト集合の導入の後に改善すべきである。（図２４は、読み取り性能を示す。）
【０１９５】
（８．３．４．GetMostRecentSnapshotの所要時間）
この実験では、GetMostRecentSnapshotの時間が測定された。テストケースでは、スナップショットシーケンスの長さが変化するファイルが作成された。その後、そのようなファイルの最も最近のスナップショットを探すアルゴリズムが実行され、その所要時間が計測された。セクション６．２に、デュアルバイナリサーチアルゴリズムに対する分析的な評価を行っている。その結果を図２５に示す。図２５は、最も最近のスナップショットを検索するための時間を示す。
【０１９６】
絶対値としての読み取りのとき、アルゴリズム間の違いは大きくはない。しかしながら、それらははるかにより重要になるかもしれない。実験は、ロードされないシステムで行われ、支配的なオペレーションであるHYDRAstorのリテンションルート読み取り要求の待ち時間は、10msのオーダーであった。しかしながら、システムがロードされる場合、それは著しく大きくなる場合がある。そのような状況では、１秒を超えるかもしれない。
【０１９７】
（８．３．５．ディレクトリ上のオペレーションの所要時間）
この実験では、多くのサブディレクトリが一つのディレクトリで作成されている。サブディレクトリ生成リクエストは、次々に出される。テストケースは、作成されたサブディレクトリの数によって異なる（図２６参照）。（図２６は、シングルスレッドによって実行されたcreate directoryオペレーションの時間を示す。）
サブディレクトリの数が多い場合については、単一オペレーションの平均時間が比較的より高いと言える。サブディレクトリの数が少ない場合については、速度は、毎秒約10オペレーションであるが、2048のサブディレクトリが作成される場合には、2〜3まで落ちる。それは、親ディレクトリエントリがリテンションルートによって指示されるレギュラーブロックに格納されているため、ディレクトリエントリのサイズが単一リテンションルートに適応することをやめると、サブディレクトリを作成することで、より多くのブロックを読み書きが生じる、という事実によって説明できる。そのような状況においては、HYDRAstorオペレーションの数は増加する（図２７参照）。（図２７は、フラット構造であることと比較して、ツリーの増加に伴うオペレーションの数が増加を示す。）
【０１９８】
（８．３．６．ディレクトリ上の並列処理の所要時間）
この実験では、複数プロセスは関係していない。各プロセスは、１つのディレクトリに１２８のサブディレクトリを作成し、すべてのプロセスに共通する。書込みプロセスの数は、テストケース間で変わる（図２８、”同じファイル”を参照）。（図２８は、"create directory"オペレーションの時間の比較を示す。）
この実験では、同じディレクトリへの並列書き込みアクセスのコストを示す。アクセスするプロセスの数を増加させることは、性能が著しく減少することとなる。これは、同時アクセスによりいくつかのオペレーションを再開しなければならないという事実によって引き起こされる。従って、HYDRAstorにおけるブロックオペレーションの数が増加する（図２９（ｂ）参照）。
【０１９９】
別の実験では、各プロセスで、ディレクトリの数の変更が行われる（図２８の「異なるファイル」を参照）。スレッドの数の増加に関係して減速にもかかわらず、多数のディレクトリに対するオペレーションの性能は単一のディレクトリの場合よりも著しく高い。
比較のために、単一のプロセスによって同数のディレクトリ上で連続して作動する時間の試算を、図２８に示す。期待されるように、コンフリクトがないため、シングルスレッドによって単一のディレクトリ上で実行される多くのオペレーションは、マルチスレッドによって並列に実行された同じ数のオペレーションよりも短い。従って、再開されるオペレーションはない。
【０２００】
（８．３．７．ツリーの深い位置にあるディレクトリを開くこと）
この実験では、深さが変わるディレクトリ構造が作られている。各ディレクトリは、１つのスナップショットからなり、そのエントリーリストは、ゼロエントリ（リーフディレクトリ）か、あるいは、１つのエントリ（残りのディレクトリ）のいずれかからなる。
パス（すなわち、OpenFileオペレーションによる"/level1Dir/level2Dir/.../levelNDir"）が与えられたリーフディレクトリの検索時間を、図３０に示す。ファイルが構造的により深く位置している場合、オープン時間が多くかかることがわかる。これは、そのような構造では、ターゲットディレクトリへのパス上のディレクトリすべてが、連続して、すなわち、初めは「/」、次に「level1Dir」、「level2Dir」などと、開かなければならないからである。
【０２０１】
オープンは時間を消費するかもしれないが、そのような深い位置にあるレギュラーファイルまたはディレクトリに対する他のオペレーションの性能は、他のどんな場所に位置したディレクトリとは変わらない。これは、オープン後は、各ファイルはそのファイルIDによって参照され、その内容を検索するか更新するその親ディレクトリのいずれも読み取る必要がないからである。
【０２０２】
＜第９章＞
（関連する研究）
（９．１．HydraFS）
HydraTFSに類似するHydra File System "HFS"は、HYDRAstor上で作動する。これらファイルシステム間の主な違いは、設計の目標である。その主用途がバックアップ機器の一部であるため、HydraFSは、高い読み取り／書き込みストリーミング性能を目指すファイルシステムである。さらに、それは、典型的なUnixファイルシステム・インターフェースを提供し、従って、標準、汎用のファイルシステムとして自由に使用されうる。一方で、アプリケーションモジュールとしてHydraTFSは機能する。
【０２０３】
他の基本的な違いは、HydraFSは１つのアクセスノードからのみアクセスされるということである。一方で、HydraTFSは、一度にすべてのアクセスノードからアクセスすることができる。HydraFSの永続的なレイアウトは、リテンションルートによって表わされるルート、スーパーブロックを備えた単一のツリーとして構築される。スーパーブロックは、inodeマップ構造のルートを指す。それは、inodeの数によってソートされたファイルとディレクトリをすべて含む。
【０２０４】
次に、各inodeマップエントリは、単一ファイルを構築するツリーを指す。このツリーは、HydraTFSの中の単一スナップショットのツリーに似ている。このアーキテクチャは、ファイルシステム全体のスナップショットを容易に準備させることができ、古くなると、削除する代わりにファイルシステムツリーのリテンションルートを保存することに十分である。満足な性能を達成するためにツリーのブロックが積極的に記憶されなければならず、ファイルへの書き込みがルートに至るまでパス上のツリーのブロックをすべて変更することを伴うため、HydraFSは、多数のファイル上で同時に作動することで不完全に実行されるかもしれない。HydraTFSの場合には、ファイルが独立し、異なるものに対するオペレーションはどんなレベルでも妨げない。
【０２０５】
HydraTFSの選択肢からHydraFSを除く重要な理由は、HydraFSが実データバイトだけが許可されるが、HYDRAstorコンテンツアドレスを格納できないという事実である。それとは別に、それはトランザクション処理ではなく、従って、HydraFSの使用法は、例えば、データベースといった追加レイヤーの導入を必要とする。最後に、HydraFSが一度に単一のANからアクセス可能なので、このアクセスノードと他のものの間の接続が必要であるが、HydraTFSにはそのような要求はない。
【０２０６】
（９．２．他のソリューション）
いくつかの既存のファイルシステムは、高い有効性を達成するために作成されている。Ivy "Ivy"は、分散化されたピア・ツー・ピア・ファイルシステムである。ファイルシステムにデータを書く各ユーザ（分散されたハッシュテーブルのまわりで置かれた）は、変更のログを保持する。参加者は全て、他のもののログを走査し、プライベートスナップショットに変更を適用する。ネットワーク分割の場合には、ファイルシステムに複数のバージョンが現われるかもしれない。そのような状況では、外部矛盾解決手段が使用されるかもしれない。
【０２０７】
Ceph "Ceph"ファイルシステムは、障害の単一ポイント無しに完全に分散化される。データは、フォールトトレラントにシームレスに複製される。ディスク障害の場合には、目標冗長度が回復されるまで、複製は他のディスクにデータを分配するために使用される。Google Chubby "Chubby"は、ファイルシステムのものに似ているインターフェースを提供する、分配されたロックサービスである。小さいファイルは、常に全体として読み書きされる。Googleでは主に、小さなメタデータにとって非常に有効な場所として、等価なマシンのセットからリーダーを選ぶ課題に対処するために使用されるGoogleファイルシステムとBigtableは、Chubbyを利用するシステムの顕著な例である。Chubbyの実行では、BerkeleyDB "BerkDB"の複製バージョンに似ているソリューションを使用する。データベースログは、分配されたコンセンサスプロトコルの助けを借りて、マシン間に分配される。
【０２０８】
ファイルシステムのデータとメタデータの一貫性は、様々な方法で達成され、外部ツールは共通のソリューションである。例えば、大きなクラスタを目的とした大規模な並列のファイルシステムであるLustre "Lustre"は、ファイルデータとメタデータの完全な状態を保護するために、分配されたロックマネージャーを使用する。
トランザクションNTFS（略してTxF）"TxF"は、NTFSファイルシステムでのトランザクションオペレーションを導入するWindowsシステムでのコンポーネントである。Windowsカーネルモードで作動する汎用のトランザクションエンジンであるKernel Transaction Manager "KTM"となズ蹴られたコンポーネントを使用する。
【０２０９】
HydraTFSのスナップショットに似ている考えを導入するファイルシステムの例として、Elephant "Elephant"がある。Elephantは、選択され価値のあるファイルの古いバージョンを自動的に保持したままとする。書き込みモードにおける各オープンオペレーションにおいては、開かれたファイルの新バージョンが作成される。対応するクローズオペレーションはバージョンを終了させる。HydraTFSと異なり、Elephantは、古いファイルバージョンへのアクセスを提供する。実際、これはその中核機能のうちの１つである。ファイルが古くなると、古いファイルバージョンは様々なポリシ従って直ちにあるいは将来に削除される。特に、全てのファイルバージョンは、ファイルの全ての修正履歴を提供して格納される。
【０２１０】
ファイルシステムバックグラウンドクリーンアップは、フラッシュドライブ用のファイルシステムで一般的である。例えば、JFFS2 "JFFS2"で、ブロックレベルで生じる。ガベージコレクションは、特別のブロックに対するI/Oオペレーションを集めて、そのようなオペレーションの数を減らすために導入されている。これはフラッシュメモリの耐用性に不可欠である。
HFSとは別に、CASブロックストアのために設計された他のファイルシステムが存在する。企業市場を目的としたCASであるCentera "Centera"は、ファイルシステムインターフェースを提供する。しかしながら、ファイルシステムのメタデータは、ローカルに保存され、その定期的なバックアップはCASに作られる。Venti "Venti"では、ブロックは削除されない。従って、ファイルシステムのスナップショットは記憶装置を消耗しないように低周期で作られる。
【０２１１】
（９．３．結論）
列挙されたファイルシステムはどれも、HydraTFSの代わりに使用することができない。これは、コンテンツアドレスの格納が必要であり、要求されたファイルシステムがHYDRAstor上で作動しなければならないためである。HYDRAstorに既存のファイルシステムのいずれかを組み込むことができるのかどうかは疑わしい。しかしながら、それが可能であっても、必要条件を満たすようなプロセスは、新しいファイルシステムを設計して導入するよりは、おそらくはるかに多くの作業を必要とするであろう。
【０２１２】
＜第１０章＞
（結論）
本論文で説明したHydraTFSは、クライアントノード間のいかなる追加のネットワーク接続を必要としないCASシステムで機能する、分散型で拡張可能なトランザクションファイルシステムとして、設計される。実験結果は、HydraTFSが設計目標を達成し適度な性能で機能することを示しているが、それでもなお、多くの面でさらに最適化することができる。
【０２１３】
本論に含まれる考察と考えは、HydraTFSのさらなる最適化を出発点として使用することができる。そして、それらは、HYDRAstor以外にコンテンツアドレスストレージ上で作動する同様の特徴を有するファイルシステムの開発に有益となる。HydraTFSは、商用HYDRAstor製品に現在統合されている。
【０２１４】
＜付記＞
上記実施形態の一部又は全部は、以下の付記のようにも記載されうる。以下、本発明におけるストレージ装置（図３１参照）、プログラム、情報処理方法の構成の概略を説明する。但し、本発明は、以下の構成に限定されない。
【０２１５】
（付記１）
記憶装置１２０に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶するデータ書き込み手段１１１と、
前記記憶装置１２０に記憶された同一の記憶データのうち、最新の記憶データを特定するデータ特定手段１１２と、を備え、
前記データ書き込み手段１１１は、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置１２０に記憶し、
前記データ特定手段１１２は、前記記憶装置１２０内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定する、
ストレージ装置１００。
【０２１６】
（付記２）
付記１に記載のストレージ装置であって、
前記データ特定手段は、
前記記憶装置内に前記更新情報が存在した最大の２ｉの値を第一更新情報とすると共に、２ｉ＋１の値を第二更新情報とし、
前記記憶装置内に、前記第一更新情報と前記第二更新情報との中間値に対応する前記更新情報が存在するか否かを調べる更新情報検索処理を行うと共に、
前記記憶装置内に、前記中間値に対応する前記更新情報が存在した場合は当該中間値を前記第一更新情報とし、前記中間値に対応する前記更新情報が存在しない場合には当該中間値を前記第二更新情報とする中間値置き換え処理を行い、
前記更新情報検索処理と前記中間値置き換え処理とを繰り返し実行して、前記記憶装置内に存在する前記更新情報の最大値を特定する、
ストレージ装置。
【０２１７】
（付記３）
付記２に記載のストレージ装置であって、
最新ではない前記記憶データを構成する前記実データ及び当該実データに関連付けられた前記更新情報を前記記憶装置内から削除するデータ削除手段を備え、
前記データ特定手段は、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報を非削除対象更新情報として特定し、
前記データ削除手段は、前記非削除対象更新情報として特定された前記更新情報を前記記憶装置内から削除する情報から除外する、
ストレージ装置。
【０２１８】
（付記４）
付記３に記載のストレージ装置であって、
前記データ特定手段は、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報と、前記中間値とされた前記更新情報と、特定された最大値の前記更新情報と、を前記非削除対象更新情報として特定する、
ストレージ装置。
【０２１９】
（付記５）
付記３又は４に記載のストレージ装置であって、
前記データ特定手段は、前記記憶装置内に存在する前記更新情報の最大値よりも小さい値の前記更新情報に関連付けられた前記実データにて構成される記憶データがアクセスされている場合に、当該アクセスされている記憶データを構成する前記実データに関連付けられている前記更新情報であるアクセス対象更新情報と、当該アクセス対象更新情報を前記データ特定手段にて前記更新情報の最大値として特定する場合に検索され前記非削除対象更新情報して特定される前記更新情報とを、当該非削除対象更新情報に含める、
ストレージ装置。
【０２２０】
（付記６）
付記５に記載のストレージ装置であって、
前記データ特定手段は、前記記憶装置内に存在する前記更新情報の最大値よりも小さく、前記アクセス対象更新情報の値よりも大きい値の前記更新情報を、前記非削除対象更新情報に含める、
ストレージ装置。
【０２２１】
（付記７）
付記３乃至６のいずれかに記載のストレージ装置であって、
前記データ削除手段は、前記非削除対象更新情報として特定された前記更新情報に関連付けられた前記実データを、前記記憶装置内から削除する、
ストレージ装置。
【０２２２】
（付記８）
付記１乃至７のいずれかに記載のストレージ装置であって、
前記データ書き込み手段は、前記更新情報を、同一の前記記憶データを特定するデータ特定情報に関連付けて記憶する、
ストレージ装置。
【０２２３】
（付記９）
付記８に記載のストレージ装置であって、
前記データ書き込み手段は、
前記記憶データを複数の実データに分割して前記記憶装置に記憶すると共に、当該各実データを参照する各参照データと、前記記憶データを構成する複数の実データを参照する複数の前記参照データにアクセス可能な前記データ特定情報と、を記憶し、
前記記憶データを更新する際に、前記記憶装置に既に記憶されている実データと同一内容の他の実データを記憶装置に記憶する場合には、当該記憶装置に既に記憶されている実データを、当該実データを参照する前記参照データを用いて前記他の実データとして参照させて当該他の実データを記憶し、前記記憶装置に記憶されていない実データを記憶する場合には、当該実データを記憶装置に新たに記憶し、
前記記憶データが更新される度に、当該更新された記憶データを構成する複数の実データを参照する複数の前記参照データにアクセス可能な前記データ特定情報を新たに生成して記憶する、
ストレージ装置。
【０２２４】
（付記１０）
情報処理装置に、
記憶装置に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶するデータ書き込み手段と、
前記記憶装置に記憶された同一の記憶データのうち、最新の記憶データを特定するデータ特定手段と、を実現させると共に、
前記データ書き込み手段は、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置に記憶し、
前記データ特定手段は、前記記憶装置内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定する、
ことを実現させるためのプログラム。
【０２２５】
（付記１１）
付記１０に記載のプログラムであって、
前記データ特定手段は、
前記記憶装置内に前記更新情報が存在した最大の２ｉの値を第一更新情報とすると共に、２ｉ＋１の値を第二更新情報とし、
前記記憶装置内に、前記第一更新情報と前記第二更新情報との中間値に対応する前記更新情報が存在するか否かを調べる更新情報検索処理を行うと共に、
前記記憶装置内に、前記中間値に対応する前記更新情報が存在した場合は当該中間値を前記第一更新情報とし、前記中間値に対応する前記更新情報が存在しない場合には当該中間値を前記第二更新情報とする中間値置き換え処理を行い、
前記更新情報検索処理と前記中間値置き換え処理とを繰り返し実行して、前記記憶装置内に存在する前記更新情報の最大値を特定する、
プログラム。
【０２２６】
（付記１２）
付記１１に記載のプログラムであって、
情報処理装置に、最新ではない前記記憶データを構成する前記実データ及び当該実データに関連付けられた前記更新情報を前記記憶装置内から削除するデータ削除手段をさらに実現させると共に、
前記データ特定手段は、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報を非削除対象更新情報として特定し、
前記データ削除手段は、前記非削除対象更新情報として特定された前記更新情報を前記記憶装置内から削除する情報から除外する、
プログラム。
【０２２７】
（付記１３）
付記１２に記載のプログラムであって、
前記データ特定手段は、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報と、前記中間値とされた前記更新情報と、特定された最大値の前記更新情報と、を前記非削除対象更新情報として特定する、
プログラム。
【０２２８】
（付記１４）
記憶装置に、書込み対象となる記憶データを構成する実データを記憶すると共に、当該記憶データの内容が更新される毎に当該更新された記憶データを構成する実データを新たに記憶してデータを書き込み、このとき、前記記憶データを構成する実データに、当該記憶データが更新される毎に値が１ずつ増加する更新情報を関連付けて前記記憶装置に記憶し、
前記記憶装置に記憶された同一の記憶データのうち、最新の記憶データを特定する際に、前記記憶装置内に、２ｉ（ｉは、０以上の整数）の値の前記更新情報が存在するか否かを前記ｉの値が小さい順に調べ、前記更新情報が存在した最大の２ｉの値と２ｉ＋１との間の値から、存在する前記更新情報の最大値を特定し、当該更新情報の最大値に関連付けられた実データにて構成される記憶データを最新の記憶データとして特定する、
情報処理方法。
【０２２９】
（付記１５）
付記１４に記載の情報処理方法であって、
前記最新のデータを特定する際に、
前記記憶装置内に前記更新情報が存在した最大の２ｉの値を第一更新情報とすると共に、２ｉ＋１の値を第二更新情報とし、
前記記憶装置内に、前記第一更新情報と前記第二更新情報との中間値に対応する前記更新情報が存在するか否かを調べる更新情報検索処理を行うと共に、
前記記憶装置内に、前記中間値に対応する前記更新情報が存在した場合は当該中間値を前記第一更新情報とし、前記中間値に対応する前記更新情報が存在しない場合には当該中間値を前記第二更新情報とする中間値置き換え処理を行い、
前記更新情報検索処理と前記中間値置き換え処理とを繰り返し実行して、前記記憶装置内に存在する前記更新情報の最大値を特定する、
情報処理方法。
【０２３０】
（付記１６）
付記１５に記載の情報処理方法であって、
前記最新のデータを特定する際に、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報を非削除対象更新情報として特定し、
最新ではない前記記憶データを構成する前記実データ及び当該実データに関連付けられた前記更新情報を前記記憶装置内から削除する際に、前記非削除対象更新情報として特定された前記更新情報を前記記憶装置内から削除する情報から除外する、
情報処理方法。
【０２３１】
（付記１７）
付記１６に記載の情報処理方法であって、
前記最新のデータを特定する際に、前記更新情報の最大値を特定する際に検索され、前記記憶装置内に存在した２ｉの値に対応する前記更新情報と、前記中間値とされた前記更新情報と、特定された最大値の前記更新情報と、を前記非削除対象更新情報として特定する、
情報処理方法。
【０２３２】
なお、上述したプログラムは、記憶装置に記憶されていたり、コンピュータが読み取り可能な記録媒体に記録されている。例えば、記録媒体は、フレキシブルディスク、光ディスク、光磁気ディスク、及び、半導体メモリ等の可搬性を有する媒体である。
【０２３３】
以上、上記実施形態や付記を参照して本願発明を説明したが、本願発明は、上述した実施形態に限定されるものではない。本願発明の構成や詳細には、本願発明の範囲内で当業者が理解しうる様々な変更をすることができる。
【符号の説明】
【０２３４】
１  ストレージシステム
２  アクセラレータノード
３  ストレージノード
４  バックアップシステム
５  バックアップ対象装置
１１  データ書き込み部
１２  データ読み出し部
１３  データ特定部
１４  データ削除部
２０  記憶装置
３０  アプリケーション
１００  ストレージ装置
１１１  データ書き込み手段
１１２  データ特定手段
１２０  記憶装置
【図１】
0005500309.tif 000003
【図２】
0005500309.tif 000004
【図３】
0005500309.tif 000005
【図４】
0005500309.tif 000006
【図５】
0005500309.tif 000007
【図６】
0005500309.tif 000008
【図７】
0005500309.tif 000009
【図８】
0005500309.tif 000010
【図９】
0005500309.tif 000011
【図１０】
0005500309.tif 000012
【図１１】
0005500309.tif 000013
【図１２】
0005500309.tif 000014
【図１３】
0005500309.tif 000015
【図１４】
0005500309.tif 000016
【図１５】
0005500309.tif 000017
【図１６ａ】
0005500309.tif 000018
【図１６ｂ】
0005500309.tif 000019
【図１６ｃ】
0005500309.tif 000020
【図１６ｄ】
0005500309.tif 000021
【図１７】
0005500309.tif 000022
【図１８】
0005500309.tif 000023
【図１９ａ】
0005500309.tif 000024
【図１９ｂ】
0005500309.tif 000025
【図２０ａ】
0005500309.tif 000026
【図２０ｂ】
0005500309.tif 000027
【図２０ｃ】
0005500309.tif 000028
【図２１ａ】
0005500309.tif 000029
【図２１ｂ】
0005500309.tif 000030
【図２２】
0005500309.tif 000031
【図２３】
0005500309.tif 000032
【図２４】
0005500309.tif 000033
【図２５】
0005500309.tif 000034
【図２６】
0005500309.tif 000035
【図２７】
0005500309.tif 000036
【図２８】
0005500309.tif 000037
【図２９】
0005500309.tif 000038
【図３０】
0005500309.tif 000039
【図３１】
0005500309.tif 000040