昨日発覚した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
前述した性質により、一度ashift 12となったプールはディスクアクセスが4kのアライメントとなるので、
gnopによる仮想デバイスはいらなくなると。
FreeBSD9のcamcontrolではセクターサイズを正確に取れるっぽいので、自動化してくれればいいのに、と思った。
gpartでGPTを切る意義はよーわからんの。
パーティションを複数切るなら必須なんで、たとえばBOOT用のZFSプールを作るときには無いとダメだね。
しかしディスク全体をプールに入れてしまうなら、容量のコントロール以外で使う必要は無いと思った。
(RAIDでディスクを交換したときに、ディスクの容量差でリビルド出来なくなることがあるので、わざと容量を余らせたパーティションを作ることがある)