4096 バイトセクタの HDD と Linux
先日 1TB クラスのハードディスクを買いに秋葉原へいってきました。ずいぶん安くなったものだなぁと感激しながら物色してたんですが、なぜかキャッシュ 64MB のほうが 32MB のものより安かったのでこりゃお得だろうと思いそちらを考えなしに買いました。
帰ってきて調べてみたら、買ったやつは 4096 バイトセクタのものでした。なんか Windows XP だとそのまま使うとパフォーマンスがでないとか聞いていた気はしていたんですが、まさかそれを買ってしまうとは。どうりでバッファ容量が大きいほう(つまり 4K セクタ)がどの店でも安いわけだ。
たしか Linux の場合だと大丈夫だよねと思いながら検索してみると、Linux でもパフォーマンスが落ちるという話が。うわーどうしようと思い、4096 バイトセクタ HDD と Linux についていろいろ調べてみました。
ただ、机上の調査であり実地検証はおこなっていないですし、ATA 仕様や Linux のブロックデバイスドライバまわりも明るくないので間違いも多々あるかもしれませんが、ツッコミ歓迎ということで。
結論から書くと、Linux で使う場合、(現状では)fdisk のエキスパートモードを使ってパーティション境界を 8 の倍数(セクタ)に指定してあげるとパフォーマンスはきちんと出ます。新規インストールするならあらかじめ別の(ブータブル Linux などの)OS などでパーティションを切っておく。ハードウェア RAID の場合どうすればいいかはわかんない。
- 従来の HDD はセクタサイズが 512 バイトである
- いまどきの OS は複数セクタをまとめたブロック単位で扱っている(たいてい 4096 バイト単位*1)
- 最近物理セクタサイズを 4096 バイト(4K)とした HDD が出荷されるようになってきた
- Western Digital は Advanced Format Technology (AFT) と呼んでいる
- 最終的には(業界全体の意向としては)外部インタフェースも含めて 4096 バイトセクタ(など 512 バイト以上)にしたい
- 既存のハードウェア・ソフトウェアとの互換性維持のため、現在出荷されている(物理)4K セクタ HDD は、外部インタフェース向けとしては(論理)512 バイトセクタであるかのように振る舞う(エミュレーション)
- エミュレーションによる 4K セクタ HDD は、論理セクタ*2(512 バイト)を1つ書き込む際、一度物理セクタ(4096 バイト)を HDD 内部のバッファに読み込み、該当する部分だけ*3を変更して物理セクタ全体を書き込む(read-modify write; RMW)
- このままだと書き込みパフォーマンスが大幅に低下してしまう(単純計算で8倍)ので、
同一物理セクタ内の論理セクタに連続して書き込む場合、HDD 内部のバッファにそれらを書き込んでからまとめて物理セクタに書き出している、複数セクタを書き込む場合、物理セクタサイズ境界で分割して一度に書き込む、と思われる(推測) - 前述したように、いまどきの OS ではブロックサイズ単位(現在はデフォルトでたいてい 4K)でディスクとやりとりするので、書き込み時のスループット低下はほぼおきなくてハッピー(のはず)
- ところが
- 「ハッピー」の前提は、HDD の物理セクタの境界と OS のブロック境界が一致していた場合の話
- もし境界がずれている場合、1ブロックの書き込みに対して、物理セクタ1つの読み書きが2つ分発生する(ブロックサイズ 4K の場合)→スループットが1/2に低下
- 古典的な DOS パーティションテーブルでは、通常、パーティションの境界はシリンダ単位としている
- 実際にはパーティション境界はセクタ単位で指定できる(しブートも可能)が、歴史的経緯からシリンダ単位で切り上げするのが定番となっている
- 歴史的経緯により現在(仮想的な)シリンダは 63 セクタから構成されているとみなされる
- 63 は 8 の倍数ではないので、シリンダ境界はたいてい*4物理セクタの境界と一致しない
- 実際、第1パーティションはたいてい LBA 63 (0 オリジン) から始まる
- ブロックサイズ自体は 4K なので、パーティション内の各ブロックの境界はすべて物理セクタの境界と一致しない
- オワタ\(^o^)/
- さて
- Western Digital は Windows XP では HDD をそのまま使うと性能がでないが、Linux ではそのまま使ってよいとしている*5
- 実際、理論上、(DOS)パーティションテーブルのパーティション境界を 8 セクタ単位にすれば、書き込み性能の劣化はみられないはずである
- しかしながら、現在のたいていの Linux ディストリビューション付属のパーティショニングユーティリティは、デフォルトでシリンダ単位(つまり 63 セクタ単位)でパーティションをわりふる
- anaconda などのインストーラ組み込みのパーティショニングツールも含む
- このため、何も考えずに 4K セクタ HDD を Linux を使うと、書き込み性能が大幅に劣化する
- シーケンシャル書き込みで 40%、ランダム書き込みで 30% に書き込み速度が低下
- というわけで
- 現在、Linux で 4K セクタ HDD を使う場合
- あとから追加する HDD なら、
fdisk
のエキスパートモード(x
コマンド)においてパーティションの開始セクタを(b
コマンドなどで)8 の倍数に設定する - インストール時に使用する HDD であれば、KNOPPIX や Ubuntu Live mode や SystemRescueCd などをあらかじめ立ち上げて上述する方法でパーティションを切っておき、そのパーティションにインストールすればよい
- たしかめていないけど、Windows XP でもインストール後に WD Align utility を利用しなくても、インストール前に上記のように CD ブート Linux などでパーティションを切っておけばうまくいくと思う
- あとから追加する HDD なら、
- 今後の Linux ディストリビューションでは、物理セクタサイズに対応したパーティションテーブルを作成できるようになるはず
参考文献
- Windows XPでは再設定が必要な1TB HDDが発売
- WD のディスクの場合ジャンパでモードを変えられるみたいですけど、何がおきるんだろう。LBA 63 以降を物理的には LBA 64 以降にマッピング(あるいは LBA 0 の部分からシフト)しているのかなと思いますが、わかりません。
- はいじん☆ちゃんねる » Linuxで4KセクタHDDの使用方法
- 下の記事の紹介
- Linux Not Fully Prepared for 4096-Byte Sector Hard Drives
- comment 409410 - Linux Not Fully Prepared for 4096-Byte Sector Hard Drives
- 上記記事の有用なコメント(とはいえ斜め読みしたので下記の内容は間違ってるかも)
- ATA の仕様では物理セクタサイズ(境界)を取得する方法が定義されている
- WD から送ってもらったエンジニアリングサンプルはちゃんとこの情報を返していた
- でも出荷されたドライブでは間違った情報を返すようになっている
- Linux 2.6.31 以降では、すべてのブロックデバイスでブロックサイズ境界を取得するようになっている
- ユーザランドのパーティショニングコマンド(fdisk や parted)はそれらを使ってパーティション境界を設定するように(最近のコードでは)変更されている
- そもそもさいきんの fdisk はパーティション境界を 1MB(を HDD の物理セクタ境界でアラインしたもの) にしている
- Fedora の最近のコードベースはそれらをとりいれてるはず。少なくとも Fedora 13 はそうなるだろう。Fedora 12 はたぶんとりいれてない。他のディストリビューションは知らない。
- Linux and 4K disk sectors [LWN.net]
- HDD の 512 バイトセクタから 4096 バイトセクタへの移行段階と Linux における対応についてまとまっている
- Western Digital’s Advanced Format: The 4K Sector Transition Begins
- 4096 バイトセクタの必要性と、Windows XP におけるブロック境界ずれについてまとまっている
- 34GBのIDE HDDが認識できない? - Q&A
- これまでの HDD の容量の限界の推移(歴史的経緯がわかる)
- ファイルシステムのブロックサイズを調べる - メモ帳
- Over2TB - wiki@nothing
- 今回の件とはちょっと関係ないけど、HDD の 2TB 限界について
- 16TB のディスクボリュームのスクリーンショットがあるけど、どうやって実現したんだろう。
- Topology information - libblkid Reference Manual
- GNU parted を深追いしてみつけた関数
parted --align optimal
の場合、(Linux アーキテクチャでは)このへんの関数を使ってパーティション境界を決める- OPTIMAL_IO_SIZE: usually the stripe width for RAID or zero. For RAID arrays it is usually the stripe width or the internal track size.
- ということで(現役の Linux だと)きちんとサポートされた RAID アレイでもない限り使われてなさそう。
- 2.6.31 以降だとここにも反映するようにしたのかな?(不明)
*1:ちなみに x86 アーキテクチャのページサイズも 4096 バイトである(自信なし)ので、この倍数にしておくといろいろ都合がよい。
*2:OS 側の論理セクタという意味ではなく、あくまで HDD 側のエミュレーションレイヤにおける論理的セクタ
*3:実際には物理セクタ全体の ECC を計算して書き込む必要がある。
*4:もちろん、第2パーティション以降でたまたまシリンダ境界が物理セクタ境界と一致することもありえる。
*5:実際にはそのような記述は見当たらなかった。HDD に添付された注意書きでは、「All other OS」というくくりになっているし、Advanced Format に関するページには Mac OS の表記はあるものの Linux の表記はない。