FreeBSD:ZFSストレージ続き

投稿者: | 2012年7月24日

昨日発覚したWD30EZRXx4でZFS RAIDZのアライメントがずれた件を調べてみる

まず何もしないでディスク単体

NEKOSABA /root# dd if=/dev/zero of=/dev/ada0 bs=1m count=10240
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 81.348583 secs (131992689 bytes/sec)
NEKOSABA /root# dd if=/dev/ada0 of=/dev/null bs=1m count=10240
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 81.310937 secs (132053800 bytes/sec)
NEKOSABA /root# zpool create ztest ada0
NEKOSABA /root# zpool status
  pool: ztest
 state: ONLINE
 scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        ztest       ONLINE       0     0     0
          ada0      ONLINE       0     0     0

errors: No known data errors
NEKOSABA /root# zdb -C ztest | grep ashift
                ashift: 9

NEKOSABA /root# dd if=/dev/zero of=/ztest/test10G.dat bs=1m count=10240
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 106.064630 secs (101234674 bytes/sec)
NEKOSABA /root# dd if=/ztest/test10G.dat of=/dev/null
20971520+0 records in
20971520+0 records out
10737418240 bytes transferred in 113.156549 secs (94889941 bytes/sec)

うーん、ZFSのオーバーヘッドを除けば大した差が無さそう

続いて4kのnop生やしてやってみる

NEKOSABA /root# zpool create ztest2 ada0.nop
NEKOSABA /root# zpool status
  pool: ztest2
 state: ONLINE
 scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        ztest2      ONLINE       0     0     0
          ada0.nop  ONLINE       0     0     0

errors: No known data errors
NEKOSABA /root# zdb -C ztest2 | grep ashift
                ashift: 12
NEKOSABA /root# dd if=/dev/zero of=/ztest2/test10G.dat bs=1m count=10240
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 91.202363 secs (117731799 bytes/sec)
NEKOSABA /root# dd if=/ztest2/test10G.dat of=/dev/null
20971520+0 records in
20971520+0 records out
10737418240 bytes transferred in 106.861155 secs (100480088 bytes/sec)

微妙に差が出た。nop使わないのとはざっと1割程度早い。
これがシーケンシャルアクセスのアライメントによる性能差といったところかの。

うーん、本命のアレイをnop使って作ってみる

NEKOSABA /root# zpool create zdata raidz ada0.nop ada1.nop ada2.nop ada3.nop
NEKOSABA /root# zpool status
  pool: zdata
 state: ONLINE
 scan: none requested
config:

        NAME          STATE     READ WRITE CKSUM
        zdata         ONLINE       0     0     0
          raidz1-0    ONLINE       0     0     0
            ada0.nop  ONLINE       0     0     0
            ada1.nop  ONLINE       0     0     0
            ada2.nop  ONLINE       0     0     0
            ada3.nop  ONLINE       0     0     0

errors: No known data errors

NEKOSABA /root# zdb -C zdata | grep ashift
                ashift: 12
NEKOSABA /root# dd if=/dev/zero of=/zdata/test20G.dat bs=1m count=20480
20480+0 records in
20480+0 records out
21474836480 bytes transferred in 99.939992 secs (214877308 bytes/sec)
NEKOSABA /root# dd if=/zdata/test20G.dat of=/dev/null bs=1m count=20480
20480+0 records in
20480+0 records out
21474836480 bytes transferred in 60.833272 secs (353011367 bytes/sec)

あれ、アライメントズレが直ったぽい?
・・・gpartでパーティション切ったのがダメだったのかな?仕組み的には大丈夫そうに見えたんだけど
ググってみるとそういう手順で作ってるところ結構あるんだよねぇ
うーん、よく分からないがよしとしよう。追試は面倒なので無しの方向で!

後はやり残した作業を忘備録代わりに

ログとキャッシュのデバイス入れてるのだけど、パーティションを切る必要があることからアライメントを修正
前やった作業だとずれてたので

NEKOSABA /root# gpart destroy -F ada5
ada5 destroyed
NEKOSABA /root# gpart create -s gpt ada5
ada5 created
NEKOSABA /root# gpart add -b 40 -s 4G -t freebsd-zfs ada5
ada5p1 added
NEKOSABA /root# gpart show ada5
=>      34  39091181  ada5  GPT  (18G)
        34         6        - free -  (3.0k)
        40   8388608     1  freebsd-zfs  (4.0G)
   8388648  30702567        - free -  (14G)

NEKOSABA /root# gpart add -b 8388648 -s 30702567 -t freebsd-zfs ada5
ada5p2 added
NEKOSABA /# gpart show ada5
=>      34  39091181  ada5  GPT  (18G)
        34         6        - free -  (3.0k)
        40   8388608     1  freebsd-zfs  (4.0G)
   8388648  30702567     2  freebsd-zfs  (14G)

NEKOSABA /root# zpool add zdata log ada5p1
NEKOSABA /root# zpool add zdata cache ada5p2
NEKOSABA /root# zpool status
  pool: zdata
 state: ONLINE
 scan: none requested
config:

        NAME          STATE     READ WRITE CKSUM
        zdata         ONLINE       0     0     0
          raidz1-0    ONLINE       0     0     0
            ada0.nop  ONLINE       0     0     0
            ada1.nop  ONLINE       0     0     0
            ada2.nop  ONLINE       0     0     0
            ada3.nop  ONLINE       0     0     0
        logs
          ada5p1      ONLINE       0     0     0
        cache
          ada5p2      ONLINE       0     0     0

errors: No known data errors

ZFSパラメータの調整

NEKOSABA /root# zfs set atime=off zdata/ftp_root
NEKOSABA /root# zfs set atime=off zdata/tank
NEKOSABA /root# zfs set atime=off zdata/www
NEKOSABA /root# zfs set compression=on zdata/www
NEKOSABA /root# zfs set compression=on zdata/tank
NEKOSABA /root# zfs set dedup=on zdata/tank
NEKOSABA /root# zfs set dedup=on zdata/www

下手したら膨大な時間を捨てることを覚悟しつつdedupをONにしてみる。
これで様子見やの。

んでZFSのAFT対応について調べたことをつらつらと。
ZFSはデフォルトだと512byteのアライメントで読み書きをするみたい。
ashiftの数字がもろにそれ。4k単位のアクセスとするにはashiftの数字が12で無ければいけない。
ashiftはZFSのプールを作成時に指定されるので、既存のプールにこの変更を適用することは出来ない。

ZFSはAFT対応とするためにPatchが取り込まれてるので、
プールに参加するHDDの論理セクターサイズが4096ならば、ashiftの数字は12に指定される。
ところが、AFTは後方互換性のために論理セクターサイズを512byteと通知する習性があり、実際のashiftは9になる・・・。
なのでgnop create -S 4096 によって論理セクターサイズを4096と返す仮想デバイスを生やす必要がある。
前述した性質により、一度ashift 12となったプールはディスクアクセスが4kのアライメントとなるので、
gnopによる仮想デバイスはいらなくなると。
FreeBSD9のcamcontrolではセクターサイズを正確に取れるっぽいので、自動化してくれればいいのに、と思った。

gpartでGPTを切る意義はよーわからんの。
パーティションを複数切るなら必須なんで、たとえばBOOT用のZFSプールを作るときには無いとダメだね。
しかしディスク全体をプールに入れてしまうなら、容量のコントロール以外で使う必要は無いと思った。
(RAIDでディスクを交換したときに、ディスクの容量差でリビルド出来なくなることがあるので、わざと容量を余らせたパーティションを作ることがある)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください