ファイルシステムの基礎知識
メタ領域とデータ領域
Windows で利用される NTFS や、Linux で利用される XFS 等の一般的なファイルシステムでは、ファイルの基本情報・メタ情報を格納する『メタ領域』と、ファイルのデータを格納する『データ領域』でディスク利用領域を分けています。
メタ領域は Windows だと『MFT 領域』、Linux だと『i-node 領域』と呼ばれたりします。メタ領域には『ファイル名』や『ファイルサイズ』、『アクセス権』、『ディスクの割当ブロックアドレス』等のメタ属性および属性値が格納されます。
データ領域には、例えばテキストエディタで『拝啓おふくろさま~』という文字列を書いて保存すれば、このデータがデータ領域に保存されます。
厳密には、Windows の場合はデータを保存する場所を『$DATA』というメタ属性に含めており、扱いが Linux 系のファイルシステムと異なりますが、扱いは似ているので、ここではこのように解釈します。
メタ領域はファイルシステムフォーマット時に、環境に応じて全体総量が予約されます。
1 ファイル当たりのサイズは固定長(512 B ~ 1 KB程度)です。この固定長の中に各種メタ情報が格納されます。
Linux の場合は予約したメタ領域が無くなると『i-node が枯渇した』と表現され、ディスクに空きがあるのにファイルが作れない状態になりますが、Windows の場合は枯渇する前に自動で拡張する機能があるようです。
ブロックとは
ディスクへのデータ読み込み・書き込みは『ブロック』という単位で行われます。最近のブロックサイズは 4 KB ~ 数 MB 程度です。つまり、1 回の読み書きで 4 KB ずつディスクからメモリ等へ入出力されるのです。
ディスクはブロック単位にアドレスが振られており、ディスクへの読み書きの命令はブロックアドレスを指定して行われます。
ブロックサイズはファイルシステムのフォーマット時に決定します。メタ領域とデータ領域では別のブロックサイズが使われます。
Windows ではブロックサイズのことを『クラスターサイズ』もしくは『アロケーションユニットサイズ』と呼びます。
Windows でクラスターサイズを確認するには、管理者権限でコマンドプロンプトを起動し、"fsutil fsinfo ntfsinfo c:" コマンドを使います。
『クラスターあたりのバイト数』がデータ領域のクラスターサイズを意味し、『ファイル セグメントあたりのバイト数』がメタ領域 (MFT領域) のクラスターサイズを意味します(前述の『1 ファイル当たりのサイズは固定長』と同義)。
Linux の XFS のブロックサイズの確認方法については以下を参照下さい。
ブロック割当とは
メタ領域に格納される『割当ブロックアドレス』は、そのファイルが利用するブロックアドレス範囲を示します。
※厳密には、Windows の場合は異なるのですが、ここではその様に捉えます。
ディスクはブロック単位で使われるので、1 byte 等の小さいデータをファイルに保存しても、ディスクとしてはブロックサイズ分を消費します。
例えばブロックサイズが 4 KB でフォーマットした XFS において、Linux の "ls -lsh" コマンドでファイルを見てみます。test1.txt が空ファイル、test2.txt が "a" の1文字だけ書き込んだファイルです。
[root@localhost test]# ls -lsh
合計 4.0K
0 -rw-r--r--. 1 root root 0 7月 6 10:31 test1.txt
4.0K -rw-r--r--. 1 root root 1 7月 6 10:31 test2.txt
[root@localhost test]#
一番左が割当ブロックサイズ、「7月」の左にある数字が『ファイルのサイズ』属性値です。test1.txt では割当ブロックサイズもファイルサイズも 0 ですが、test2.txt ではファイルサイズが 1 (byte) に対し、割当ブロックサイズは 4.0 KB となっています。
Windows だとプロパティで「サイズ」と「ディスク上のサイズ」が異なる場合があるかと思いますが、「サイズ」が『ファイルのサイズ』に該当し、「ディスク上のサイズ」が『割当ブロックサイズ』に該当します。
ファイルの削除と割当済ブロック
ファイルシステム上からファイルを「(ゴミ箱移動ではなく)完全に削除」した場合の一般的な動作としては、ファイルのメタ属性『ディスクの割当ブロック』から、割当ブロックを外すだけです。つまり、割当中に書き換えた 0 1 の bit はそのまま残ります。
データ復旧業者はこの仕組みを利用してデータ復旧を行っているのです。
つまり、ファイルにブロックを割り当てるとき、そのブロックは全 bit が 0 になっているとは限りませんし、大きいファイルのダウンロード・削除を繰り返す環境では多くの場合なりません。
ブロック割当時にブロック内の全てのを 0 に書き換える操作が必要になります。
シンプロビジョニングとは
先の例では『ファイルサイズ』<『割当ブロックサイズ』でしたが、ファイルサイズを大きく見せ、実際の割当を少なくすることもできます。
これを実現したのが『シンプロビジョニング』という技術です。
シンプロビジョニングを実装したファイルをスパースファイルと呼びます。
例えば、ファイルサイズとしては 1 MB と宣言しつつ、ブロック単位で全て 0 となる範囲にはブロック割当を行わない、ということができます。
VMware 等では仮想マシンのディスク領域をファイルとして扱います。一度ファイルサイズを決めると、そのあとにサイズを増減するのは結構大変だったりします。なので最初から大きめのサイズを取っておくのが良いです。
ですが例えば仮想マシン 50 台に対し、それぞれに 100 GB の仮想ディスクを作るとそれだけで 5 TB も消費してしまいます。これでは効率が悪いです。
シンプロビジョニングを使うとファイルサイズは 100 GB になっていても例えば実際のディスク消費は 1 TB 程度に抑えられたりします。
仮にその中で大きく増えるものが数台あったとしても全体で 3 TB で抑えられれば無駄に 5 TB のディスクを用意しなくて済むし、もし不足しそうだったらストレージのディスクを追加するだけで OK です。仮想マシンの設定変更は不要です。
シックプロビジョニングとは
シンプロビジョニングに対し、最初からサイズ分のブロックを割り当ててしまうのが『シックプロビジョニング』です。
Eager zeroed とは
Eager zeroed の場合はブロックを割り当て、割り当てた領域全てを 0 に書き換えます。前述の通り、割当前のブロックは最初から全 bit が 0 になっているとは限らないからです。
100 GB のファイルを作った場合、100 GB 分のブロックを割り当てますし、100 GB 分を 0 に書き換えます。
Lazy zeroed とは
Lazy zeroed の場合、ブロックを割り当てますが、割り当てた領域を 0 には書き換えません。ただし、これは VMFS (VMware の ESXi) から見た世界の話です。
例えば Windows をインストールした場合、この仮想ディスクのデータ領域を NTFS 用にフォーマットしますが、仮想サーバ の Windows が NTFS ファイルシステムにブロック割当を行うたびに、ブロックの全 bit を 0 に書き換えます。
Thin と Thick (Eager/Lazy) のメリット比較と利用シーン
指標 | シンプロ ビジョニング | シックプロビジョニング | |
Eager zeroed | Lazy zeroed | ||
ブロックの割当 (Diskの消費) | 必要に応じて割当 | 最初に割当 | 最初に割当 |
割当ブロックの初期化 (ブロックのbitを全て 0にする) | ブロック割当時 | 最初 | VM内でブロックが 割当てられた時 |
Diskの使用効率 | 高い | 普通 | 普通 |
Diskの準備時間 | 速い | 遅い | 速い |
パフォーマンス (IOの速度) | 低 | 高 | 中 |
利用シーン | ・サービスをほぼ メモリだけで 提供できる ・ログのDisk書込 量が推定不可 | ・サービスのメイン 処理がディスクIO であり、かつ速度 が求められる | ・大容量のディスク が必要となること が確実だが、速度 は求められない |
コメント