VirtualBox上のWin 7でディスクイメージとzvolの速度比較(ついでにbhyveも)
仮想マシンのストレージ形式について、一般的にはイメージファイルよりもzvolの方が適していると言われている。ホストのファイルシステムレイヤを通過したファイル上にゲストのFSレイヤを通したFSを構築するよりかは、zvol(の薄いレイヤしか通らない)のブロックデバイスをゲストのFSレイヤに渡した方が効率が良さそう、ってのは理屈としても合っている。
以前から実際に速度比較しようと思いつつ、ようやく実行に移せた。環境は以下の通り。
- ホスト
- FreeBSD 11.1-RELEASE-p1
- VirtualBox 5.2.0
- CPU: Xeon E5-2648Lv3 1.8GHz 12C24T
- RAM: 64GB
- SSD: Intel DC S3500 480GB
- SATA 3接続
- ZFSのLZ4で透過圧縮している
- ゲスト
- Windows 7 Ultimate (x64)
- CPU: 4コア
- RAM: 8GB
- SSD: VirtIO 40GB
ゲストのストレージを、同一内容のイメージファイルとzvolデバイスとで切り替えてCrystalDiskMark 6.0.0で速度を計測した。なお、イメージファイルからzvolへの変換は以下のコマンドで行った。
VBoxManage clonehd /path/to/vms/Windows/HDD.vmdk /path/to/vms/HDD.raw --format RAW zfs create -V 40G zvm/zvols/Windows dd if=/path/to/vms/Windows/HDD.raw of=/dev/zvol/zvols/Windows bs=4096 VBoxManage internalcommands createrawvmdk -filename /path/to/vms/Windows/zvol.vmdk -rawdisk /dev/zvol/zvols/Windows
おろ、殆ど変わらんがな…(´・ω・`)。シーケンシャルR/W共にSATA 3の上限ぶっちぎっちゃってるし、ホストのキャッシュが効いちゃってる?
というわけで、VirtualBoxの「ホストのI/Oキャッシュを使う」オプションを切って再計測。
すごく、、、速いです………。こりゃZFSのキャッシュが効いてるなー。確認してみるとARCで4.8GB持ってるしなー。ベンチ中にtopで見てるとARCがもりもり増えてくし。
ついでにイメージファイルをHDDに置いた時のベンチも取ってみた。
うっは2.5インチHDDとは思えぬ速さwwwww
zpool iostatの結果を見るに、ランダムライトはZFS側でまとめられ、ほぼシーケンシャルライトとしてHDDに書き出されているようだ。
capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- zhome2 1.33T 1.38T 1 922 153K 105M mirror 1.33T 1.38T 1 922 153K 105M ada3p1 - - 0 861 25.5K 105M ada2p1 - - 0 875 127K 107M logs - - - - - - mirror 40K 3.97G 0 0 0 0 ada0p4 - - 0 0 0 0 ada1p4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- zhome2 1.33T 1.38T 2 932 277K 111M mirror 1.33T 1.38T 2 932 277K 111M ada3p1 - - 0 919 50.4K 114M ada2p1 - - 1 890 227K 110M logs - - - - - - mirror 40K 3.97G 0 0 0 0 ada0p4 - - 0 0 0 0 ada1p4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- zhome2 1.33T 1.38T 0 962 102K 119M mirror 1.33T 1.38T 0 962 102K 119M ada3p1 - - 0 941 102K 117M ada2p1 - - 0 965 0 120M logs - - - - - - mirror 40K 3.97G 0 0 0 0 ada0p4 - - 0 0 0 0 ada1p4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- zhome2 1.34T 1.38T 1 940 153K 113M mirror 1.34T 1.38T 1 940 153K 113M ada3p1 - - 0 918 76.7K 113M ada2p1 - - 0 906 76.7K 112M logs - - - - - - mirror 40K 3.97G 0 0 0 0 ada0p4 - - 0 0 0 0 ada1p4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- -----
結論としては、イメージファイルでもzvolでも大差なさそう。ストレージ形式の差よりも、ZFSそのものの動作環境やチューニングの差の方が覿面に影響しそう。なので、好きな方を使えばいいんじゃないかな。俺は扱いやすいイメージファイルの方を選ぶんだぜ。
とりあえずZFSパネェ…。
(2017-11-25 追記)
ついでにbhyveでもやってみた。
ストレージは同一SSDだけど、計測環境は新規インストールのWindows 10なので厳密な比較にはならんけど。なお、ストレージはahci-hdで繋いでる。virtio-blkはWindowsでは現状未対応らしい。
ベンチ結果は左から、gzip-5のZFS上のイメージファイル、同zvol、lz4なzvol。
FreeBSD 11で「warning: total configured swap (X pages) exceeds maximum recommended amount (Y pages).」と言われた時の対処法
物理メモリ1.5GBのFreeBSD 11.1-RELEASE環境で、16GBのスワップを追加したら以下のメッセージが表示された。
warning: total configured swap (4194304 pages) exceeds maximum recommended amount (2994784 pages) warning: increase kern.maxswzone or reduce amount of swap.
カーネルが扱えるサイズを超えるスワップを追加すると出るそうで。本事例だと、最大スワップサイズは2994784ページで、1ページ=4KiBなので約11.4GiBとなる。
この値はどこで決まるかと言えば、warningの2つ目で示されているkern.maxswzone
カーネルパラメータである。スワップ管理用メモリの最大バイト数を指定するパラメータで、11.1Rではスワップ約200MiBにつき1MiBが必要とのこと。特に指定しなければ、物理メモリの8倍のスワップを扱うのに十分な容量が確保される。
実際に確保された量は恐らくvm.swzone
パラメータの値。本事例では53904384バイトとなっており、計算するとwarning中の最大スワップサイズと概ね一致する。
というわけで、/boot/loader.conf
に次の一行を追加してみた。
kern.maxswzone="75464704"
値はまー適当。11.4GiBで53904384バイト必要なんだから、16GBなら1.4倍して一応4KiB単位に揃えた感じ。
これで再起動すればOK!
……のハズだったんだけど、なぜか値が反映されないの(´・ω・`)。kern.maxswzone
には反映されるんだけど、肝心のvm.swzone
が変わってない。警告も相変わらず出る。kern.maxswzone
は名前の通り最大値を制限するものであって、スワップの最大サイズは物理メモリの8倍という制限は超えられないって事なのかしら…?これ以上はソース見ないとわからんな。
参考サイト
ZFSのメンバだったディスクを再利用する時はzpool labelclearすべき
一度でもZFSで使ったことがあるストレージを別のzpoolに使い回す際は、zpool labelclearコマンドで当該デバイスからZFSラベル情報を消した方が良さそうだ。
再利用デバイスで新しいプールを作ろうとすると、殆どの場合は以下のようなエラーが出て作ることができない。
# zpool create ztank da0p3 invalid vdev specification use '-f' to override the following errors: /dev/da0p3 is part of potentially active pool 'zroot'
「有効なプールzrootの一部かもよ」とZFS先生は仰ってるものの、zrootは間違いなくdestroy済みで、僕は確信を以てda0p3でztankを作りたいのだよ。先生ったらお節介~。destroyしたんだからラベル情報も一緒に消しとけよ!と思わなくもないが、ZFSではdestroyの取り消しをサポートしてたりする関係で、こういう仕様なのだろう。削除済みプールの復元については、zpool importの-Dオプションを調べておくんなまし。
ところがである、条件は不明だが、このお節介が働かず以前のラベル情報を残したまま新プールが作れちゃうことがある。こうなるとマジで大惨事。新しいプールと昔のプールが管理情報の上では存在する事になり、見るからにヤバげな状態となる。その時の再現ログが↓これ。
# zpool status pool: newtank state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM newtank ONLINE 0 0 0 da0p3 ONLINE 0 0 0 errors: No known data errors pool: oldtank state: UNAVAIL scan: none requested config: NAME STATE READ WRITE CKSUM oldtank UNAVAIL 0 0 0 1234567890123456789 UNAVAIL 0 0 0 errors: No known data errors
ログ上からは、別々のストレージで構成される2つのプール、newtankとoldtankがあるようにしか見えない。しかし実際のところ、oldtankはnewtank以前にda0p3で使っていたもので、既にdestroy済みのプールなのである。newtankとして実際にデータが書き込まれ、意味消失してるハズの削除済みプールoldtankが認識されているのだ…!
こうなると最早手遅れ。oldtankを再度destroyしようにも「そんなプールは存在しない」と言われるし、ならばとデバイス1234567890123456789をどうにかする方向で頑張ってもどうにもならず…。かと言って、この段階でlabelclearは絶対にしてはいけない。newtankもろとも消えてしまうので_:(´ཀ`」∠):_(実体験)。
というわけで、ZFSプールを作る時は忘れずにlabelclearで以前の情報を消すようにしたい。
(2017-11-14 追記)
やった事はと言うと…
- 以前のzroot(赤い方)を削除しlabelclear
- 新しいzroot(緑の方)を作成
- FreeBSD 11.0-RELEASEをインストール
- freebsd-updateで11.1-RELEASEに更新するも、ブート時のTrying to mount root~で失敗して起動しなくなる
- 今にして思えば、この時点で古いプールが認識されて旧zrootの方をマウントしようとしてたのかも…?
- kernel.oldの方から起動してfreebsd-updateで11.0の最新にしようとする
- 見事に失敗して起動しなくなる。起動スプラッシュのシェルでload kernelもload zfsも失敗する状態。
- インストーラメディアから起動してzpool importしたらこの状態
確かにlabelclearしたハズなんだけどなぁ…。変なzpool.cacheでも食ってんのかなぁ…?わからん。
(2017-11-16 追記)
あ、ありのまま起こったことを(ry。
症状が出たHDDの各パーティションを再度labelclearしてddでゼロフィルまでしたにもかかわらず、古い方のzrootが認識されやがったぜ……。最終的にzpool labelclear da0
してようやく認識されなくなった。(が、当然GPTは壊れる。セカンダリテーブルは生きてるからパーティションの認識と復旧は可能だが…。)GPTの領域にZFSラベルが書き込まれそうな使い方─つまりディスク全体をzpoolにするような使い方はした記憶がないんだが、どうしてこうなった……?
結論としては、zpoolを作る時は対象デバイスの/dev/daX
と/dev/daXpY
を全てlabelclearするのが安全、可能なら全体をゼロフィルするということで。
PCの電源を80 PLUS GOLDからPLATINUMに変えて10W節電
ひょんなことから、自宅PCの電源をSeasonic SSR-450RM (450W/80 PLUS GOLD)からSUPER FLOWER SF-850F14MP (850W/80 PLUS PLATINUM)に交換した。
CPU | AMD Ryzen 5 1400 |
---|---|
M/B | MSI X370 SLI PLUS |
メモリ | DDR4-2666 8GB×2 |
SSD | Intel SSD DC S3500 600GB |
GPU | GeForce GTX 1070 |
GeForce GTX 1060 (6GB) | |
GeForce GTX 1060 (3GB) | |
GeForce GTX 1060 (3GB) | |
OS | Windows 10 Pro. (x64) |
結果、上記環境で似たような条件で動かした場合の消費電力が、370W前後から360W前後へと約10W減った。24時間1ヶ月ブン回せば7.2kWh、25円/kWhとして180円の節約だ。
これでGPUを後2枚は追加できるな…!(ぉ
FreeBSD 12でRAID-Zのvdev拡張が出来るようになるかもしれない
Twitterを眺めてたら「ZFS RAIDZ expansion」なるパワーワードが目に飛び込んできた。
調べたところOpenZFS Developer Summit 2017で発表された機能で、その名の通りRAID-Zプールの構成を後から拡張できる機能のようだ。我らがFreeBSD Foundationからも声明が出ていた。Delphixとの協業のようで。
ご存知の通り、現在のRAID-Zでは後からプールのvdev構成を変更することが出来ない。この制約のため、例えばHDD×3本でRAID-Zプールを作ったが最後、容量が足りなくなったからといって、後からHDDを1本追加してHDD×4本構成にするといったことが不可能なのだ。容量を増やしたければ、vdevの構成HDDを大容量のものに入れ替えるか、別のvdevを追加するか(先の例で言えばHDD×3本のRAID-Zセットを追加してRAID-Zのストライピングにする)しかない。だがしかーし、RAID-Z expansionが実装されれば、これまで不可能だった直感的なプール拡張が出来るようになる。ZFSが今以上に使いやすくなること間違い無し!
声明によれば”FreeBSD 12.0で利用可能になるだろう”(RAID-Z expansion is expected to become available in FreeBSD 12.0.)とのこと。”expect”は7割くらいの確度だから実現性は結構高い。OpenZFSとしての実装になるようなので、実現の暁には多くの環境に恩恵があるだろう。FreeBSDのみならずZFS界隈にとって、なかなかインパクトのあるニュースではなかろうか。
現時点でFreeBSD 12のリリーススケジュールは未定だけど、とにかく楽しみな機能ですわー。
OpenZFS Developer Summit関連ついでに、ZFSをWindowsに移植するプロジェクトZFSinの存在も知った。マイルストンを見るに殆どの機能が実装されており、問題なく動きそうな雰囲気…!これも胸熱……!!