ZFS secondarycache: коли L2ARC не повинен кешувати нічого

Було корисно?

L2ARC має репутацію: «Додай SSD — і ваш пул ZFS стане швидким.» Іноді це правда. Іноді це еквівалент того, як поставити спойлер на вантажний фургон.
Похмура правда в тому, що найкраща конфігурація L2ARC для багатьох реальних систем — це… нічого не кешувати взагалі.

Ця стаття про secondarycache — властивість набору даних, яка вирішує, чи блоки можуть потрапити в L2ARC — і про операційну реальність навколо неї.
Ми поговоримо, чому L2ARC може бути нейтральним, чому він може бути активною шкодою, і як довести (не гадати), що відбувається на ваших серверах.

Що secondarycache насправді робить

У ZFS є два основні поняття кешу, які люди плутають:

  • ARC (Adaptive Replacement Cache): живе в ОЗП, автоматично кешує часто та нещодавно використовувані дані (й метадані).
  • L2ARC: розширення ARC, яке зберігає допустимі для кешу блоки на швидкому пристрої (зазвичай SSD/NVMe).

Властивість, яка визначає, чи блоки набору даних можуть потрапити в L2ARC, — це secondarycache. Це налаштування на рівні набору даних, яке успадковується, і яке контролює, що ZFS має право записувати в L2ARC.

Значення, які ви справді використовуватимете

  • secondarycache=all: і дані, і метадані можуть потрапляти в L2ARC.
  • secondarycache=metadata: лише метадані є допустимими (часто несподівано ефективно для певних робочих навантажень).
  • secondarycache=none: нічого з цього набору даних не допущено до L2ARC.

Висновок: встановлення secondarycache=none не означає «вимкнути кеш». ARC все одно кешуватиме в RAM.
Ви лише кажете ZFS: «Не витрачай пропускну здатність L2ARC і облік на цей набір даних».

Якщо ви коли-небудь бачили, як система падає через «ми додали кеш», ви розумієте, наскільки це важливо.
L2ARC не безкоштовний; він коштує CPU, пам’яті для метаданих і пропускної здатності запису для заповнення.

Жарт №1: L2ARC схожий на абонемент у спортзал — мати його не робить вас швидшим, а правильно ним користуватися може.

Цікаві факти та трохи історії

Кілька конкретних фактів, які пояснюють, чому L2ARC поводиться так, як поводиться сьогодні:

  1. L2ARC з’явився рано і еволюціонував повільно. Дизайн виник за епохи Solaris, коли SSD були меншими, повільнішими і значно дорожчими, ніж сьогодні.
  2. L2ARC — кеш для читання, який наповнюється записами. Він заповнюється копіюванням буферів, які вигнали з ARC, на пристрій L2ARC — тобто споживає записні I/O навіть якщо навантаження в основному читальне.
  3. Історично вміст L2ARC зникав після перезавантаження. Довгий час L2ARC завжди починався «холодним» після рестарту; час прогріву міг займати години. Постійний L2ARC з’явився пізніше в деяких реалізаціях, але операційно вам все одно треба планувати холодну поведінку кешу.
  4. L2ARC потребує ОЗП для індексації того, що на диску. Пристрій кешу марний без заголовків в пам’яті, які кажуть, що де збережено; великий L2ARC може тихо з’їдати значну кількість пам’яті.
  5. Предфетч ZFS може саботувати наївне кешування. Послідовні читання можуть підвантажувати дані, які виглядають як «варто кешувати», але ніколи не будуть повторно використані; L2ARC може стати музеєм однократно переглянутих блоків.
  6. ARC зазвичай — найкращий кеш, який ви можете купити. Затримка й пропускна здатність RAM досі домінують, і ARC розумніший, ніж багато хто думає — особливо для навантажень, багатих на метадані.
  7. L2ARC не є кешем для записів. Люди постійно намагаються використовувати його таким чином. Для цього потрібен SLOG (separate log), і навіть він допомагає тільки для синхронних записів.
  8. Стискання змінює арифметику. Кешування стиснених блоків означає більше логічних даних на байт, але також інші компроміси по CPU; іноді стискання робить ARC настільки ефективним, що L2ARC стає маргінальним.
  9. Кешування метаданих може принести реальну вигоду. Файлові сервери та сховища VM часто більше виграють від кешування непрямих блоків, dnode та директорій, ніж від кешування вмісту файлів.

L2ARC простими словами (і чому це складно)

