ZFS – Copy on Write -

はじめに

Solaris 10 6/06 にて初めてインプリされ、現在の Oracle Solaris 一番のストロングポイントと言えるZFS について、特徴的な機能を紹介させていただこうと思っております。
第一回は、Copy on Write を取り上げて参ります。

ハードディスクドライブ上のファイルイメージ

まず、ハードディスクドライブ(以下 HDD)上に格納されたファイルイメージについて、簡単にふれておきます。HDD上の最小のデータ格納領域単位としてブロックと呼ばれるものがあります。このブロックの集まりがファイルということになります。

そのファイルとブロックの関係ですが、1ファイルが連続したブロックに格納されているとは限りません。連続したブロックの場合もあれば、バラバラに分散してしまっている場合もあります。(これを整理するのが、windows のデフラグという処理にあたると言えば、分かりやすいでしょうか。)

あるファイルを作成する際に、どのくらい連続したブロックを確保するのか、それとも、必要最小限の連続したブロックしか確保しないのかは、そのアプリケーションに依存します。ファイルは書き換えが発生し、より大きな容量が必要になる場合もありますし、逆に、小さな容量でカバーできるようになる場合もあります。その際に、必要になった分だけ容量を追加で確保したり、不要になった分をリリース(解放)したりということを繰り返しているとファイルの断片化は進みます。なので、小さなファイルを更新が多いアプリケーションなどは、一定の領域を確保し、そのファイルが存在する限り、その領域はリリースせずに確保し続けることでファイルの断片化を押さえるような仕組みを取ります。その確保した領域で足りなくなってしまった場合には、また、ある一定の領域をまとめて確保することで、断片化を押さえるのです。

1ファイルあたりの断片数の大小はありますが、いずれにせよ、断片化する可能性はあります。OS(オペレーティング・システム)は、あるファイルがHDD上のどことどこに格納されているのかという、アドレス情報をHDD上にもっています。あるファイルに対して、read 処理を行う場合は、そのアドレス情報の収集を行い、そのアドレスにあるデータを収集し、ファイルというものが復元されます。

ここまでは、前置きになります。理解しておいて欲しいことをまとめます。

  • HDD上の最小データ格納領域単位=ブロック
  • ファイルとはブロックに格納されたデータの集まり
  • HDD上のどこに何が格納されているかをまとめたアドレス帳のようなものがある

一般的なファイル編集の内部処理

さて、ここから、少しずつ本題に入ります。あるファイルに対しての編集処理を行うことをイメージしてください。ファイルの断片が格納されたアドレス情報を収集し、そのアドレスに格納されたデータを読み込みます。続いて、編集された部分に更新処理を行い、アドレス情報の更新を行い終了です。およそ、ファイルの編集処理はこのような流れで処理されます。

  1. ファイルの断片が格納されたアドレス情報の収集
  2. 収集したアドレスに格納されたデータを読み込み
  3. 編集された部分に更新処理を加える
  4. ファイルのアドレス情報を更新する

HDD上の断片イメージ
ここで一つ問題です。3の処理が始まり、4の処理が終わる前のタイミングでサーバが停止したら、どうなるでしょうか。サーバが停止した原因を取り除き、サーバを立ち上げると、どうなっていると考えられるでしょうか。

考えられるリスクとしては主に以下の通りです。

  • そのファイルが壊れてしまう
  • そのファイルが壊れているのにOSが気付かずに、後々、それが露呈する

こういった事象が起こってしまった結果、アプリケーションが正しく起動できないなどの二次的な障害に至ることも考えられます。

例えば、PCであれば、絶えずHDDへの書き込み処理を行なっている訳ではありませんし、突然、PCがダウンしても、ファイルが壊れたりすることも稀ですし、仮に、ファイルが壊れてしまったとしても、ユーザが一人ですから、どのファイルが壊れている可能性があるかを特定できる場合もありますし、それができれば、対処の仕方はあります。しかし、サーバであれば、その用途によっては、絶えずHDDへの書き込みを行なっているものもあり、どのファイルが壊れているかの特定も難しく、対処や復旧は大幅に難易度が上がってしまいます。

このようなリスクを最小限に押さえるアーキテクチャとしてZFSのCopy on Writeという機能が、とても有効になります。

Copy on Write 機能におけるファイル編集の内部処理

Copy on Write(以下 CoW)での、ファイルの更新は次のような手順にて行います。Copy on Write

  1. ファイルの断片が格納されたアドレス情報の収集・・・①
  2. 収集したアドレスに格納されたデータを読み込み
  3. 書き込みを行うブロックのコピーを空き領域に作成・・・②
  4. コピーに対して、編集された部分の更新を反映・・・③
  5. ファイルのアドレス情報を更新
  6. コピー元の領域を解放・・・④

この処理が終わる前にサーバが停止した場合には、どうなるでしょうか。サーバが停止した要因を取り除き、サーバを立ち上げると、どうなっていると考えられるでしょうか。

非常に高い確率で処理前の状態ではありますが、ファイルは正常のまま残存していることになります。ファイルのアドレス情報を更新している際に、サーバが停止してしまった場合には、ファイルが壊れてしまうリスクは考えられますが、それも更新量が、ファイルのデータ領域の更新に比べて、ファイルのアドレス領域はごく小さい更新量となるので、そのリスクが大幅に低下します。

もちろん、想定外の事象により、ファイル破損に至る可能性が全くない訳ではありませんが、ZFS のCoW機能により、リスクを大幅に低減できたことは間違いありません。

次回は、このCoW機能により実現が容易になったsnapshotについて、ご紹介いたします。

※本ドキュメントはIT機器選定を行う立場でありながら、比較的ライトなユーザを対象に紹介しております。あらかじめご理解くださいますよう、お願い申し上げます。