Чому 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

Ось як виглядали властивості 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видає за замовчуванням ВВП розміром 4 КБ; Натомість набори даних ZFS використовують, за замовчуванням, запит на 128 КБ. Ця невідповідність означає, що кожне записування 4K викликає зчитування / модифікацію / запис всього 128K запису.

З іншого боку, ZVOL за замовчуванням використовують 8K волонщики. Це означає, що 4K запис викликає набагато менший цикл читання / модифікування / запису 8K запису, і, за деякої долі, два записи 4K можна об'єднати в одне записування 8K (яке зовсім не вимагає читання / модифікації / запису).

zfs set recordize=8K <dataset>Зміна записів набору даних ZFS може бути змінена за допомогою, і в цьому випадку вона повинна дати більш-менш еквівалентну продуктивність, ніж 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.