Sno*_*all 11 performance zfs hard-drive zfsonlinux
我最近安装了一个新磁盘并在其上创建了一个 zpool:
/# zpool create morez /dev/sdb
Run Code Online (Sandbox Code Playgroud)
使用了一段时间后,我发现它很慢:
/morez# fio --name rw --rw rw --size 10G
read: IOPS=19.6k, BW=76.6MiB/s (80.3MB/s)(5120MiB/66834msec)
write: IOPS=19.6k, BW=76.6MiB/s (80.3MB/s)(5120MiB/66834msec)
Run Code Online (Sandbox Code Playgroud)
这个测试与我的实际用例非常相似。我正在从磁盘读取中等数量(~10k)的图像(每个~2 MiB)。当磁盘大部分为空时,它们是一次性写入的,所以我不希望它们被碎片化。
为了比较,我测试了 ext4:
/# gdisk /dev/sdb
...
/# mkfs.ext4 -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# fio --name rw --rw rw --size 10G
read: IOPS=48.3k, BW=189MiB/s (198MB/s)(5120MiB/27135msec)
write: IOPS=48.3k, BW=189MiB/s (198MB/s)(5120MiB/27135msec)
Run Code Online (Sandbox Code Playgroud)
和 btrfs:
/# mkfs.btrfs -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# fio --name rw --rw rw --size 10G
read: IOPS=51.3k, BW=201MiB/s (210MB/s)(5120MiB/25528msec)
write: IOPS=51.3k, BW=201MiB/s (210MB/s)(5120MiB/25528msec)
Run Code Online (Sandbox Code Playgroud)
什么可能导致 ZFS 出现性能问题,我该如何使其更快?
我还尝试明确设置 zpool 的扇区大小,因为我的磁盘(Seagate ST1000DM003)使用 4096 字节物理扇区:
/# zpool create -o ashift=12 morez /dev/sdb
Run Code Online (Sandbox Code Playgroud)
这并没有提高性能:
/morez# fio --name rw --rw rw --size 10G
read: IOPS=21.3k, BW=83.2MiB/s (87.2MB/s)(5120MiB/61573msec)
write: IOPS=21.3k, BW=83.2MiB/s (87.2MB/s)(5120MiB/61573msec)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,使用 zvol 有很好的性能:
/# zfs create -V 20G morez/vol
/# fio --name rw --filename /dev/zvol/morez/vol --rw rw --size 10G
read: IOPS=52.7k, BW=206MiB/s (216MB/s)(5120MiB/24852msec)
write: IOPS=52.7k, BW=206MiB/s (216MB/s)(5120MiB/24852msec)
Run Code Online (Sandbox Code Playgroud)
为什么这只影响 ZFS 文件系统而不影响 zvol?
在评论中,有人建议差异可能是由于缓存。经过进一步测试,我认为情况并非如此。我将 btrfs 测试的大小增加到远高于我计算机的内存量,其性能仍然明显高于 ZFS:
/# mkfs.btrfs -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# $ fio --name rw --rw rw --size 500G --runtime 3600 --time_based --ramp_time 900
read: IOPS=41.9k, BW=164MiB/s (172MB/s)(576GiB/3600003msec)
write: IOPS=41.9k, BW=164MiB/s (172MB/s)(576GiB/3600003msec)
Run Code Online (Sandbox Code Playgroud)
以下是运行 fio 之前 ZFS 属性的样子。这些只是使用默认设置创建 zpool 的结果。
# zpool get all morez
NAME PROPERTY VALUE SOURCE
morez size 928G -
morez capacity 0% -
morez altroot - default
morez health ONLINE -
morez guid [removed] default
morez version - default
morez bootfs - default
morez delegation on default
morez autoreplace off default
morez cachefile - default
morez failmode wait default
morez listsnapshots off default
morez autoexpand off default
morez dedupditto 0 default
morez dedupratio 1.00x -
morez free 928G -
morez allocated 276K -
morez readonly off -
morez ashift 0 default
morez comment - default
morez expandsize - -
morez freeing 0 default
morez fragmentation 0% -
morez leaked 0 default
morez feature@async_destroy enabled local
morez feature@empty_bpobj enabled local
morez feature@lz4_compress active local
morez feature@spacemap_histogram active local
morez feature@enabled_txg active local
morez feature@hole_birth active local
morez feature@extensible_dataset enabled local
morez feature@embedded_data active local
morez feature@bookmarks enabled local
morez feature@filesystem_limits enabled local
morez feature@large_blocks enabled local
# zfs get all morez
NAME PROPERTY VALUE SOURCE
morez type filesystem -
morez creation Thu Jun 29 19:34 2017 -
morez used 240K -
morez available 899G -
morez referenced 96K -
morez compressratio 1.00x -
morez mounted yes -
morez quota none default
morez reservation none default
morez recordsize 128K default
morez mountpoint /morez default
morez sharenfs off default
morez checksum on default
morez compression off default
morez atime on default
morez devices on default
morez exec on default
morez setuid on default
morez readonly off default
morez zoned off default
morez snapdir hidden default
morez aclinherit restricted default
morez canmount on default
morez xattr on default
morez copies 1 default
morez version 5 -
morez utf8only off -
morez normalization none -
morez casesensitivity sensitive -
morez vscan off default
morez nbmand off default
morez sharesmb off default
morez refquota none default
morez refreservation none default
morez primarycache all default
morez secondarycache all default
morez usedbysnapshots 0 -
morez usedbydataset 96K -
morez usedbychildren 144K -
morez usedbyrefreservation 0 -
morez logbias latency default
morez dedup off default
morez mlslabel none default
morez sync standard default
morez refcompressratio 1.00x -
morez written 96K -
morez logicalused 72.5K -
morez logicalreferenced 40K -
morez filesystem_limit none default
morez snapshot_limit none default
morez filesystem_count none default
morez snapshot_count none default
morez snapdev hidden default
morez acltype off default
morez context none default
morez fscontext none default
morez defcontext none default
morez rootcontext none default
morez relatime off default
morez redundant_metadata all default
morez overlay off default
Run Code Online (Sandbox Code Playgroud)
年纪大了,我觉得这个问题值得回答。
fio默认情况下,问题是 4KB 大小的 IOP;相反,ZFS 数据集默认使用 128KB 记录。这种不匹配意味着每次 4K 写入都会导致读取/修改/写入整个 128K 记录。
另一方面,ZVOL 默认使用 8K volblocksize。这意味着 4K 写入会导致 8K 记录的读取/修改/写入周期小得多,幸运的是,两个 4K 写入可以合并为一个 8K 写入(根本不需要读取/修改/写入)。
ZFS 数据集记录大小可以更改zfs set recordize=8K <dataset>,在这种情况下,它应该提供与 ZVOL 或多或少等效的性能。然而,当用于相对较大的传输时(OP 谈到 2 MB 的文件,作为图像,每次访问时都应该完全读取)最好有大的记录大小/卷块大小,有时甚至大于默认设置(128K)。
注意:由于 fio 作业缺少direct=1(http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-direct ),因此可能会缓存正在执行的某些 I/O(读取和写入)操作系统会扭曲你的结果(并人为地使数字变高)。这本身因以下原因而变得更加复杂:
O_DIRECT(因此打开失败),要么如果支持,那么它会通过悄悄回退到缓冲 I/O 来实现这一点(请参阅https://github.com/zfsonlinux/zfs/commit的第 3 点) /a584ef26053065f486d46a7335bea222cb03eeea)。O_DIRECT回退到缓冲 I/O。请注意,O_DIRECT仍然允许执行缓冲 I/O,因为在 Linux 上O_DIRECT更多的是提示(请参阅/sf/answers/3246434061/的参考部分)。
如果您处于无法正确绕过缓存的情况,那么在足够大的区域上执行足够的 I/O 以最大限度地减少缓存的影响至关重要(当然,除非您实际上想要测试缓存)...
| 归档时间: |
|
| 查看次数: |
5677 次 |
| 最近记录: |