部屋を掃除したら漫画が沢山出てきたので書く日記

漫画とか合唱とかUNIXとかLinuxとかについて書く日記です。

OpenSolaris 2009.06でWD*EARS(WD15EARS)を使用する その2

その1の続きです。

凄く長くなってしまったので畳みます。興味のない方は飛ばしてくださいませ・・・。

対策の前に、そもそもの問題点について書きます。

問題

今回問題となっているのは、「WD*EARSというHDDをOpenSolarisで使用すると、性能が落ちるようである」というものですが、何故性能が落ちるのか、についてです。

色々記述されているサイトがあるのですが、こちらにまとまっていました。

  • WD*EARSでは、セクタのサイズが4096バイトとなっている。従来のHDDのセクタサイズは512バイトである。
  • 4096バイトのセクタサイズを認識できない従来OSのために、内部では大きい物理セクタサイズ(4096バイト)を使用し、OSには512バイトの論理セクタサイズを認識させるようにしている。
  • 一方、OS(の上で動作しているファイルシステム)がファイルにデータを読み書きする単位「ブロックサイズ」は、大抵4096バイトあるいはその倍数*1である、らしい。
  • 前述したとおり、OSからみたセクタのサイズは512バイトで、4092バイトの1/8である。なので、下表のように、OSから見た0〜7セクタは物理セクタの0セクタ、8〜15セクタが物理セクタの1セクタとなるはずである。

























論理セクタ(512バイト) 01234567 89101112131415
物理セクタ(4096バイト) 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1

  • ところが、Windows XPや現行バージョンのSolarisなどのOSでパーティションを作成すると、第一パーティションの開始位置は先頭から第63セクタ目となる。これは色々な歴史的経緯からそうなっているらしい(未調査)。
  • 63という数字は8の倍数ではない。するとブロックサイズが4096バイトだとすると、読み書きにあたり必ず二つの物理セクタへのアクセスが発生する事になる。これを仮に「ずれ」と呼ぶことにする。

表で説明をする。以下の通り、4096バイトのデータ書き込みが発生すると、物理セクタの7セクタと8セクタの二つの物理セクタにデータが書き込まれる事になる。
































論理セクタ(512バイト) 56575859606162 63 64 65 66 67 68 69 70 71
物理セクタ(4096バイト) 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8

  • 上記で説明した経緯から、「ずれ」がある場合に4096バイトの書き込みが一回あると、必ず二つの物理セクタへの書き込みが発生する事になる。そうすると単純に考えて性能は半分となってしまう。
  • よって、DISK性能の低下が発生する。

という事のようです。いまだに良くわかっていないので非常に怪しい文章です。

考えた対策

Linuxにおいてもこの問題があるため、対策としては

「パーティションの開始セクタを8の倍数に設定する」

というものが考案され、実際に実施して効果が出た、という報告がWEB上で何件かありました。上記の「ずれ」を修正する訳です。OpenSolarisでも同様の対策をしてやればよさそうです。
しかし、具体的にどうやったら良いのかが判りませんでした。Linuxでパーティションを操作するユーティリティソフト「fdisk」は、OpenSolarisでは使えません。同名のユーティリティソフトは存在しますが中身はまったく別なのです。
よって同じ方法は使えません。こちらなどを参考の上で試行錯誤の末、

Solarisのfdiskユーティリティで、パーティションの開始セクタを8の倍数に設定する
事を試した結果、効果が見られましたので書いてみます。

まず、前提としてOpenolarisから該当のDISKは
/dev/dsk/c8d0
として認識されているものとします。
このディスクのパーティション情報を確認します。

スーパユーザで以下のコマンドを実行

# fdisk -W - c8d0p0

以下のようにディスクに関する情報が表示されます。

* /dev/rdsk/c8d0p0 default fdisk table
* Dimensions:
*    512 bytes/sector
*    189 sectors/track
*    255 tracks/cylinder
*   60800 cylinders
*
* systid:
*    1: DOSOS12
*    2: PCIXOS
*    4: DOSOS16
*    5: EXTDOS
*    6: DOSBIG
*    7: FDISK_IFS
*    8: FDISK_AIXBOOT
*    9: FDISK_AIXDATA
*   10: FDISK_0S2BOOT
*   11: FDISK_WINDOWS
*   12: FDISK_EXT_WIN
*   14: FDISK_FAT95
*   15: FDISK_EXTLBA
*   18: DIAGPART
*   65: FDISK_LINUX
*   82: FDISK_CPM
*   86: DOSDATA
*   98: OTHEROS
*   99: UNIXOS
*  101: FDISK_NOVELL3
*  119: FDISK_QNX4
*  120: FDISK_QNX42
*  121: FDISK_QNX43
*  130: SUNIXOS
*  131: FDISK_LINUXNAT
*  134: FDISK_NTFSVOL1
*  135: FDISK_NTFSVOL2
*  165: FDISK_BSD
*  167: FDISK_NEXTSTEP
*  183: FDISK_BSDIFS
*  184: FDISK_BSDISWAP
*  190: X86BOOT
*  191: SUNIXOS2
*  238: EFI_PMBR
*  239: EFI_FS
*

* Id    Act  Bhead  Bsect  Bcyl    Ehead  Esect  Ecyl    Rsect      Numsect
  191   128  0      1      3       254    63     1023    48195      2930207805

ここでは最下行のうち「Rsect」に注目します。「相対的に見たパーティションの開始セクタ」みたいなことがmanを打つと書いていますが、とにかく開始セクタだと思ったので、これを次の8の倍数である「48200」に変更する事にします。

で、これらを具体的に設定する方法ですが、まず以下のような内容の「test.txt」(名前は適当)というテキストファイルを用意します。