ARC знаходиться в ОЗП і тримає те, що вважає потрібним вам наступним. Коли ARC закінчує місце, він виганяє буфери.
Деякі з цих вигнаних буферів можуть бути записані в L2ARC. Пізніше, якщо той самий блок запитується знову і його немає в ARC,
ZFS може отримати його з L2ARC замість звернення до дисків пулу.

Це звучить просто, поки ви не запустите продукційне навантаження, тому що в реченні «пізніше» приховано багато деталей.
L2ARC допомагає тільки коли:

  • навантаження передбачає повторні читання одних і тих же блоків,
  • ARC занадто малий, щоб утримувати їх «гарячими»,
  • пристрій L2ARC достатньо швидкий, щоб бути швидшим за пул,
  • і наповнення L2ARC не забирає ресурси, потрібні для інших завдань.

Дві невидимі витрати: трафік заповнення та метадані

Перша витрата — це трафік заповнення. L2ARC наповнюється записами. Ці записи конкурують з нормальною роботою пулу:
цикли CPU, пропускну здатність пам’яті і іноді той самий планувальник I/O та бюджет переривань.

Друга витрата — це накладні витрати на метадані. ZFS має пам’ятати, що знаходиться в L2ARC. Цей індекс живе в оперативній пам’яті.
Якщо у вас і так мало пам’яті (саме тому ви хотіли L2ARC), додавання великого L2ARC може бути як купити більший холодильник і потім скаржитися, що кухня стала меншою.

Чому «кешувати все» рідко найкраща політика

Більшість продакшен-наборів даних містять мішанину патернів доступу:

  • Стрімінгові/послідовні читання (резервні копії, медіа, ETL): жахливі для L2ARC.
  • Випадкові повторні читання (бази даних, образи VM, навантаження з маленькими файлами): потенційно корисні для L2ARC.
  • Метадані з високою змінністю (build-сервери, CI): іноді краще обслуговуються метаданими або просто більшою кількістю ОЗП.

Властивість secondarycache дозволяє бути вибірковим.
Кращі оператори, яких я знаю, не «включають L2ARC»; вони вирішують, які набори даних можуть його використовувати, а які ввічливо просять триматися подалі.

Коли правильним вибором є кешування нічого

«L2ARC має нічого не кешувати» не означає «L2ARC марний». Це означає: для конкретного набору даних (або всього пулу) витрати кешування перевищують вигоду.
Ось сценарії, коли secondarycache=none не лише розумний, але часто найчистіше рішення.

1) Навантаження здебільшого послідовне або одноразове

Думайте: цілі резервні копії, архіви логів, відеофайли, завантаження в data lake, нічні експорти. ZFS prefetch читає наперед, ARC бачить потік даних, і L2ARC
старанно починає записувати вигнані буфери. Але нічого не перечитується. Ви побудували кеш для навантаження, яке не повторюється.

Симптоми:

  • Записний I/O на L2ARC високий; коефіцієнт попадань L2ARC залишається низьким.
  • Диски пулу показують додаткову активність, навіть якщо «SSD кеш» зайнятий.
  • Під час важких сканувань затримка погіршується, бо система виконує додаткову роботу.

2) У вас дефіцит пам’яті і L2ARC «з’їдає» останню хорошу RAM

ARC потребує ОЗП. ОС потребує ОЗП. Додатки потребують ОЗП. L2ARC також потребує ОЗП (для заголовків і обліку).
Якщо ви вже близькі до свапінгу або бачите, що ARC постійно зменшується під тиском, додавання L2ARC може зробити продуктивність більш нестабільною.

Тут secondarycache=none — скальпель: ви можете зберегти L2ARC для наборів даних, які справді виграють, одночасно запобігаючи «трішенню кешу»
від масивних/стрімінгових наборів даних.

3) Пристрій кешу швидкий, але недостатньо або нестабільний

Не всі SSD однакові. Деякі виглядають добре в специфікаціях продавця, але розвалюються при тривалих записах, змішаних навантаженнях або великому QD.
L2ARC створює тривалі записи. Якщо поведінка запису пристрою «потворна», наповнення L2ARC може викликати стрибки затримок.

Якщо ваш пул уже розміщений на NVMe, «кеш NVMe» може бути фактично не швидшим за пул.
У такому випадку ви платите за накладні витрати L2ARC, щоб замінити одне швидке читання іншим. Це не злочин, але марнотратство.

4) Ваш реальний вузький горлишко не в читанні

