web-dev-qa-db-ja.com

書き込み時のZFSコピー

バックアップに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をサポートしていないようです
3
Igor Chulkov

これは公正な戦いではありません:

  • ddを使用しているときはゼロを書き込んでいますが、 fioはデフォルトで単一のランダムブロックを生成し、可能な場合はそれを再利用します 。すべてのゼロは(わずかに)圧縮性が高いため、これにより数値が歪む可能性があります。
  • ddで使用されているブロックサイズは1MByteですが、fio行で使用されているサイズは4KBytesです。
  • iodepth実行のfioを1つだけに制限しています(この選択は、上記のddブロックサイズの選択よりも小さいものを合成します)。
  • ddは常にライトバックキャッシュの使用を許可されていますが、fioの実行の1つは許可されていません(direct=1を設定していたため)。
  • お使いのバージョンのZFSはO_DIRECTを「許可」しないため、libaioでより高い深度を使用しようとしても、送信は非同期ではありません( SSD IOPS on linux、DIRECTはバッファリングよりもはるかに高速です。fio )が、未処理の最大I/Oは1つに制限されているため(上​​記を参照)、これは重要な問題です。
  • ddは、メモリのサイズ(24GBytes)と比較して、書き込みデータが非常に少ない(4GBytes)ため、Linuxが終了したときにページキャッシュに大量の書き込みデータが残っている可能性があります。それが実際に不揮発性ストレージに到達したことを確認するには、少なくとも何らかのファイル同期を行う必要があります...コメントで指摘conv=fdatasyncddに設定されているため、終了する前に最終的なfdatasyncがあり、データが不揮発性だけではないことが保証されます。キャッシュ。
  • Ext4ボリュームでのシーケンシャルとZFSボリュームでのランダムを比較しています(比較の間にワークロードとファイルシステムを変更しました)。

最低限、最初からやり直すことをお勧めします。ZFSですべてのテストを実行し、順次テストとランダムテストの両方にfioを使用し、残りの行は同じままにします。 end_fsync のようなものを使用して、データが実際にディスクにヒットし、不揮発性キャッシュだけにないことを確認することも検討します(ただし、このビットをスキップするための引数を見ることができます) 。

TLDR;比較方法に欠陥があるのではないかと思います。比較間の変更を少なくしたほうがよいのではないでしょうか。

1
Anon