ZFS優しすぎ涙がでた。

前口上

試しにZFSを使ってみて(VMware Playerで気軽に試せるようになったとは、なんと便利な世の中か)本当に驚いた。
ディスク繋いでzpoolコマンド一発ですぐ使える。パーティションに頭を悩ませる必要もない。RAIDだって楽勝。ディレクトリごとに圧縮することもできるし、気が変わったら、いつでも止めることもできる。スナップショットも早い。
実は、何年か前にZFSについて調べたときはまだまだバギーな印象だったのと、ZFSを使えるようなパワフルマシンがなく保留にしてたんだけど、すごく損した気分。
いままで幾たび、fdiskやnewfs失敗してひどい目にあったことか。電子の海に消えたデータを思う。


そしてRAID。ソフトRAIDで言えばlvmも有名だが、俺にはもうコマンドが複雑すぎて覚えられない(lv...が論理ボリュームを、pv...が物理ボリュームを扱うんだって?)。
これはすごく危険。
だってソフトRAID含め、こういったディスクを扱うコマンドを使うのは、初期設定と、問題の発生したとき。
俺みたいなオッチョコチョイが、問題が発生して焦っているときに、コマンドが複雑だと二次災害を引き起こすんだって。
…正直に言うと実際に引き起こした。


ZFSならとにかくzpool、zfsさえ覚えておけばいいのだ。


ZFS

宅鯖ではZFSを使いたいからFreeBSDを選んだ。
そして、いろいろwebを渉猟するにi386ZFSは辛そうなのでamd64とし、下記の通りZFSのバージョンもどーんと上がっているので, 9.0-RELEASEを入れた。メジャーバージョンの最初はちょっと不安ではあるけれど。

ZFSのバージョン
8.2+ - ZFS v15
9.0+ - ZFS v28

あとは、特に難しいこともなく、2.5Tのディスク1本買ってきて、つないで、領域作って、こんな感じ。
作業ログは後述。

$ sudo zpool status
パスワード:
  pool: vault
 state: ONLINE
 scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        vault       ONLINE       0     0     0
          ada1      ONLINE       0     0     0

errors: No known data errors
$ zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
vault  2.27T  1007G  1.28T    43%  1.00x  ONLINE  -


ディスク1本なので、RAIDも組まず、圧縮もせず(データがjpg写真とか自炊本、自炊DVD、CDとか圧縮の効かないものばかりだから)。
あんなに煽っておいてアレだが、だってまだディスク高いし・・。


チューニング

ただまあ、ここを見てチューニングだけはしておいた。
http://wiki.freebsd.org/ZFSTuningGuide


/boot/loader.confにおけるチューニング

vfs.zfs.prefetch_disable="1"
vfs.zfs.txg.timeout="5"

1行目
ZFSのprefetchを無効にすると全体的にスピードが向上する。
ただし読み書きが頻繁に発生する状態だとシステムが遅くなる傾向あり。
なお、4GB以上のメモリが実装されているとデフォルトで0になるとのこと。

2行目
txgが何の意味か分からないけど(task queue?)、こうしておくとスループットが上がる上に、システムが極端に遅くなる問題が改善される。
(In my case 50-100% CPU is used by ZFS with *no* disk activity during the pauses then a burst of rapid disk activity and then another pause. なんて言ってる)
なお、これはZFS v28からはデフォルト。


/etc/sysctl.confにおける設定

kern.maxvnodes=250000
vfs.zfs.write_limit_override=131072

1行目でvnodes数の上限をデフォルトの約200000(a little over 200,000)から増やす。
2行目でTXG write limitの値を減らす。デフォルト値は知らん。
4GBメモリなら256MB、と書いてあるので、2GBを積んでる俺は128MBにした。
なお、ZFS v28より前ではvfs.zfs.txg.write_limit_overrideとのこと。



そのほかの設定:periodic script

/etc/periodic/daily/404.status-zfsスクリプトがある。
有効にすると、毎日zpoolの状態をしらべて、daily output, security outputでメールしてくれる。
そうそう、root宛のメールは転送設定しておくと便利。

$ sudo /etc/periodic/daily/404.status-zfs

Checking status of zfs pools:
all pools are healthy


/etc/periodic.confに以下を追記しておけばOK

daily_status_zfs_enable="YES" 


以下は作業ログ

作業ログ

ディスクをつないで起動、dmesgで確認