Я бачив команди, які ганялися за попаданнями L2ARC, тоді як реальна проблема була в:

  • затримці синхронного запису (потребує налаштування SLOG, вирівнювання recordsize або змін у додатку),
  • завантаженні CPU від стиснення/контрольних сум,
  • затримці мережі,
  • фрагментації і маленьких розмірах записів,
  • або просто «надто багато клієнтів».

У цих випадках L2ARC — побічна задача. Встановлення secondarycache=none на неважливих наборах даних запобігає витратам L2ARC
поки ви усуваєте реальну проблему.

5) Ви кешуєте дані, які краще зробити «спеціальними»

L2ARC — це кеш для читання. Спеціальний vdev інший: він може постійно зберігати метадані (і опціонально малі блоки) на швидкому носії.
Якщо ваша біль — затримка метаданих (перегляди директорій, малі випадкові читання, метадані VM), «правильним» прискоренням може бути special vdev — а не L2ARC.

Це не означає «завжди розгортайте special vdev». Це означає: якщо ви використовуєте L2ARC, щоб заглушити проблему з метаданими, ви можете платити постійні витрати
за користь, яку можна зробити структурною.

6) У вас немає стабільного вікна повторного використання

L2ARC блищить, коли робочий набір більший за RAM, але все ще має локальність — тобто блоки перечитуються протягом хвилин/годин.
Деякі навантаження мають робочий набір більший за RAM і немають корисного повторного використання. Ви не можете «викешувати» ентропію.

Жарт №2: Якщо ваше навантаження — це чистий стрімінг, L2ARC — по суті дуже дорогий сувенірний магазин: багато товару, ніхто не повертається.

Швидкий план діагностики (перший, другий, третій)

Коли продуктивність погана і L2ARC у справі, вам потрібна швидка, відтворювана процедура триажу. Ось що я перевіряю по порядку, коли хтось пише «дискова підсистема повільна»
і в системі гордо встановлено пристрій L2ARC.

Перший: це проблема читання, запису чи затримки?

  • Подивіться на затримки пулу і операції: повільні читання, повільні записи чи і те, й інше?
  • Перевірте, чи додаток чекає на I/O або на CPU.
  • Підтвердіть, чи погіршення корелює з послідовними скануваннями, резервними копіями, реплікацією або scrub.

Другий: чи ARC уже виконує роботу?

  • Якщо коефіцієнт попадань ARC високий і стабільний, L2ARC часто не допоможе.
  • Якщо ARC зазнає тиску пам’яті, виправте це перед «додаванням кешу».

Третій: чи L2ARC реально обслуговує читання (попадання), чи просто записується в нього?

  • Перевірте коефіцієнт попадань L2ARC, швидкість підживлення і співвідношення читань до записів L2ARC.
  • Якщо L2ARC зайнятий записами, але не дає попадань, обмежте його через secondarycache.

Четвертий: чи показує пристрій кешу погану поведінку?

  • Спостерігайте за затримкою пристрою під час заповнення.
  • Шукайте тривалий високий коефіцієнт завантаження, черги або періодичні затримки.
  • Перевірте, що він не ділиться лініями/контролерами з іншими гарячими пристроями.

П’ятий: звужуйте зону ураження

  • Встановіть secondarycache=none на очевидні стрімінгові набори даних першими.
  • Залиште кешування метаданих для наборів, де це допомагає.
  • Виміряйте знову. Не «відчувайте» це інтуїтивно.

Практичні завдання: команди + інтерпретація

Мета тут не «запустити ці команди один раз». Мета — виробити звичку: спостерігати, змінити одну річ, знову спостерігати.
Нижче — практичні завдання, які ви можете виконати на реальному хості ZFS. Вивід залежить від платформи, але намір і інтерпретація стабільні.

Завдання 1: Підтвердити, які набори даних допустимі для L2ARC

cr0x@server:~$ zfs get -r -o name,property,value,source secondarycache tank
NAME                 PROPERTY        VALUE     SOURCE
tank                 secondarycache  all       default
tank/backups         secondarycache  all       inherited from tank
tank/vmstore         secondarycache  all       inherited from tank
tank/logarchive      secondarycache  all       inherited from tank

Інтерпретація: якщо ви бачите стрімінгові набори даних на кшталт tank/logarchive, що успадковують all, це червоний прапор.
Ви дозволяєте L2ARC інгестувати найменш придатні для кешу дані в системі.

Завдання 2: Встановити стрімінгові набори даних так, щоб вони нічого не кешували

cr0x@server:~$ sudo zfs set secondarycache=none tank/logarchive
cr0x@server:~$ sudo zfs set secondarycache=none tank/backups

