WD80EFZXを買って考える、大容量HDDのアロケーションユニットサイズ

8TBのHDDを買いました。

2TBのHDD2本で長いこと暮らしていましたが、いよいよ容量が逼迫してきてここ数か月は不要なファイルを削除しつつなんとか凌いでいる感じでした。

しかしいつ満杯になってしまうか気にしながら恐る恐る使うのは精神衛生上よろしくないので、ちょっと奮発して8TBのHDDを買ってしまいました。
これで一気に容量が倍、さらに8TBがいっぱいになっても、1本追加する余裕ができるということで、しばらくはデータの掃除から解放されることに。

さて、この8TBのHDDをフォーマットするにあたり、ふと、アロケーションユニットサイズをいくらにするのが適切か、ちょっと考えてみました。

アロケーションユニットサイズとは

アロケーションユニットサイズ、クラスタサイズともいいますが、これはファイルシステムがディスクに読み書きする際の最小単位のことです。

ファイルシステムがファイルを書き込む際、ファイルはアロケーションユニットに分割されてディスクに書き込まれます。

たとえば、アロケーションユニットサイズが4KBだった場合、16KBのファイルは4つのアロケーションユニットに分割して書き込まれることになります。16KB÷4KB=4 ということですね。 

NTFSアロケーションユニットサイズはデフォルトで4KBです。フォーマット時に4KB~64KBの範囲で選ぶことができます。

https://msdn.microsoft.com/ja-jp/library/dn466522(v=ws.11).aspx

さて、このアロケーションユニットサイズを変更することでどんな影響があるかというと、大きくは以下の2点です。

フラグメンテーション

一つ目のフラグメンテーション(断片化)ですが、さっきの例では16KBのファイルが4つのアロケーションユニットに分割して保存されました。実はこのとき、分割されたアロケーションユニットが、必ずしもディスク上で連続した場所に保存されるとは限りません。連続した4つのアロケーションユニットが確保できればいいのですが、できなかった場合は空いている場所に飛ばされてしまいます。HDDは連続した領域への読み書き(シーケンシャルアクセス)は得意ですが、ばらばらな場所からデータを読み書きする(ランダムアクセス)は苦手です。そのため、アロケーションユニットサイズを大きくとり、できるだけファイルが分割されないようにしたほうが、ファイルアクセスが高速になります。

クラスタギャップ

二つ目のクラスタギャップについてです。
さっきの例では、16KBのファイルをきっちり4KBのアロケーションユニット4つにおさめることができました。
ここでもし、ファイルサイズが17KBであったらどうなるのでしょうか?アロケーションユニットは、ファイルシステムがディスクに読み書きする最小単位なので、17KBのファイルを保存するには、16KB+4KB、つまり5つのアロケーションユニットが必要となります。さて、5つ目のアロケーションユニットには1KBしかデータを保存しませんが、残りの3KBは何に使われるのでしょうか?
答えは、何にも使われません。
つまり、17KBのデータを保存するには、20KBのディスク上の領域が必要で、そのとき3KBは無駄になってしまうということになります。この、実際のデータサイズとそのデータを保存するために必要なディスク上のサイズの差をクラスタギャップといいます。
クラスタギャップはファイル数が多いほど、またアロケーションユニットサイズが大きいほど多くなります。
例えばアロケーションユニットサイズが4KBであれば、1KBのファイルを保存するときのクラスタギャップは3KBですが、アロケーションユニットサイズが64KBであれば、1KBのファイルを保存するときのクラスタギャップは63KBにもなります。
また、クラスタギャップが発生するのは、そのファイルの最後のアロケーションユニットだけなので、ファイルサイズが大きくても小さくても関係なく、クラスタギャップは1ファイルにつき1つだけ発生します。

上記2点を考慮すると、ディスクの読み書きの速度を上げるにはアロケーションユニットはできるだけ大きくしたいですが、クラスタギャップを小さくしてディスクの無駄遣いをなくすには、アロケーションユニットを小さくしたほうがよいとなります。

最適なアロケーションユニットサイズの考え方

さて、では最適なアロケーションユニットサイズはどのように考えればいいでしょうか?

今回は、今まで使っていたHDDの置き換えですので、既存ディスクの使用状況を見てみます。
アロケーションユニットサイズはすべてデフォルトの4KBで作ってあります。

HDD1台目
ファイル数 54,863
サイズ   1,965,779,878,872 バイト
ディスク上のサイズ 1,965,890,957,312 バイト
クラスタギャップ 111,078,440 バイト

HDD2台目
ファイル数 54,045
サイズ   1,441,201,290,584 バイト
ディスク上のサイズ 1,441,313,718,272 バイト
クラスタギャップ 112,427,688 バイト

クラスタギャップをファイル数で割ると、約2KBになりました。クラスタギャップが0~4KBの範囲でどのように発生するかはファイルサイズによりますが、平均すると1ファイルあたりアロケーションユニットサイズの半分と考えてよさそうです。

また、1ファイルあたりの平均サイズは約34MB(35,253KB)程度となりました。データ保存に使っているので、比較的大きなファイルが多いようです。

この傾向で今後もデータが増えていくとして、8TBのディスクを使いきるころに、クラスタギャップはどの程度のサイズになっているでしょうか?

まずはアロケーションユニットサイズを64KBにした場合を考えてみます。
1ファイルあたりのディスク上のサイズは、ファイルサイズ35,253KB+クラスタギャップ32KB(64KBの半分)なので、35,285KB (約35MB)になります。

8TB÷35MB=226,519 で、ファイル数は22万6千ほどになっている見込みです。
すると、クラスタギャップは (64KB÷2) × 22万6千 = 7.2 GB となりました。

アロケーションユニットサイズを4KBにすれば、クラスタギャップは1/16になるので460MBほどになるでしょう。

アロケーションユニットサイズを4KBから64KBに変更した際のアクセス速度の向上が、ディスク6.8GBを無駄にしてもいいと思えるほどであれば、増やすメリットがあるということになりますね。

ただ、アロケーションユニットサイズの違いによるディスクアクセス性能への影響は、通常のディスクパフォーマンス測定ツールを使った定量測定が難しい(*)ので、とりあえず今回は64KBでフォーマットしてみようと思いました。

(*)断片化を意図的に発生させる必要があるため。デフラグツールは結構ありますが、断片化ツールは意外にないですね。ファイルのランダム再配置でがんばって断片化させようというツールはありましたが、ディスクサイズを考えるとデフラグツールと同じようにWindowsの標準デフラグAPIを使って任意に断片化を発生させないと意味のある測定はできなさそう。

ちなみに

システムディスクはOSやアプリケーションの小さなファイルが大量にあるため、アロケーションユニットサイズは小さくしたほうがいいでしょう。
最近のシステムディスクにはSSDを使う人が多いと思います。SSDはHDDと比べてランダムアクセスがはるかに高速なので、アロケーションユニットサイズを大きくすることによる速度向上はHDDに比べて小さくなると思います。逆に容量単価が高いので、アロケーションユニットサイズを小さくして効率的に利用するメリットが大きいと思います。