$ dmesg|grep ada
ada0 at ahcich0 bus 0 scbus0 target 0 lun 0
ada0: <VB0250EAVER HPG7> ATA-8 SATA 2.x device
ada0: 300.000MB/s transfers (SATA 2.x, UDMA5, PIO 8192bytes)
ada0: Command Queueing enabled
ada0: 238475MB (488397168 512 byte sectors: 16H 63S/T 16383C)
ada0: Previously was known as ad4
ada1 at ahcich1 bus 0 scbus1 target 0 lun 0
ada1: <WDC WD25EZRX-00MMMB0 80.00A80> ATA-8 SATA 3.x device
ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada1: Command Queueing enabled
ada1: 2384658MB (4883781168 512 byte sectors: 16H 63S/T 16383C)
ada1: Previously was known as ad6

ada1が新しく繋いだディスク。
ここにZFSを作成する。

$ sudo zpool create vault ada1
Password:
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault on /vault (zfs, local, nfsv4acls)
$ df -h
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/ada0p2    228G     15G    194G     7%    /
devfs          1.0k    1.0k      0B   100%    /dev
vault          2.2T     31k    2.2T     0%    /vault


無事完成。
なんと勝手にマウントまでしてくれる。これですぐ使える。
2.5Tなのに数秒程度で完了。
ビクビクしながらfdiskしたりnewfsしたりする必要がない。電卓も要らない(そういう時代もあったのです)。
衝撃的です。
コマンドが簡単なうえに、早いというのは、重ねて言うけど障害復旧に極めて有利な点。
大きなディスクをnewfsするときの、遅々として進まないカウンタを見てジリジリしたことのある人なら共感してくれるはず。


なお、この状態では/etc/fstabに何も書き込まれていないので、再起動すればマウントは外れる。


ではここにディレクトリをいくつか作る。
itunes用と、通常の共有ディレクトリ用の二つを作る。

$ sudo zfs create vault/itunes
$ sudo zfs create vault/chamber
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault on /vault (zfs, local, nfsv4acls)
vault/itunes on /vault/itunes (zfs, local, nfsv4acls)
vault/chamber on /vault/chamber (zfs, local, nfsv4acls)
$ df -h
Filesystem      Size    Used   Avail Capacity  Mounted on
/dev/ada0p2     228G     15G    194G     7%    /
devfs           1.0k    1.0k      0B   100%    /dev
vault           2.2T     32k    2.2T     0%    /vault
vault/itunes    2.2T     31k    2.2T     0%    /vault/itunes
vault/chamber    2.2T     31k    2.2T     0%    /vault/chamber


これらを/export配下に移動させる。
これが既存の考えにはない動作。頭の中でファイルシステムに対する考え方がグニョっとなるのを俺は感じたよ。

$ sudo zfs set mountpoint=/export/itunes vault/itunes
$ sudo zfs set mountpoint=/export/chamber vault/chamber
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault on /vault (zfs, local, nfsv4acls)
vault/itunes on /export/itunes (zfs, local, nfsv4acls)
vault/chamber on /export/chamber (zfs, local, nfsv4acls)

そしたら/etc/fstabに書き込んでおしまい。
昔はデバイス名を書き込んでいた場所にZFSのディスクプールを書くわけですな。

vault/itunes    /export/itunes         zfs     rw      0       0
vault/chamber   /export/chamber                zfs     rw      0       0

afpでファイルをコピーしているのだが、あまり負荷はかかっていない模様。
ZFSはリソース食いと聞いてたのでコワゴワコピーしたんだけど、まあ100Mbpsのネットワーク越しですしな。

last pid:  1773;  load averages:  0.11,  0.21,  0.17    up 0+00:45:03  23:54:03
42 processes:  1 running, 41 sleeping
CPU:  0.2% user,  0.0% nice, 15.0% system,  0.4% interrupt, 84.4% idle
Mem: 46M Active, 189M Inact, 1426M Wired, 64M Cache, 200M Buf, 119M Free
Swap: 907M Total, 556K Used, 906M Free

  PID USERNAME     THR PRI NICE   SIZE    RES STATE   C   TIME   WCPU COMMAND
 1697 root           1  31    0 55860K  4288K select  1   3:55 16.36% afpd

そのほか

重大な作業をするときは必ず-nオプションを付けること。
ドライランと呼ばれるもので、実際の作業はせずに結果をシミュレートできる。


ストレージプールを作業するときには明示的にexportすること。
exportすれば、未書き込みのデータがすべて処理され、システムから削除される。

そこで引数なしでimportを実行すると、import可能な、言い換えるとexport済みのプールが表示される。