191 128 0 6 3 254 63 1023 48200 2930207805

そして、このファイルを以下のように指定しながらfdiskを実行します。

fdisk -F test.txt c8d0p0

再度-W -付でfdiskを実行し、状態を確認します。

# fdisk -W - c8d0p0

* /dev/rdsk/c8d0p0 default fdisk table
* Dimensions:
*    512 bytes/sector
*    189 sectors/track
*    255 tracks/cylinder
*   60800 cylinders
〜中略〜

* Id    Act  Bhead  Bsect  Bcyl    Ehead  Esect  Ecyl    Rsect      Numsect
  191   128  0      6      3       254    63     1023    48200      2930207805

これで開始セクタが変更されました。
あとはformatコマンドでスライスc8d0s0を作ってやる、といった従来のDISK管理を行いますがここでは省略します。

対策の効果

これまでの操作によって作られた、c8d0s0という領域をzfsで作成し、これSambaでWindows側からマウントさせて、Windows環境でのHDD性能ベンチマークの定番ソフトCrystalDiskMarkで性能を測定してみました。
手順としては、既に以下の通りbata64ユーザのホームディレクトリがSambaで公開されているとします。

/export/home/bata64

zpool 「test20100830」をc8d0s0を用いて作成、「/export/home/bata64/test20100830」としてマウント

zpool create -f -m /export/home/bata64/test20100830 test20100830 c8d0s0

このままでは所有権がないので、chownでbata64ユーザに所有権を与えます。

chown bata64:staff /export/home/bata64/test20100830

Windows側で上記領域をYドライブとしてマウント(Zは別のネットワークドライブに使われていたからYにしただけです)
DOS/Vプロンプトで以下を実行

net use y: \\192.168.0.1\bata64\test20100830

この状態で、Yドライブに対してベンチマークを実施します。
まず、上記対策をしない状態での結果は以下の通りです。

-----------------------------------------------------------------------
CrystalDiskMark 3.0 (C) 2007-2010 hiyohiyo
                           Crystal Dew World : http://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 byte/s [SATA/300 = 300,000,000 byte/s]

           Sequential Read :     9.989 MB/s
          Sequential Write :    11.525 MB/s
         Random Read 512KB :     9.950 MB/s
        Random Write 512KB :    11.612 MB/s
    Random Read 4KB (QD=1) :     3.258 MB/s [   795.5 IOPS]
   Random Write 4KB (QD=1) :     0.376 MB/s [    91.9 IOPS]
   Random Read 4KB (QD=32) :    11.626 MB/s [  2838.5 IOPS]
  Random Write 4KB (QD=32) :     1.405 MB/s [   343.1 IOPS]

  Test : 1000 MB [Y: 7.9% (104.0/1320.8 GB)] (x5)
  Date : 2010/08/30 12:06:20
    OS : Windows XP Professional SP3 [5.1 Build 2600] (x86)

次に、対策を実施した状態での結果は以下の通りです。

-----------------------------------------------------------------------
CrystalDiskMark 3.0 (C) 2007-2010 hiyohiyo
                           Crystal Dew World : http://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 byte/s [SATA/300 = 300,000,000 byte/s]

           Sequential Read :     9.812 MB/s
          Sequential Write :    11.630 MB/s
         Random Read 512KB :     9.832 MB/s
        Random Write 512KB :    11.597 MB/s
    Random Read 4KB (QD=1) :     3.237 MB/s [   790.4 IOPS]
   Random Write 4KB (QD=1) :     1.099 MB/s [   268.4 IOPS]
   Random Read 4KB (QD=32) :    11.631 MB/s [  2839.6 IOPS]
  Random Write 4KB (QD=32) :     1.434 MB/s [   350.1 IOPS]

  Test : 1000 MB [Y: 7.9% (104.0/1320.8 GB)] (x5)
  Date : 2010/08/30 13:20:54
    OS : Windows XP Professional SP3 [5.1 Build 2600] (x86)

大体同様の数値となっていますが、一つだけ、
Random Write 4KB (QD=1)の値が、
0.376 MB/s [ 91.9 IOPS]
から
1.099 MB/s [ 268.4 IOPS]
に変わっています。効果が見られます。

考察

試験中にOpenSolarisのシステム・モニタで監視していたところ、以下の図の通り概ねネットワークの帯域の90%を使用しており、DISK性能の限界に達する前に、Sambaで接続しているネットワーク帯域がボトルネックとなっている事がわかりました。NICは1000BASEなんですが、PCを繋ぐL2スイッチが100BASEなんですよね・・・。

よってRandom Write 4KB (QD=1)以外は本来はもっと性能が出るのかもしれません。がしかし、Random Write 4KB (QD=1)については値に変化があり、対策を実施た時のほうが性能が向上しています。これは対策実施前には、ネットワーク帯域の限界の以前にDISK性能の低下が発生しているのだと考えられます。
この事から、4KB程度のランダム書き込みについては本対策は効果があると思われます。

課題

Rsectの値は相対的なセクタの位置という事らしいので、絶対的な位置では8の倍数ではないのでは?という疑問が残ります。これを変えた場合に変化があるのか測定してみたいところです。

また、Samba経由でのベンチマークではボトルネックがネットワーク帯域になってしまうこともわかったので、今度はSolaris側で、ZFSマウントしたDiskへのベンチマークをして見たいと思いますので方法の模索をしてみます。

ではー。

※2010年11月4日追記:
その3を書きました。

*1:OpenSolarisの標準ファイルシステムであるZFSのデフォルトのブロックサイズは8Kバイトらしい。多分8192バイトという事であろう。参考:http://docs.sun.com/app/docs/doc/819-1211/zfs-1m?l=en&n=1&a=view