Почему 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)

Этот тест довольно похож на мой реальный вариант использования. Я читаю умеренное количество (~ 10 КБ) изображений (~ 2 МиБ каждый) с диска. Они были записаны сразу, когда диск был в основном пуст, поэтому я не ожидаю, что они будут фрагментированы.

Для сравнения я проверил 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
  • ZFS в Linux 0.6.5.10
  • ФИО 2.21

аппаратные средства

ZFS info

Вот как выглядели свойства ZFS перед запуском fio. Это всего лишь результат создания 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+ МБ / с. Большинству накопителей SATA потребительского уровня в реальных условиях повезет, если их число операций ввода-вывода превышает 70-80 в секунду, или более 100-120 МБ / с. И если вы будете выполнять случайные операции ввода-вывода с небольшими блоками на таком диске, вы, вероятно, получите что-то вроде 30-40 КБ / с. 10 ГБ может слишком легко оказаться в кеше.
Эндрю Хенле

1
@ewwhite Нет настроек настройки в/etc/modprobe.d/zfs.conf
Snowball

1
@ewwhite Они есть. Я вытер таблицу разделов между каждым тестом. Во всех случаях раздел имел смещение в 1 МБ от начала диска.
Снежок

1
Примечание для себя / любого, кто сталкивается с этим вопросом: настройки, о которых упоминает ewwhite, задокументированы man 5 zfs-module-parameters.
Снежок

Ответы:


6

В старости я чувствую, что этот вопрос заслуживает ответа.

fioпо умолчанию выдает IOP размером 4 КБ; Вместо этого наборы данных ZFS по умолчанию используют 128 КБ записи. Это несоответствие означает, что каждая запись 4K вызывает чтение / изменение / запись всей записи 128K.

ZVOL, с другой стороны, по умолчанию используют 8K volblocksize. Это означает, что запись 4K вызывает намного меньший цикл чтения / изменения / записи записи 8K, и, если повезет, две записи 4K можно объединить в одну запись 8K (которая вообще не требует чтения / изменения / записи).

Размер записи набора данных ZFS можно изменить, zfs set recordize=8K <dataset>и в этом случае он должен давать более или менее эквивалентную производительность, чем ZVOL. Однако, когда используется для относительно больших передач (OP говорил о 2 МБ файлах, которые, будучи изображениями, должны быть полностью прочитаны каждый раз, когда к ним обращаются), лучше иметь большой размер записи / объемный размер, иногда даже больше, чем значение по умолчанию (128 КБ).


4

Примечание: по мере отсутствия задания fio direct=1( http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-direct ) некоторое количество выполняемых операций ввода-вывода (как чтение, так и запись) может быть кэшировано операционной системой, искажая ваши результаты (и делая цифры искусственно завышенными). Само это еще более осложняется следующим:

  • ZFS в Linux либо не поддерживает O_DIRECT(так что открытие завершается неудачно), либо, если это так, то делает это путем тихого возврата к буферизованному вводу / выводу (см. Пункт 3 https://github.com/zfsonlinux/zfs/commit / a584ef26053065f486d46a7335bea222cb03eeea ).
  • В некоторых случаях BTRFS и ext4 O_DIRECTвозвращаются к буферизованному вводу / выводу .

Имейте в виду, O_DIRECTчто буферизованный ввод-вывод по-прежнему разрешен, поскольку в Linux O_DIRECTэто подсказка (см. Раздел ссылок на /programming//a/46377629/2732969 ).

Если вы не можете правильно обойти кэширование, крайне важно, чтобы вы выполняли достаточно операций ввода-вывода на достаточно большой области, чтобы минимизировать влияние кэширования (если, конечно, вы действительно не хотите тестировать кэширование) ...

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.