FreeBSD:ZFSストレージ続き

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

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

[plain]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)[/plain]

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

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

[plain]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)[/plain]

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

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

[plain]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)[/plain]

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

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

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

[plain]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
[/plain]

ZFSパラメータの調整

[plain]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[/plain]

下手したら膨大な時間を捨てることを覚悟しつつ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でディスクを交換したときに、ディスクの容量差でリビルド出来なくなることがあるので、わざと容量を余らせたパーティションを作ることがある)

タイトルとURLをコピーしました