Інтерпретація: це не очищує ARC; це просто зупиняє допуск нових блоків із цих наборів даних до L2ARC у майбутньому.
Ви зменшили майбутній треш L2ARC.

Завдання 3: Спробувати кешування тільки метаданих для «багато імен файлів, мало повторного читання»

cr0x@server:~$ sudo zfs set secondarycache=metadata tank/home
cr0x@server:~$ zfs get secondarycache tank/home
NAME       PROPERTY        VALUE     SOURCE
tank/home  secondarycache  metadata  local

Інтерпретація: кешування тільки метаданих — це прагматична золота середина. Для файлових серверів це може покращити обходи директорій і операції stat
без заповнення L2ARC вмістом файлів, який не буде перечитано.

Завдання 4: Перевірити, чи ви взагалі маєте пристрій L2ARC підключений

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
config:

        NAME                         STATE     READ WRITE CKSUM
        tank                         ONLINE       0     0     0
          raidz2-0                   ONLINE       0     0     0
            sda                      ONLINE       0     0     0
            sdb                      ONLINE       0     0     0
            sdc                      ONLINE       0     0     0
            sdd                      ONLINE       0     0     0
        cache
          nvme0n1p1                  ONLINE       0     0     0

errors: No known data errors

Інтерпретація: пристрої L2ARC з’являються під cache. Якщо немає cache vdev, secondarycache все ще має значення лише в контексті майбутньої політики.

Завдання 5: Перевірити, чи пул обмежений IOPS або пропускною здатністю

cr0x@server:~$ zpool iostat -v tank 1 5
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        6.12T  5.88T    410    120  52.1M  14.2M
  raidz2-0                  6.12T  5.88T    410    120  52.1M  14.2M
    sda                         -      -     80     25  10.6M  3.1M
    sdb                         -      -     85     24  10.5M  3.0M
    sdc                         -      -     78     22  10.2M  2.8M
    sdd                         -      -     82     25  10.8M  3.2M
--------------------------  -----  -----  -----  -----  -----  -----

Інтерпретація: якщо ви бачите велику пропускну здатність з низькими IOPS, це пахне послідовним стрімінгом. Саме там L2ARC часто нічого не робить корисного.
Якщо IOPS високі і читання випадкові, L2ARC може допомогти — якщо існує повторне використання.

Завдання 6: Спостерігати системні затримки I/O і виявити реальний біль

cr0x@server:~$ iostat -x 1 5
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.30    0.00    4.10    8.90    0.00   74.70

Device            r/s   w/s   rkB/s   wkB/s  await  r_await  w_await  %util
sda              95.0  28.0  11520.0  3200.0  18.2    16.9     22.1   96.0
nvme0n1           5.0  900.0    80.0 51200.0   2.1     1.2      2.2   82.0

Інтерпретація: дивіться на await і %util. Тут NVMe робить багато записів (ймовірно підживлення L2ARC),
тоді як HDD майже насичені. Якщо L2ARC не дає попадань, ці записи — просто зайва робота.

Завдання 7: Перевірити лічильники ARC і L2ARC (поширено на Linux з OpenZFS)

cr0x@server:~$ kstat -p zfs:0:arcstats:hits zfs:0:arcstats:misses zfs:0:arcstats:l2_hits zfs:0:arcstats:l2_misses
zfs:0:arcstats:hits                             389002134
zfs:0:arcstats:misses                            54200121
zfs:0:arcstats:l2_hits                             120934
zfs:0:arcstats:l2_misses                          3812490

Інтерпретація: попадання ARC значно переважають промахи (добре), а попадання L2ARC дуже малі в порівнянні з промахами L2 (погано).
У такій формі L2ARC не дає цінності. Слід розглянути обмеження secondarycache і/або видалення L2ARC, якщо він створює накладні витрати.

Завдання 8: Обчислити швидкі та грубі співвідношення попадань

cr0x@server:~$ python3 - <<'PY'
hits=389002134
misses=54200121
l2hits=120934
l2misses=3812490
print("ARC hit ratio:", hits/(hits+misses))
print("L2ARC hit ratio:", l2hits/(l2hits+l2misses))
PY
ARC hit ratio: 0.8777331151094286
L2ARC hit ratio: 0.03076857030623538

Інтерпретація: ~3% коефіцієнт попадань L2ARC — сильний натяк, що пристрій в основному служить як sink для записаних буферів.
Є винятки, але на практиці це зазвичай означає «перестаньте годувати його сміттям».

Завдання 9: Спостерігати швидкість підживлення L2ARC і його розмір (залежить від платформи, але корисно)

