2018年4月7日土曜日

ZFSの新機能?デバイス取り外しを試す

実に2016年以来のZFSネタです。

ZFSといえば私の信奉する最強ファイルシステムということで、特にMacでの利用について思い返せば5年以上前から取り上げていたものです。

何が最強かというと色々あるわけですが、強力なのは論理ボリュームマネージャに相当する機能が組み込まれておりRAID・領域切り出し・スナップショット等々が自由自在というあたりです。

が、自由自在なZFSでも数少ない不自由がスケールアップが簡単でもスケールダウンができないこと。つまり、2台ミラーリングのプールに更に2台ミラーリングを追加して容量拡大するのは容易ですが、容量に空きがあってもそこからディスク本数を減らすことは基本的にできなかったのです。

なんですが、なんとついにこの機能が実装されたらしい。まだあらゆる環境で使えるわけではないですが、意外なことにMacで簡単に試せるので試してみました。

結論から言うとRAID-Zでは使えなかったので過度な期待は禁物ですが、それ以外は期待した動作をしてくれました。


背景


自分はosx86機でZFSを普段使いしており、常に最新版を追っているわけではないですがこの前たまたまOpenZFS on OS Xのリリースノートを読んでいたら興味深い記述が。
7614 zfs device evacuation/removal (OpenZFS Team)
デバイスの取り外し・・・?

本家のチケット7614を読んでみると確かにトップレベルデバイスの取り外しができそう。

今年に入ってからマージされた割と新しい機能のようで、ZFS on Linuxではまだマージされておらず未リリースである0.8.0のマイルストーンになっています。FreeBSDではSTABLEには入ってないようですがmasterには入っているのでCURRENTでは使えそう。あとは本家illumos系ではOmniOS CEのbloodyあたりなら入ってそうです。

自分としてはファイルサーバをZFS on Linux(がまだrcだった頃!)で構築することにして以来FreeBSDとSolaris系は触っていないので、もちろんMacで試してみます。


注意


OpenZFS on OS Xは割とイケイケな開発方針をしているのでいつの間にかZFS on Linuxより先にOpenZFSのコードを取り込んでstableとして出していますが、本家FreeBSDで今回のzpool remove機能起因のバグ報告がされてたりしていて、ちょっとまだ怪しい感じもします。

なにせ10年レベルで待望されていたにも関わらず最近までマージされなかった(できなかった)大物機能なのでまだ色々と地雷がありそう。

というわけで自己責任で試してくださいね!自分は大事なデータが入ってるプールのあるメインHackintoshに入れちゃいましたけど!


試す


というわけで、インストール自体はOpenZFS on OS Xの1.7.2(以上)を落としてきて入れるだけです。自称stableリリースなのでMountain Lion以上であれば入るはず。

ダミーディスクとして1GBと2GBの空ファイルをいくつか作っておきます。
# dd if=/dev/zero of=dummy1 bs=1g count=1
1+0 records in
1+0 records out
1073741824 bytes transferred in 0.822363 secs (1305678824 bytes/sec)

# dd if=/dev/zero of=dummyA bs=1g count=2
2+0 records in
2+0 records out
2147483648 bytes transferred in 1.464317 secs (1466542781 bytes/sec)

# for n in {2..8}; do cp dummy1 dummy$n; done
# for n in B C D; do cp dummyA dummy$n; done

# ls -lh
total 33554432
-rw-r--r--  1 root  staff   1.0G  4  5 23:57 dummy1
-rw-r--r--  1 root  staff   1.0G  4  5 23:57 dummy2
-rw-r--r--  1 root  staff   1.0G  4  5 23:52 dummy3
-rw-r--r--  1 root  staff   1.0G  4  5 23:52 dummy4
-rw-r--r--  1 root  staff   1.0G  4  5 23:52 dummy5
-rw-r--r--  1 root  staff   1.0G  4  5 23:52 dummy6
-rw-r--r--  1 root  staff   1.0G  4  5 23:52 dummy7
-rw-r--r--  1 root  staff   1.0G  4  5 23:52 dummy8
-rw-r--r--  1 root  staff   2.0G  4  6 00:00 dummyA
-rw-r--r--  1 root  staff   2.0G  4  6 00:00 dummyB
-rw-r--r--  1 root  staff   2.0G  4  6 00:00 dummyC
-rw-r--r--  1 root  staff   2.0G  4  6 00:00 dummyD

