为什么ZFS比ext4和btrfs慢得多?


11

问题

我最近安装了一个新磁盘,并在其上创建了一个zpool:

/# zpool create morez /dev/sdb

使用一段时间后,我注意到它非常慢:

/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)

该测试与我的实际用例非常相似。我正在从磁盘读取适量(〜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)

和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)

是什么可能导致ZFS的性能问题,如何使它更快?

尝试解决方案失败

我还尝试显式设置zpool的扇区大小,因为我的磁盘(Seagate ST1000DM003)使用4096字节的物理扇区:

/# zpool create -o ashift=12 morez /dev/sdb

这并没有提高性能:

/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)

观察

奇怪的是,使用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)

为什么这只影响ZFS文件系统而不影响zvols?

扩展对btrfs的测试

在评论中,建议差异可能是由于缓存。经过进一步测试,我认为情况并非如此。我将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)

系统信息

软件

  • Arch Linux,内核版本4.11.6
  • Linux 0.6.5.10上的ZFS
  • 菲奥2.21

硬件

ZFS信息

这是运行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

没有诸如使用的硬件,操作系统和版本,控制器,系统设置等详细信息。我不确定我们能告诉您什么!
ewwhite

2
什么是驱动器本身?它是现成的消费类SATA驱动器。要证明它实际上可以处理200+ MB /秒的持续速度,您还有很长的路要走。在现实条件下,大多数消费级SATA驱动器将很幸运地获得每秒70-80多个I / O操作,或每秒约100-120 MB以上的速度。而且,如果对这样的驱动器执行随机的小块I / O操作,则可能会得到30-40 KB /秒的数据。10 GB可能很容易在缓存中结束。
Andrew Henle

1
@ewwhite在/etc/modprobe.d/zfs.conf
Snowball中,

1
@ewwhite他们是。我在每次测试之间都擦除了分区表。在所有情况下,分区与磁盘开始的偏移量均为1 MiB。
雪球

1
注意自己/其他偶然发现此问题的人:ewwhite提到的调优设置记录在中man 5 zfs-module-parameters
雪球

Answers:


6

虽然年代久远,但我觉得这个问题值得回答。

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)大。


4

注意:由于缺少fio作业direct=1http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-direct),可能会缓存正在执行的某些I / O(读取写入)操作系统会扭曲您的结果(并使人为地增加数字)。由于以下原因,这本身就变得更加复杂:

请注意,O_DIRECT仍然允许仍然进行缓冲的I / O,因为在Linux O_DIRECT上更多是提示(请参阅/programming//a/46377629/2732969的参考部分)。

如果您无法正确地绕过缓存,那么在足够大的区域上进行足够的I / O以最大程度地减少缓存的影响至关重要(当然,除非您实际上要测试缓存)...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.