cr0x@server:~$ kstat -p zfs:0:arcstats:l2_size zfs:0:arcstats:l2_asize zfs:0:arcstats:l2_write_bytes zfs:0:arcstats:l2_read_bytes
zfs:0:arcstats:l2_size                           81234165760
zfs:0:arcstats:l2_asize                          79877812224
zfs:0:arcstats:l2_write_bytes                   918230012928
zfs:0:arcstats:l2_read_bytes                      9112346624

Інтерпретація: майже терабайт записано, і лише ~9 ГБ прочитано назад. Це не «кеш», це бігова доріжка.
Це також означає зношування пристрою кешу за дуже малий віддачу.

Завдання 10: Виявити набори даних, які спричиняють великі читання (щоб вирішити, кому давати L2ARC)

cr0x@server:~$ sudo zpool iostat -r -v tank 1 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        6.12T  5.88T    900    140  95.0M  16.0M
  raidz2-0                  6.12T  5.88T    900    140  95.0M  16.0M
--------------------------  -----  -----  -----  -----  -----  -----

Інтерпретація: залежно від збірки OpenZFS, ви можете не отримати тут iostat на рівні набору даних.
Якщо у вас є інструменти з iostat на рівні набору даних, використовуйте їх; інакше корелюйте з логами додатків і патернами доступу.
Операційний сенс: обирайте переможців і програшних для secondarycache, замість включати все.

Завдання 11: Перевірити recordsize і подивитися, чи кешуєте ви гігантські блоки, які ніколи не перечитуються

cr0x@server:~$ zfs get -o name,property,value recordsize tank/backups tank/vmstore
NAME         PROPERTY    VALUE   SOURCE
tank/backups recordsize  1M      local
tank/vmstore recordsize  128K    local

Інтерпретація: набір резервних копій з recordsize=1M часто є великим, послідовним і не перечитується.
Кешування 1 MB блоків в L2ARC рідко вигідне. Це первинний кандидат для secondarycache=none.

Завдання 12: Безпечно внести зміну, потім валідувати знімками лічильників «до/після»

cr0x@server:~$ kstat -p zfs:0:arcstats:l2_hits zfs:0:arcstats:l2_misses zfs:0:arcstats:l2_write_bytes > /tmp/l2arc.before
cr0x@server:~$ sudo zfs set secondarycache=none tank/backups tank/logarchive
cr0x@server:~$ sleep 300
cr0x@server:~$ kstat -p zfs:0:arcstats:l2_hits zfs:0:arcstats:l2_misses zfs:0:arcstats:l2_write_bytes > /tmp/l2arc.after
cr0x@server:~$ diff -u /tmp/l2arc.before /tmp/l2arc.after
--- /tmp/l2arc.before
+++ /tmp/l2arc.after
@@
-zfs:0:arcstats:l2_write_bytes                   918230012928
+zfs:0:arcstats:l2_write_bytes                   918380112896

Інтерпретація: після п’яти хвилин байти запису L2ARC ледве змінилися. Це те, чого ви хочете, якщо ці набори даних були основою підживлення.
Тепер підтвердіть, що затримка додатків покращилася і I/O пулу зменшився. Метрики виграють диспути.

Завдання 13: Перевірити тиск пам’яті, який може зробити L2ARC контрпродуктивним

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           128Gi        92Gi       4.1Gi       1.2Gi        32Gi        28Gi
Swap:           16Gi       3.4Gi        13Gi

Інтерпретація: використання свапу на сервері ZFS не завжди є зло, але тривалий свапінг під час пікових I/O — це податок на продуктивність.
Якщо ви бачите свапінг разом із накладними витратами L2ARC, зменшення допуску L2ARC (через secondarycache) часто дає швидкий виграш.

Завдання 14: Якщо підозрюєте, що пристрій кешу працює з проблемами, подивіться лічильники помилок

cr0x@server:~$ sudo smartctl -a /dev/nvme0n1 | sed -n '1,120p'
smartctl 7.4 2023-08-01 r5530 [x86_64-linux-6.8.0] (local build)
=== START OF INFORMATION SECTION ===
Model Number:                       ExampleNVMe 1TB
Serial Number:                      XYZ123
Firmware Version:                   1.02
...
Percentage Used:                    23%
Data Units Written:                 912,345,678
Media and Data Integrity Errors:    0
Error Information Log Entries:      0

Інтерпретація: якщо «Data Units Written» злітає вгору в системі, де L2ARC не дає попадань, ви спалюєте витривалість заради спорту.
Це ще одна причина встановити secondarycache=none для невідповідних наборів даних.

