使用FreeBSD 11.1-稳定,我有一个ZFS数据集配置gzip-9压缩,以及记录大小为8K。(此卷用于小文件的存档,而不是速度。)
zfs get all pool02/redactedStorage显示的压缩比为1.4x,比我预料的还要糟糕,但这里有大量的文本文件和压缩文件,所以这并不令人担忧。然后,我查看了存储在该数据集中的一些大型的压缩文件,并感到困惑。
du -h和du -hA的输出不是我所期望的压缩文件的输出。
例如,我预计一个40 MB的零文件几乎不会占用任何磁盘空间:
# 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 (零):
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个间接块*128 K=640米,然后这些块被压缩,从而导致51.9米的开销?
如果是的话,什么是最好的方法来避免混乱呢?创建一个具有更大记录大小的新数据集并将内容移到上面?
以下是我的数据集参数:
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的部分输出:
(请注意这个池的底层vdev的ashift: 12。)
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发布于 2023-04-20 05:54:05
在由12个带4K扇区的磁盘组成的vdev上对8K记录进行条带化( ashift为12)是一个糟糕的想法,并造成巨大的开销:
来自OpenZFS:
https://openzfs.github.io/openzfs-docs/Basic概念/RAIDZ.html
由于这些输入,如果记录大小小于或等于扇区大小,则RAIDZ的奇偶校验大小将有效地等于具有相同冗余的镜像。例如,对于具有raidz1和recordsize=4K的3个磁盘,我们将在磁盘上分配:
可用空间比为50%,与双面镜相同。3个磁盘的ashift=12和recordsize=128K的raidz1的另一个示例:
因此,在这种情况下,可用空间比率将为66%。RAIDZ的磁盘越多,条纹越宽,空间效率越高。
该文本后面是一个图表,如果截图并包含在这里,它将是难以辨认的,但它表明,对于记录大小为1倍或2倍的扇区大小,开销将是67%的RAIDZ2。
根据图表,这种情况下的解决方案是将recordsize提高到256 K,这在12个磁盘RAIDZ2 vdev上的parity+padding成本为18%。(相比之下,128 K recordsize将产生24%的开销)。
但没那么简单。对于“经典”文件系统,最初选择8K recordsize可能是正确的,因为recordsize是最大块大小,而不是固定块大小。但是,对于具有相对较小文件的较大recordsize,仍有一定的损失。
增加recordsize只会影响更改后创建的数据,但在这种情况下,池的空间消耗仅为6%,当前压缩比为1.4x。现有数据可以保持在原地,而不会造成任何长期能力问题。然而,在需要收回间接费用的情况下:
https://openzfs.github.io/openzfs-docs/Performance和调优/工作负载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应该调优到数据集的内容。
当然,128 K的默认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这确实显示了使用19K磁盘空间的8K测试文件,但是存在必要的元数据开销。查看不可压缩的现有文件<=8K的大小,它们都显示了在原始recordsize=8K下磁盘使用情况的19K。我进一步尝试了recordsize=64K,它并没有改变这些样本文件的大小。
还请注意,在新的cp下创建文件的实例确实需要mv后面的D34。
这篇文章还很好地描述了正在发生的事情,我将为后人介绍:
https://klarasystems.com/articles/choosing-the-right-zfs-pool-layout/
https://unix.stackexchange.com/questions/743384
复制相似问题