単純なストライピング


普通に1GBx2のストライピングでプールを作ります。
# zpool create pool1 /tmp/dummy1 /tmp/dummy2

# zpool status pool1
  pool: pool1
 state: ONLINE
  scan: none requested
config:

 NAME           STATE     READ WRITE CKSUM
 pool1          ONLINE       0     0     0
   /tmp/dummy1  ONLINE       0     0     0
   /tmp/dummy2  ONLINE       0     0     0

errors: No known data errors

# zfs list pool1
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool1  1.06M  1.75G  1.01M  /Volumes/pool1

ここで、1GBのファイルを配置してからremoveをかけてみます。
# cp dummy1 /Volumes/pool1/dummy

# zfs list pool1
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool1  1.00G   767M  1.00G  /Volumes/pool1

# zpool remove pool1 /tmp/dummy2
cannot remove /tmp/dummy2: out of space

当然残容量が足りないのでremoveできません。

ファイルを消してからremoveをかけます。
# rm /Volumes/pool1/dummy

# zpool remove pool1 /tmp/dummy2

# zpool status pool1
  pool: pool1
 state: ONLINE
  scan: none requested
remove: Removal of vdev 1 copied 102K in 0h0m, completed on Thu Apr  5 23:57:33 2018
    768 memory used for removed device mappings
config:

 NAME           STATE     READ WRITE CKSUM
 pool1          ONLINE       0     0     0
   /tmp/dummy1  ONLINE       0     0     0

errors: No known data errors

期待通り、シングルディスクのプールになりました!おお。


ミラーリング構成


今度は1GBx2のミラーを更にストライピングさせた、ありがちなプールを作ってみます(先程のプールをdestroyしているのは省略)。
# zpool create pool2 \
> mirror /tmp/dummy1 /tmp/dummy2 \
> mirror /tmp/dummy3 /tmp/dummy4

# zpool status pool2
  pool: pool2
 state: ONLINE
  scan: none requested
config:

 NAME             STATE     READ WRITE CKSUM
 pool2            ONLINE       0     0     0
   mirror-0       ONLINE       0     0     0
     /tmp/dummy1  ONLINE       0     0     0
     /tmp/dummy2  ONLINE       0     0     0
   mirror-1       ONLINE       0     0     0
     /tmp/dummy3  ONLINE       0     0     0
     /tmp/dummy4  ONLINE       0     0     0

errors: No known data errors

# zfs list pool2
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool2   910K  1.75G   850K  /Volumes/pool2

# cp dummy5 /Volumes/pool2/dummy

# zfs list pool2
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool2  1.00G   767M  1.00G  /Volumes/pool2

ミラーなので容量は半分。つまり先程のプールと変わりません。先ほどと同じように1GBのファイルも配置。

1GBを1TBのディスクで置き換えて考えてみると、こういったプールの容量を増やしたい場合、ミラーの片割れに対して2TBのディスクで2回zpool replaceをかけて2TBx2のミラーに置換する、といった作業が従来のイメージだと思います。

が、今回はここで2GBx2のミラーを置換ではなく追加します。
# zpool add pool2 \
> mirror /tmp/dummyA /tmp/dummyB

# zpool status pool2
  pool: pool2
 state: ONLINE
  scan: none requested
config:

 NAME             STATE     READ WRITE CKSUM
 pool2            ONLINE       0     0     0
   mirror-0       ONLINE       0     0     0
     /tmp/dummy1  ONLINE       0     0     0
     /tmp/dummy2  ONLINE       0     0     0
   mirror-1       ONLINE       0     0     0
     /tmp/dummy3  ONLINE       0     0     0
     /tmp/dummy4  ONLINE       0     0     0
   mirror-2       ONLINE       0     0     0
     /tmp/dummyA  ONLINE       0     0     0
     /tmp/dummyB  ONLINE       0     0     0

errors: No known data errors

# zfs list pool2
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool2  1.00G  2.62G  1.00G  /Volumes/pool2

容量は増えましたが、従来だとこういった追加を行うとここから1TBx2のミラーを外せません。
# zpool remove pool2 mirror-0

# zpool status pool2
  pool: pool2
 state: ONLINE
  scan: none requested
remove: Removal of vdev 0 copied 512M in 0h0m, completed on Fri Apr  6 00:31:52 2018
    13.2K memory used for removed device mappings