Три короткі історії з корпоративного світу

Міні-історія №1: Інцидент через хибне припущення

Середня компанія керувала кластером NFS на базі ZFS для домашніх каталогів розробників і артефактів збірки.
У них був напружений сезон — новий продукт, багато CI, багато «просто запустити ще раз» — і команда зберігання отримала класичну скаргу:
збірки зависали на I/O, особливо вдень.

Хтось запропонував очевидне рішення: «Додайте L2ARC». У них були запасні enterprise SSD, було вікно обслуговування, і зміна була простою.
Після цього дашборди виглядали «краще» в тому сенсі, як дашборди виглядають, коли всі хочуть бачити покращення: пристрій кешу показував активність, і це здавалося успіхом.

Через два дні справжній інцидент: клієнти почали повідомляти про періодичні зависання. Не постійні повільності — зависання.
Ноди зберігання не падали, але графіки затримок виглядали як кардіограма.
Запити до служби техпідтримки майже були поетичні: «Іноді все нормально, інколи зависає на 20 секунд».

Корінь проблеми — хибне припущення: вони вважали, що навантаження — «випадкові перечитування». Насправді домінувальний трафік — це завантаження артефактів CI і великі послідовні
читання результатів збірки, які рідко перечитовувалися на тому самому вузлі. ZFS prefetch зробив свою роботу, ARC заповнився і вигнав буфери, і підживлення L2ARC почалося.
Пристрій кешу не обслуговував читання; він був зайнятий інгестом вигнаних буферів. Водночас система платила за облік і планування I/O.

Виправлення було соромливо простим: встановити secondarycache=none для наборів даних артефактів збірки, і secondarycache=metadata для домашніх каталогів.
L2ARC перестав діяти як підсилювач трешу, затримки стабілізувалися, і «рандомні зависання» зникли.
Урок запам’ятався: якщо ви не можете описати вікно повторного використання, ви не налаштовуєте кеш — ви граєте в азарт.

Міні-історія №2: Оптимізація, що обернулася проти

Інший магазин обслуговував віртуалізоване середовище, де пул ZFS обслуговував диски VM через iSCSI.
У них були пристойні NVMe для L2ARC, скромна ОЗП і багато VM. Хтось дізнався, що «L2ARC чудовий для навантажень VM», що часто правда.
Вони встановили secondarycache=all на корінь пулу, тож кожен набір даних успадковував це.

Спочатку продуктивність покращилася в вузькому тесті: шторми завантаження були швидші. Ось у чому пастка.
В продакшені середовище включало нічні повні резервні копії VM, які читали кожен блок кожної VM. Ці резервні копії були послідовними і величезними.
Як тільки резервне копіювання стартувало, швидкість підживлення L2ARC підскочила, пристрій кешу писав постійно, і затримки для звичайного I/O VM зросли.

Зворотний ефект мав конкретний відтінок: графіки зберігання показували, що пристрій кешу «допомагає» (зайнятий!), але VM стали повільніші.
Інженери намагалися «виправити» це, додавши другий пристрій кешу і збільшуючи розмір кешу, що лише погіршило трафік підживлення і споживання RAM для індексації.
Врешті кеш перетворився не в кеш, а в фонову задачу з дуже дорогою пам’яттю SSD.

Переломний момент прийшов від нудного вимірювання: вони порівняли L2ARC read bytes і write bytes під час вікна резервного копіювання.
Записи переважали читання. Пристрій кешу поглинав дані, які не були перечитані до моменту вигнання.
Вони змінили політику: набори резервних копій — secondarycache=none, диски VM — all.

Після цього шторм завантаження залишився покращеним, резервні копії перестали карати всіх інших, а витривалість L2ARC перестала стрімко падати.
Мораль: «L2ARC для VM» не неправильна; «L2ARC для всього в одному пулі» часто є.

Міні-історія №3: Нудна, але правильна практика, що врятувала день

Команда фінансових послуг (така, що боїться непередбачуваної затримки більше, ніж повільної затримки) керувала ZFS-апаратом для аналітики.
Їх основне навантаження — база даних з відомим робочим набором, плюс іноді великі експорти та операції реіндексації.
У них було правило: ніяких змін кешування без зняття показників «до/після» і плану відкату.

Коли команда БД попросила «більше кешу», інженери зберігання не сперечалися. Вони запитали: «Який набір даних, який патерн доступу і яке вікно повторного використання?»
Набору даних БД дали secondarycache=all. Експортам — secondarycache=none. Спільній staging-площі — metadata.
Це не героїзм; це відмова вважати все I/O морально рівним.

