FreeBSD 11.1-STABLEを使用してgzip-9圧縮と8Kのレコードサイズで構成されるZFSデータセットがあります。 (このボリュームは速度ではなく小さなファイルを保持するために使用されます。)
zfs get all pool02/redactedStorage
1.4倍の圧縮率を示しますね。思ったより悪いですが、そこにはテキストファイルと圧縮ファイルが混ざっていて大きく気になるほどではありません。その後、このデータセットに保存されているいくつかの大容量zipファイルを見て混乱しました。
du -h
との出力は、du -hA
圧縮ファイルに期待したものとは異なります。
たとえば、40MBのゼロファイルはディスク容量をほとんど占有しないと予想されます。
# dd if=/dev/zero of=testfile bs=4M count=10
# du -h testfile
512B testfile
# du -hA testfile
40M testfile
ただし、40 MBのランダムファイルは圧縮できないため(すべての実用的な目的のために)約40 MBのディスク容量を消費すると予想されます。しかし、ほとんど消費されるとは知りませんでした。ダブルスペース:
# dd if=/dev/random of=testfile.rnd bs=4M count=10
# du -h testfile.rnd
92M testfile.rnd
# du -hA testfile.rnd
40M testfile.rnd
研究によると、間接ブロックは余分なスペースを消費するようです。
testfile
(0)について:
Dataset pool02/redactedStorage [ZPL], ID 56, cr_txg 360697, 958G, 22881480 objects, rootbp DVA[0]=<0:9dd68959000:3000> DVA[1]=<0:14e1475b5000:3000> [L0 DMU objset] fletcher4 uncompressed LE contiguous unique double size=800L/800P birth=25863270L/25863270P fill=22881480 cksum=13497492df:14cc540c2b5f:e089aa02d6109:73afb0d244bcb42
Object lvl iblk dblk dsize lsize %full type
22910497 3 128K 8K 0 40.0M 0.00 ZFS plain file
168 bonus System attributes
dnode flags: USED_BYTES USERUSED_ACCOUNTED
dnode maxblkid: 5119
path /testfile
uid 0
gid 1004
atime Wed Apr 19 00:08:20 2023
mtime Wed Apr 19 00:08:20 2023
ctime Wed Apr 19 00:08:20 2023
crtime Wed Apr 19 00:08:20 2023
gen 25862395
mode 100644
size 41943040
parent 17938432
links 1
pflags 40800000004
Indirect blocks:
[ No Indirect blocks ]
testfile.rnd
(任意性)の場合:
Dataset pool02/redactedStorage [ZPL], ID 56, cr_txg 360697, 958G, 22881480 objects, rootbp DVA[0]=<0:9dbfec9d000:3000> DVA[1]=<0:14ffe1461000:3000> [L0 DMU objset] fletcher4 uncompressed LE contiguous unique double size=800L/800P birth=25863170L/25863170P fill=22881480 cksum=13b3f2c021:15912a82ff8a:ebef1e0641453:7abda3903292dba
Object lvl iblk dblk dsize lsize %full type
22910499 3 128K 8K 91.9M 40.0M 100.00 ZFS plain file
168 bonus System attributes
dnode flags: USED_BYTES USERUSED_ACCOUNTED
dnode maxblkid: 5119
path /testfile.rnd
uid 0
gid 1004
atime Wed Apr 19 00:16:47 2023
mtime Wed Apr 19 00:16:48 2023
ctime Wed Apr 19 00:16:48 2023
crtime Wed Apr 19 00:16:47 2023
gen 25862495
mode 100644
size 41943040
parent 17938432
links 1
pflags 40800000004
Indirect blocks:
[ 5120 Indirect blocks redacted ]
それでは、間接ブロック5120個* 128K = 640Mで、これらのブロックが圧縮されて51.9Mのオーバーヘッドが発生しますか?
それでは、この問題を解決するための最良の方法は何ですか? レコードサイズの大きい新しいデータセットを作成し、コンテンツを別の場所に移動しますか?
私のデータセットパラメータは次のとおりです。
NAME PROPERTY VALUE SOURCE
pool02/redactedStorage type filesystem -
pool02/redactedStorage creation Mon Jan 28 1:03 2019 -
pool02/redactedStorage used 958G -
pool02/redactedStorage available 15.1T -
pool02/redactedStorage referenced 958G -
pool02/redactedStorage compressratio 1.40x -
pool02/redactedStorage mounted yes -
pool02/redactedStorage quota none local
pool02/redactedStorage reservation none local
pool02/redactedStorage recordsize 8K local
pool02/redactedStorage mountpoint /mnt/pool02/redactedStorage default
pool02/redactedStorage sharenfs off default
pool02/redactedStorage checksum on default
pool02/redactedStorage compression gzip-9 local
pool02/redactedStorage atime on default
pool02/redactedStorage devices on default
pool02/redactedStorage exec on default
pool02/redactedStorage setuid on default
pool02/redactedStorage readonly off default
pool02/redactedStorage jailed off default
pool02/redactedStorage snapdir hidden default
pool02/redactedStorage aclmode passthrough local
pool02/redactedStorage aclinherit passthrough inherited from pool02
pool02/redactedStorage canmount on default
pool02/redactedStorage xattr off temporary
pool02/redactedStorage copies 1 default
pool02/redactedStorage version 5 -
pool02/redactedStorage utf8only off -
pool02/redactedStorage normalization none -
pool02/redactedStorage casesensitivity sensitive -
pool02/redactedStorage vscan off default
pool02/redactedStorage nbmand off default
pool02/redactedStorage sharesmb off default
pool02/redactedStorage refquota none local
pool02/redactedStorage refreservation none local
pool02/redactedStorage primarycache all default
pool02/redactedStorage secondarycache all default
pool02/redactedStorage usedbysnapshots 0 -
pool02/redactedStorage usedbydataset 958G -
pool02/redactedStorage usedbychildren 0 -
pool02/redactedStorage usedbyrefreservation 0 -
pool02/redactedStorage logbias latency default
pool02/redactedStorage dedup off inherited from pool02
pool02/redactedStorage mlslabel -
pool02/redactedStorage sync standard default
pool02/redactedStorage refcompressratio 1.40x -
pool02/redactedStorage written 958G -
pool02/redactedStorage logicalused 501G -
pool02/redactedStorage logicalreferenced 501G -
pool02/redactedStorage volmode default default
pool02/redactedStorage filesystem_limit none default
pool02/redactedStorage snapshot_limit none default
pool02/redactedStorage filesystem_count none default
pool02/redactedStorage snapshot_count none default
pool02/redactedStorage redundant_metadata all default
zdb
関連プールを示すいくつかの出力は次のとおりです。
(ashift: 12
このプールのデフォルトvdevをメモしてください。)
pool02:
version: 5000
name: 'pool02'
state: 0
txg: 25383030
pool_guid: 1288056053628670413
hostid: 3785389258
hostname: 'redacted'
com.delphix:has_per_vdev_zaps
vdev_children: 1
vdev_tree:
type: 'root'
id: 0
guid: 1288056053628670413
create_txg: 4
children[0]:
type: 'raidz'
id: 0
guid: 9072182531784548301
nparity: 2
metaslab_array: 49
metaslab_shift: 37
ashift: 12
asize: 23978959699968
is_log: 0
create_txg: 4
com.delphix:vdev_zap_top: 36
children[0]:
type: 'disk'
id: 0
guid: 17108175667375824896
path: '/dev/gptid/e07bacd6-1224-11e9-98bd-90b11c29519f'
whole_disk: 1
DTL: 293
create_txg: 4
com.delphix:vdev_zap_leaf: 37
children[1]:
type: 'disk'
id: 1
guid: 6726950469173540573
path: '/dev/gptid/e443f9f2-1224-11e9-98bd-90b11c29519f'
whole_disk: 1
DTL: 292
create_txg: 4
com.delphix:vdev_zap_leaf: 38
--------==== 10 ADDITIONAL PHY DISKS REDACTED ====---------
features_for_read:
com.delphix:hole_birth
com.delphix:embedded_data
答え1
4Kセクタ(合計12個)を持つ12個のディスクで構成されたvdevで8Kレコードをストライピングすることはashift
悪い考えであり、多くのオーバーヘッドをもたらします。
OpenZFSから:
https://openzfs.github.io/openzfs-docs/基本概念/RAIDZ.html
これらの入力により、レコードサイズがセクタサイズ以下である場合、RAIDZのパリティサイズは同じ冗長性を持つミラーと実質的に同じです。たとえば、3つのディスクを持つraidz1(ashift = 12とrecords = 4K)の場合は、ディスクに次のものを割り当てます。
4Kデータブロック1個
4Kパディングブロック1個
利用可能なスペース比は50%で、デュアルミラーと同じです。
3つのディスクがあり、ashift = 12でレコードサイズ= 128Kのraidz1の別の例:
総ストライプ幅は3です。
1つのパリティブロックがあるため、ストライプは最大2つの4Kサイズのデータ部分を持つことができます。
それぞれ8Kデータと4Kパリティを含む128K / 2 = 64のストライプがあります。
したがって、この例の空き容量比は66%です。
RAIDZにディスクが多いほど、ストライプが広くなり、スペース効率が向上します。
このテキストの後には、画面をキャプチャしてここに含めると読み取れない図がありますが、セクタサイズの1倍または2倍のレコードサイズの場合、オーバーヘッドがRAIDZ2で67%になることを示しています。
チャートによると、この場合、ソリューションはrecordsize
12ディスクRAIDZ2 vdevからパリティ+パディングコストが18%の256Kに増やすことです。 (recordsize
比較すると、128Kの場合、24%のオーバーヘッドが発生します)。
しかし、それほど単純ではありません。 「クラシック」ファイルシステムでは、次のように初期選択である8Kがrecordsize
正しいことがあります。recordsize
最高固定ブロックサイズではなくブロックサイズ。しかし、recordsize
より大きなファイルと比較的小さいファイルについてはまだ不利益があります。
増加はrecordsize
変更後に生成されたデータにのみ影響しますが、この場合、プールはスペースの6%しか消費されず、現在の圧縮率は1.4倍です。長期的な容量の問題を引き起こすことなく、既存のデータをそのまま維持できます。ただし、回復オーバーヘッドが必要な場合:
https://openzfs.github.io/openzfs-docs/パフォーマンスとチューニング/ワークロード Tuning.html
アプリケーションが他のレコードサイズでより良いパフォーマンスを発揮する必要があるため、レコードサイズを変更する場合は、そのファイルを再生成する必要があります。各ファイルにcpの後にmvがあれば十分です。または、完全な受信が完了したら、send / recvは正しいレコードサイズでファイルを再生成する必要があります。
相関プーリングの実際の実験では:
# zfs set recordsize=256K pool02/redactedStorage
# dd if=/dev/zero of=testfile256.40M.zeroes bs=1M count=40
# du -h testfile256.40M.zeroes
512B testfile256.40M.zeroes
# dd if=/dev/random of=testfile256.40M.rnd bs=1M count=40
# du -h testfile256.40M.rnd
40M testfile256.40M.rnd
# dd if=/dev/random of=testfile256.8K.rnd bs=8192 count=1
# du -h testfile256.8K.rnd
37K testfile256.8K.rnd
ご覧のとおり、40Mファイルは大量の論理スペースを使用しています。しかし、8Kファイルは37Kのスペースを消費します!
したがって、recordsize
データセットの内容に応じて調整する必要があります。
もちろん、128Kのデフォルト値recordsize
が最適なようですので、触れないでください。
# zfs set recordsize=128K pool02/redactedStorage
# cp testfile256.40M.rnd testfile128.40M.rnd
# du -h testfile128.40M.rnd
512B testfile128.40M.rnd
# mv testfile128.40M.rnd testfile128.40M.rnd2
# du -h testfile128.40M.rnd2
40M testfile128.40M.rnd2
# cp testfile256.8K.rnd testfile128.8K.rnd
# mv testfile128.8K.rnd testfile128.8K.rnd2
# du -h testfile128.8K.rnd2
19K testfile128.8K.rnd2
これは、8Kテストファイルが19Kのディスク容量を使用しますが、必要なメタデータオーバーヘッドがあることを示しています。見ている非圧縮性既存のファイルサイズは<= 8Kで、すべてのファイルも元のファイルからrecordsize=8K
19Kのディスク使用量を表示します。さらに試しましたが、recordsize=64K
サンプルファイルのサイズには何の影響もありませんでした。
また、newの下にファイルインスタンスを作成するには、cp
後者が実際に必要であることに注意してください。mv
recordsize
この記事はまた、何が起こっているかについての良い説明を提供し、これは子孫のために残すでしょう。
https://klarasystems.com/articles/choosing-the-right-zfs-pool-layout/
- パディング、ディスクセクタサイズ、レコードサイズの設定:RAID-Zでは、パリティ情報はRAID-5のように特定のストライプではなく各ブロックに関連付けられているため、小さすぎて再利用できないセグメントが解放されるのを防ぐために、各データ割り当てはp + 1(パリティ+ 1)複数である必要があります。割り当てられたデータがp + 1の倍数ではない場合は「パディング」が使用されるため、RAID-ZはRAID-5よりも少しパリティとパディングスペースが必要です。これは複雑な質問ですが、簡単に言ってスペースの非効率性を防ぐために、ZFSレコードサイズをディスクセクタサイズよりはるかに大きく保つ必要があります。 512バイトセクタディスクの場合は、Recordsize = 4Kまたは8Kを使用できます。 4Kセクターディスクの場合、Recordsizeはこの値の数倍でなければなりません(デフォルトは128Kで十分です)。そうしないと、あまりにも多くのスペースを失う可能性があります。