config:

 NAME             STATE     READ WRITE CKSUM
 pool2            ONLINE       0     0     0
   mirror-1       ONLINE       0     0     0
     /tmp/dummy3  ONLINE       0     0     0
     /tmp/dummy4  ONLINE       0     0     0
   mirror-2       ONLINE       0     0     0
     /tmp/dummyA  ONLINE       0     0     0
     /tmp/dummyB  ONLINE       0     0     0

errors: No known data errors

# zfs list pool2
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool2  1.00G  1.69G  1.00G  /Volumes/pool2

ですが、今回はmirror-0を指定して外すことができる!今回は超小容量プールなので一瞬ですが、実際は内部のデータ移動に時間がかかるはず。ですが、replaceを2回かけるよりよっぽど簡単ですね(現実のサーバーではその分のHDDスロットが必要ですが)。

今回のケースだと、大きなディスクに移行したのでmirror-1も外すことができます。
# zpool remove pool2 mirror-1

# zpool status pool2
  pool: pool2
 state: ONLINE
  scan: none requested
remove: Removal of vdev 1 copied 682M in 0h0m, completed on Fri Apr  6 00:32:16 2018
    30.3K memory used for removed device mappings
config:

 NAME             STATE     READ WRITE CKSUM
 pool2            ONLINE       0     0     0
   mirror-2       ONLINE       0     0     0
     /tmp/dummyA  ONLINE       0     0     0
     /tmp/dummyB  ONLINE       0     0     0

errors: No known data errors

# zfs list pool2
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool2  1.00G   767M  1.00G  /Volumes/pool2

「大容量HDDに移行してディスク本数を減らす」といった操作ができるようになったわけです。

RAID-Z


さて、(個人的には)本命のRAID-Z構成です。ミラーと同じようにディスク入れ替えをしたい。
# zpool create pool3 \
> raidz \
> /tmp/dummy1 \
> /tmp/dummy2 \
> /tmp/dummy3 \
> /tmp/dummy4 \
> raidz \
> /tmp/dummy5 \
> /tmp/dummy6 \
> /tmp/dummy7 \
> /tmp/dummy8

# zpool status pool3
  pool: pool3
 state: ONLINE
  scan: none requested
config:

 NAME             STATE     READ WRITE CKSUM
 pool3            ONLINE       0     0     0
   raidz1-0       ONLINE       0     0     0
     /tmp/dummy1  ONLINE       0     0     0
     /tmp/dummy2  ONLINE       0     0     0
     /tmp/dummy3  ONLINE       0     0     0
     /tmp/dummy4  ONLINE       0     0     0
   raidz1-1       ONLINE       0     0     0
     /tmp/dummy5  ONLINE       0     0     0
     /tmp/dummy6  ONLINE       0     0     0
     /tmp/dummy7  ONLINE       0     0     0
     /tmp/dummy8  ONLINE       0     0     0

errors: No known data errors

# zfs list pool3
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool3  1.09M  5.43G   871K  /Volumes/pool3

# cp dummyA dummyB /Volumes/pool3/

# zfs list pool3
NAME    USED  AVAIL  REFER  MOUNTPOINT
pool3  4.00G  1.43G  4.00G  /Volumes/pool3

プールを作って4GBのデータを置くとこんな感じ。

ここに2GBx4のRAID-Zを足して、1TBx4のRAID-Zを抜いてみます。
# zpool add pool3 \
> raidz \
> /tmp/dummyA \
> /tmp/dummyB \
> /tmp/dummyC \
> /tmp/dummyD

# zpool remove pool3 raidz1-0
cannot remove raidz1-0: invalid config; all top-level vdevs must have the same sector size and not be raidz.

が、できませんでした。このremove機能はRAID-Zには対応していないようです。無念・・・


というわけで


一番期待していた、RAID-Zのストライピング構成でRAID-Z vdevを抜く、といったことはできませんでした。RAID-Zを使っている場合は従来どおり1本ずつreplaceしていく必要がありそうです。

ただ、HDDの大容量化も進み、最近ではメンテも楽なミラー構成で使っている方も多いと思います。そういう人にとっては良い機能、あるいはミラーとRAID-Zどちらを使おうか悩んでいる人にはミラーを使う動機になりそうです。

0 件のコメント:

コメントを投稿