Через місяці патч платформи вимагав перезавантаження. Після перезавантаження з’явилися скарги на продуктивність — очікувано — через холодні кеші.
Але інцидент не переріс у пожежу. У них були базові лічильники і очікування часу прогріву.
Більше того, оскільки експорт ніколи не підживлював L2ARC, кеш розігрівся на реальному робочому наборі БД, а не потонув у трафіку експорту.

Вони здавалися везучими. Насправді вони спеціально були нудними.
Практика, що врятувала день, — політика: явні рішення secondarycache на рівні набору даних, валідація лічильниками, перегляд раз на квартал.
«Ніяких сюрпризів» — це функція, яку можна спроектувати.

Типові помилки: симптоми та виправлення

Помилка 1: Увімкнути L2ARC глобально і забути про резервні копії

Симптоми: пристрій L2ARC показує постійні записи під час вікон резервного копіювання; затримка пулу зростає; коефіцієнт попадань L2ARC залишається низьким.

Виправлення: Встановіть secondarycache=none для наборів резервних копій/реплікацій/експортів. Розгляньте metadata для каталогів і каталогів файлів.

Помилка 2: Інтерпретувати «L2ARC зайнятий» як «L2ARC працює»

Симптоми: висока пропускна здатність запису на пристрій кешу; мала пропускна здатність читання; відсутнє значуще покращення затримки додатків.

Виправлення: Порівняйте l2_write_bytes і l2_read_bytes. Якщо читання не відповідають записам, обмежте допуск через secondarycache.

Помилка 3: Використовувати L2ARC як компенсацію за недостатню RAM без вимірювання тиску пам’яті

Симптоми: свапінг, активність kswapd, рвані затримки, ARC постійно зменшується; L2ARC все ще не дає попадань.

Виправлення: Зменште слід L2ARC (або видаліть) і пріоритетизуйте RAM. Якщо ви вимушені тримати L2ARC, використовуйте secondarycache=metadata для багатьох наборів даних.

Помилка 4: Очікувати, що L2ARC виправить затримку синхронних записів

Симптоми: висока затримка комітів, повільний fsync бази даних, повільні синхронні записи NFS, але метрики читань нормальні.

Виправлення: Дивіться на SLOG, поведінку sync і налаштування write path. L2ARC не є кешем для записів; зміни secondarycache тут не допоможуть.

Помилка 5: Кешувати «надто великі» блоки і руйнувати ефективність кешу

Симптоми: L2ARC швидко заповнюється; коефіцієнт попадань залишається низьким; навантаження змішане, але домінують великі читання записів.

Виправлення: Встановіть secondarycache=none для наборів з великими стрімінговими записами (часто резервні копії), або розділіть дані по наборах.

Помилка 6: Ставитися до L2ARC як до обов’язкового після встановлення

Симптоми: постійні регресії продуктивності; команди опираються вимкненню, бо «ми заплатили за SSD».

Виправлення: Працюйте за результатами, а не за втраченими витратами. Вимкніть допуск для невідповідних наборів даних; якщо треба, видаліть cache vdev і перемістіть SSD куди інше.

Контрольні списки / покроковий план

Покроково: як вирішити, чи набір даних має нічого не кешувати

  1. Визначте патерн доступу набору даних. Якщо це послідовні сканування, припускайте secondarycache=none, поки не доведете протилежне.
  2. Зніміть базові лічильники. Запишіть pool iostat, попадання/промахи ARC, байти читання/запису L2ARC.
  3. Змінюйте лише один набір даних спочатку. Почніть з найочевиднішого стрімінгового набору (резервні копії/архіви логів).
  4. Застосуйте secondarycache=none. Не крутіть відразу п’ять регулювань.
  5. Чекайте репрезентативного вікна. Принаймні один цикл навантаження (наприклад, повне резервне копіювання або пікова година).
  6. Порівняйте метрики після. Байти запису L2ARC повинні впасти; затримка пулу має покращитися або залишитися стабільною.
  7. Ітеруйте. Рухайте межу політики. Залишайте all для підтверджених виграшних наборів даних, використовуйте metadata для змішаних файлових навантажень і none для стрімінгових.

