バックアップにZFSを使用することを計画しています。 5〜10台のサーバーが、DRBDを介してZFSファイルシステム上の非常に大きなファイル(それぞれ500ギガバイト)に更新を「ストリーミング」します。
サーバーは、合計で約100MBpsのランダム書き込みを毎秒約20メガバイト生成します。私はこれらのファイルを読み取らないので、パターンはほぼ100%の書き込みになるはずです。
私にとって、コピーオンライトは非常に重要な機能です。
私が理解しているように、COWはランダム書き込みをシーケンシャル書き込みに変換する必要があります。しかし、これは起こっていません。
12 SASドライブE5520XEON(4コア)および24 GB RAMで、ランダム書き込みが非常に低かったサーバーでテストしました。
最初に同じサーバー上の1 SAS HDDでデバッグすることにしました。
EXT4ファイルシステムを作成し、いくつかのテストを行いました。
root @ zfs:/ mnt/hdd/test#dd if =/dev/zero of = tempfile bs = 1M count = 4096 conv = fdatasync、notrunc 4096 + 0 records in 4096 +0レコード出力 4294967296バイト(4.3 GB)コピー、30.2524秒、142MB /秒[.____]
したがって、書き込み速度は約140MBpsであることがわかります。
ランダム書き込み〜500 KBps〜100〜150iops。これは正常です。
fio --randrepeat = 1 --ioengine = libaio --direct = 1 --gtod_reduce = 1 --name = test --filename = test --bs = 4k --iodepth = 1 --size = 4G --readwrite = randwrite test:(g = 0):rw = randwrite、bs = 4K-4K/4K-4K/4K-4K、ioengine = libaio、iodepth = 1 fio -2.1.11 1プロセスの開始 bs:1(f = 1):[w(1)] [0.6%完了] [0KB/548KB/0KB/s] [0/137/0 iops] [eta 02h:02m:57s]
次に、同じドライブでZFSを作成しました。
zpool create -f -m/mnt/data bigdata scsi-35000cca01b370274
4Kのランダム書き込みがあるため、レコードサイズを4Kに設定しました。私がテストしていたとき、レコードサイズ4Kは128kよりもうまく機能しました。
zfs set recordsize = 4k bigdata
4Gファイルへのランダム書き込みをテストしました。
fio --randrepeat = 1 --ioengine = libaio --gtod_reduce = 1 --name = ./ test --filename = test --bs = 4k --iodepth = 1 --size = 4G- readwrite = randwrite ./ test:(g = 0):rw = randwrite、bs = 4K-4K/4K-4K/4K-4K、ioengine = libaio、iodepth = 1 fio- 2.1.11 1プロセスの開始 ./ test:レイアウトIO file(s)(1 file(s)/ 4096MB) ジョブ:1(f = 1):[w(1)] [100.0%完了] [0KB/115.9MB/0KB/s] [0/29.7K/0 iops] [eta 00m:00s ]
COWはここで毎秒115.9MBでうまくいったようです。
16Gファイルへのランダム書き込みをテストしました。
fio --randrepeat = 1 --ioengine = libaio --gtod_reduce = 1 --name = test --filename = ./ test16G --bs = 4k --iodepth = 1 --size = 16G- readwrite = randwrite test:(g = 0):rw = randwrite、bs = 4K-4K/4K-4K/4K-4K、ioengine = libaio、iodepth = 1 fio-2.1.11 1プロセスの開始 bs:1(f = 1):[w(1)] [0.1%完了] [0KB/404KB/0KB/s] [0/101/0 iops] [eta 02h:08m:55s]
非常に悪い結果は毎秒400キロバイトです。
8Gファイルで同じことを試しました:
fio --randrepeat = 1 --ioengine = libaio --gtod_reduce = 1 --name = test --filename = ./ test8G --bs = 4k --iodepth = 1 --size = 8G- readwrite = randwrite test:(g = 0):rw = randwrite、bs = 4K-4K/4K-4K/4K-4K、ioengine = libaio、iodepth = 1 fio-2.1.11 1プロセスの開始 テスト:レイアウトIOファイル(1ファイル/ 8192MB) bs:1(f = 1):[w(1)] [14.5%完了] [0KB/158.3MB/0KB/s] [0/40.6K/0 iops] [eta 00m:53s ]
当初、COWは毎秒136メガバイトで問題ありませんでした。
デバイス:rrqm/s wrqm/sr/sw/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm%util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sdg 0.00 0.00 0.00 1120.00 0.00 136.65 249.88 9.53 8.51 0.00 8.51 0.89 99.24
しかし、テストが90%に達したとき、書き込み速度は1秒あたり5メガバイトに低下しました。
デバイス:rrqm/s wrqm/sr/sw/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm%util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sdg 0.00 0.00 0.00 805.90 0.00 5.33 13.54 9.95 12.34 0.00 12.34 1.24 100.00
したがって、4Gファイルは問題なく、8Gはほぼ問題ありませんが、16GファイルはCOWを取得していません。
ここで何が起こっているのか理解できません。ここでは、メモリキャッシュが役割を果たす可能性があります。
OS:Debian 8 ZFSver500。圧縮や重複排除はありません。
zpool list NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT bigdata 1.81T 64.4G 1.75T-2%3%1.00xONLINE- root @ zfs:/ mnt/data/test#zdb bigdata: バージョン:5000 名前: 'bigdata' 状態:0 txg:4 pool_guid:16909063556944448541 errata:0 hostid:8323329 ホスト名: 'zfs' vdev_children:1 vdev_tree: type: 'root' id:0 guid:16909063556944448541 create_txg:4 children [0]: type: 'disk' id:0 guid:8547466691663463210 path: '/ dev/disk/by- id/scsi-35000cca01b370274-part1 ' whole_disk:1 metaslab_array:34 metaslab_shift:34 ashift:9 asize: 2000384688128 is_log:0 create_txg:4 features_for_read: com.delphix:hole_birth com.delphix:embedded_data zpool status bigdata プール:bigdata 状態:ONLINE スキャン:要求なし config: NAME STATE READ WRITE CKSUM bigdata ONLINE 0 0 0 scsi-35000cca01b370274 ONLINE 0 0 0 エラー:既知のデータエラーはありません
fioはZFS上のO_DIRECTでは機能しません。それなしで実行する必要がありました。私が理解しているように、それはさらに良い結果を生み出すはずです。しかし、それは起こっていません。
fio --randrepeat = 1 --ioengine = libaio --direct = 1 --gtod_reduce = 1 --name = ./ test --filename = test16G --bs = 4k --iodepth = 1- size = 16G --readwrite = randwrite ./ test:(g = 0):rw = randwrite、bs = 4K-4K/4K-4K/4K-4K、ioengine = libaio、iodepth = 1 fio-2.1.11 1プロセスの開始 fio:ファイルシステムがdirect = 1/buffered = 0 fio:宛先がO_DIRECTをサポートしていないようです
これは公正な戦いではありません:
dd
を使用しているときはゼロを書き込んでいますが、 fio
はデフォルトで単一のランダムブロックを生成し、可能な場合はそれを再利用します 。すべてのゼロは(わずかに)圧縮性が高いため、これにより数値が歪む可能性があります。dd
で使用されているブロックサイズは1MByteですが、fio
行で使用されているサイズは4KBytesです。iodepth
実行のfio
を1つだけに制限しています(この選択は、上記のddブロックサイズの選択よりも小さいものを合成します)。dd
は常にライトバックキャッシュの使用を許可されていますが、fio
の実行の1つは許可されていません(direct=1
を設定していたため)。O_DIRECT
を「許可」しないため、libaio
でより高い深度を使用しようとしても、送信は非同期ではありません( SSD IOPS on linux、DIRECTはバッファリングよりもはるかに高速です。fio )が、未処理の最大I/Oは1つに制限されているため(上記を参照)、これは重要な問題です。dd
は、メモリのサイズ(24GBytes)と比較して、書き込みデータが非常に少ない(4GBytes)ため、Linuxが終了したときにページキャッシュに大量の書き込みデータが残っている可能性があります。それが実際に不揮発性ストレージに到達したことを確認するには、少なくとも何らかのファイル同期を行う必要があります...conv=fdatasync
はdd
に設定されているため、終了する前に最終的なfdatasyncがあり、データが不揮発性だけではないことが保証されます。キャッシュ。最低限、最初からやり直すことをお勧めします。ZFSですべてのテストを実行し、順次テストとランダムテストの両方にfio
を使用し、残りの行は同じままにします。 end_fsync
のようなものを使用して、データが実際にディスクにヒットし、不揮発性キャッシュだけにないことを確認することも検討します(ただし、このビットをスキップするための引数を見ることができます) 。
TLDR;比較方法に欠陥があるのではないかと思います。比較間の変更を少なくしたほうがよいのではないでしょうか。