Операційний чекліст: «Ми маємо L2ARC, але він не допомагає»

  1. Підтвердьте, що ви не обмежені CPU або мережею.
  2. Перевірте коефіцієнт попадань ARC і тиск пам’яті. Виправте дефіцит RAM передусім.
  3. Виміряйте попадання/промахи L2ARC і байти читання/запису.
  4. Якщо L2ARC важко пише і має низькі попадання, припиніть його підживлення через secondarycache=none для стрімінгових наборів даних.
  5. Якщо L2ARC має багато попадань, але все ще повільний — перевірте затримку і стан пристрою кешу.
  6. Якщо покращення все ще незначні, розгляньте, що ваш пул уже досить швидкий або у робочого набору немає повторного використання.

Питання та відповіді

1) Чи secondarycache=none вимикає ARC?

Ні. ARC працює як і раніше в RAM. secondarycache контролює лише допуск до L2ARC (пристрій вторинного кешу).

2) Якщо L2ARC — кеш для читання, чому він так багато записує?

Тому що його треба наповнювати. ZFS заповнює L2ARC записом вигнаних з ARC буферів на пристрій кешу. Якщо ваше навантаження проходить через багато унікальних даних,
L2ARC буде постійно писати, даючи небагато попадань.

3) Чи варто ставити secondarycache=metadata скрізь?

Не скрізь, але це сильний дефолт для змішаних файлових навантажень, де повторне використання метаданих високе, а повторне використання даних сумнівне.
Це також безпечніший вибір, коли ви підозрюєте «забруднення кешу» від великих стрімінгових читань.

4) У чому різниця між primarycache та secondarycache?

primarycache керує тим, що може потрапити в ARC (RAM). secondarycache керує тим, що може потрапити в L2ARC (пристрій кешу).
Більшість систем мають бути дуже обережними при зміні primarycache; використовуйте secondarycache для політики L2ARC.

5) Якщо L2ARC не зберігається після перезавантаження, чи це марно?

Не марно, але потрібно враховувати час прогріву. Якщо ваша система часто перезавантажується або ваші SLO не терплять періодів холодного кешу,
L2ARC може бути не тим інструментом — або ви маєте гарантувати, що лише високоповторні набори даних його підживлюють, щоб він швидко прогрівався.

6) Чи L2ARC може погіршити продуктивність навіть якщо він дає деякі попадання?

Так. Якщо витрати на заповнення і облік створюють конкуренцію за CPU, тиск пам’яті або стрибки затримок пристрою, загальна швидкість може впасти.
Лікування — селективний допуск: встановіть secondarycache=none там, де коефіцієнт попадань і повторне використання не виправдовують витрати.

7) Як зрозуміти, чи має ваше навантаження достатньо повторного використання для L2ARC?

Вимірюйте. Практичний проксі: байти читання L2ARC мають бути значною частиною байтів запису L2ARC за репрезентативне вікно,
і затримка додатків має покращитися. Якщо ви в основному пишете в L2ARC і рідко читаєте з нього, вікна повторного використання нема.

8) Чи додавання більшої ємності L2ARC — хороший вихід при низькому коефіцієнті попадань?

Іноді, але це зазвичай не перший правильний крок. Низький коефіцієнт попадань частіше є проблемою політики (кешуються невідповідні набори даних), ніж проблемою розміру.
Збільшуйте ємність лише після виключення стрімінгових наборів даних через secondarycache=none і підтвердження реального повторного використання.

9) Чи варто видаляти пристрій L2ARC зовсім, якщо я встановив багато наборів даних на none?

Якщо у вас залишився невеликий набір даних, що виграють, зберігати L2ARC все ще може мати сенс.
Але якщо виміри показують мінімальні попадання і значні накладні витрати, його видалення — цілком обґрунтований інженерний крок. SSD можуть бути корисніші в іншому місці.

Висновок

L2ARC — не магія; це компроміс. Властивість набору даних secondarycache — спосіб точно контролювати цей компроміс.
Якщо ви запам’ятаєте тільки одне: кеш, що дає мало, не є «безпечним». Він спалює ресурси — CPU, RAM, пропускну здатність запису і витривалість SSD.

Найбільш продакшн-зріла конфігурація L2ARC, яку я бачив, була також найменш драматичною: кешуйте набори даних, які явно перечитуються,
розглядайте лише метадані там, де це підходить, і безапеляційно встановлюйте secondarycache=none для стрімінгових навантажень. Кешувати нічого — іноді найшвидший варіант.

← Попередня
Mars Climate Orbiter: Розбіжність одиниць, яка призвела до втрати космічного апарата
Наступна →
Обмеження розміру електронних повідомлень: безпечно збільшити їх, не дозволивши зловживань

Залишити коментар