ZFS: використання NVMe як L2ARC — коли ARC замало

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

Коли б не був адміністратор ZFS, рано чи пізно з’являється одна й та сама проблема: робочий набір даних не поміщається в оперативну пам’ять. Симптоми знайомі — різкі стрибки затримок, інтенсивна робота дисків, користувачі стверджують «сховище повільне» з такою моральною впевненістю, ніби ніколи не дивилися на iostat.

NVMe як L2ARC здається очевидним вирішенням: додайте швидкий кеш-пристрій і живіть далі. Іноді це блискуче рішення. Іноді це дорогий спосіб вбити NVMe, при цьому продуктивність залишається посередньою. Цей матеріал про те, як зрозуміти, у якій ви реальності — перш ніж навчитися цьому в продуктиві.

Що таке L2ARC (і чим він не є)

ZFS має первинний кеш під назвою ARC (Adaptive Replacement Cache). Він живе в оперативній пам’яті і дуже добре зменшує вартість повторних зчитувань. Коли ARC замалий для вашого робочого набору, ZFS може розширити кеш на швидкий пристрій: L2ARC, «рівень 2 ARC». L2ARC — це кеш тільки для читання. Не буфер запису, не акселератор журналювання, не чарівна паличка.

Що відбувається на практиці:

  • ARC відстежує «гарячі» дані. Якщо ARC не може їх утримати, ZFS може перемістити частину цих даних в L2ARC.
  • При промаху в ARC, ZFS може шукати в L2ARC. Якщо знайдено, читання відбувається з NVMe замість повільніших дисків або SSD.
  • Вміст L2ARC наповнюється з часом. Історично він не зберігався після перезавантаження; у новіших реалізаціях існує персистентність (детальніше далі).

Чого L2ARC не робить:

  • Не прискорює синхронні записи (це вже зона SLOG, і навіть там — тільки для певних навантажень).
  • Не виправить пул, який повільний через фрагментацію, погане розташування vdev або вузьке місце на CPU.
  • Не усуває необхідність правильно розмірювати оперативну пам’ять. L2ARC все ще потребує RAM-метаданих, щоб бути корисним.

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

Цитата, яка має бути у кожному on-call розкладі: Надія — не стратегія — attributed to General Gordon R. Sullivan. Ставтеся до L2ARC так само: вимірюйте, потім приймайте рішення.

Цікаві факти та історія (коротко, корисно, з думкою)

  • ARC з’явився ще до більшості «хмарних» практик. ZFS та ARC походять із періоду Solaris, коли пам’ять була дорогою, а диски повільними, тому політика кешування мала значення.
  • L2ARC був створений для кешування читань, а не для надійності. Ранні реалізації втрачали кеш після перезавантаження; це формувало очікування операційних команд роками.
  • L2ARC потребує RAM для опису вмісту. Кожен кешований блок вимагає метаданих в ARC. Величезний L2ARC може непомітно відбирати RAM, яка таки потрібна ARC.
  • NVMe зробив L2ARC менш ганебним. Ранні L2ARC-пристрої часто були SATA SSD; поліпшення латентності були реальні, але не завжди драматичні. Низька латентність NVMe змінила баланс.
  • Prefetch і L2ARC мають складні відносини. Послідовні читання можуть залити кеш даними, які ви ніколи не торкнетеся знову. ZFS додав параметри (наприклад, l2arc_noprefetch), бо люди постійно кешували те, про що потім жалкували.
  • Є «податок на прогрів». L2ARC наповнюється поступово, а не миттєво. Перші години (або дні) можуть виглядати гірше, ніж «без L2ARC», особливо якщо ви неправильно його розмірили.
  • Швидкість наповнення кешу навмисно обмежена. ZFS обмежує агресивність записів в L2ARC, щоб уникнути перетворення системи на фабрику запису кешу.
  • L2ARC — не безкоштовна опція. Він споживає CPU, пам’ять і робить записи на NVMe. Це зношування реальне; плануйте його, як плануєте зберігання логів.
  • Сьогодні існує персистентний L2ARC у сучасних реалізаціях ZFS. Він зменшує проблему прогріву після перезавантажень, але не універсальний і також має свої витрати.

Коли NVMe L2ARC дійсно допомагає

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

Хороші випадки

  • Хости віртуалізації з стабільними «гарячими» блоками ОС для багатьох гостьових систем: спільні бібліотеки, завантажувальні файли, загальні бінарні файли, репозиторії патчів.
  • Бази даних з навантаженням, орієнтованим на читання, де робочий набір трохи перевищує RAM (або ви не хочете купувати більше RAM через фінанси).
  • CI/build кеші, де одні й ті самі тулчейни використовуються повторно і пул базується на HDD.
  • Аналітичні кластери, що часто сканують ті самі «свіжі» розділи, але не в повністю послідовний спосіб.

Ключова умова: L2ARC має бути швидшим за те, що він замінює

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

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

Коли L2ARC — пастка

Більшість історій «L2ARC розчарував» зводяться до одного з наступних випадків:

1) Ваше навантаження не робить повторних читань

Інвентаризація резервних копій, холодні аналітичні сканування, одноразові копіювання файлів, обробка великих послідовних медіафайлів — ці операції зазвичай «пропливають» через кеш і зникають. L2ARC перетворюється на записовий трафік NVMe з невеликим віддачею по хитам.

2) ARC голодний, і L2ARC робить ситуацію гіршою

L2ARC потребує метаданих в RAM. Якщо у системи вже тиск на пам’ять, додавання великого L2ARC може зменшити ефективний розмір ARC і підвищити кількість промахів. Вітаємо — ви закешували більше на NVMe, одночасно втративши те, що робить кеш швидким: RAM.

3) Ваша проблема не в читаннях

Якщо біль викликаний синхронними записами, малими випадковими записами або контенцією метаданих, L2ARC може майже нічого не змінити. Часто правильним рішенням буде інший vdev-лэйаут, окремий vdev для метаданих/малих блоків, більше RAM або тонке налаштування застосунку.

4) Ви побудували кеш, який трешиться

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

Вибір NVMe для L2ARC: затримки, витривалість і чому «швидкий» недостатньо

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

Латентність і поведінка черги

L2ARC-операції — це випадкові читання. Ваш NVMe має витримувати високі IOPS без перетворення p99-латентності на щотижневий сюрприз. Важливі диски зі стабільною продуктивністю (часто «підприємницького» класу). Побутові диски можуть бути прийнятними, але ризик стрибків вищий, коли SLC-кеш вичерпується або під тривалими записами при наповненні кеша.

Витривалість — це фіча, а не дрібниця

L2ARC наповнюється записами. Деякі навантаження створюють постійний обмін: блоки записуються в кеш, замінюються, знову записуються. Це може швидко з’їдати TBW у побутових дисків швидше, ніж очікує відділ закупівель.

Правило приблизно таке: якщо ви не можете чітко пояснити швидкість запису кешу, не купуйте найдешевший NVMe. Купіть той, який ви зможете замінити без кар’єрних дискусій.

Захист від втрати живлення (PLP)

L2ARC — кеш; він не повинен бути довговічним. Але поведінка під час відключень живлення має значення, бо при проблемах диск може зависнути на шині PCIe, блокувати шляхи I/O або спричиняти ресети контролера. PLP не обов’язковий для L2ARC, але «нудна корпоративна поведінка» дуже доречна в продакшені.

Розмір L2ARC: проста математика, реальні обмеження

Люди розмірюють L2ARC як об’єктне сховище: «чим більше, тим краще». Так ви отримаєте 4 ТБ кеша перед системою з 64 ГБ RAM і ARC, що задихається.

Реальність накладних витрат RAM

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

Почніть з малого і доведіть цінність

Операційно розумні стартові підходи:

  • Вибирайте розмір L2ARC, який не перевищує кількох кратних оперативній пам’яті для типових систем, якщо у вас немає вимірювань, що виправдовують більше.
  • Надавайте перевагу «правильному за розміром» NVMe над «найбільшим доступним». Кеш, який ніколи не прогрівається, — пам’ятник оптимізму.
  • Вимірюйте коефіцієнти попадань і приріст по латентності перед масштабуванням.

Recordsize і стиснення мають значення

ZFS кешує блоки. Якщо ваші datasets використовують recordsize 1M для великих послідовних записів, це змінює поведінку кешування порівняно з 16K recordsize, типовим для деяких БД. Стиснення також впливає на те, скільки «логічних» даних вміщується в кеш і може значно підвищити ефективну ємність кеша.

Ручки налаштування, що важливі (і ті, що здебільшого ні)

Більшість налаштувань L2ARC стосується зменшення марного кешування і запобігання перетворенню наповнення кеша в самостійне навантаження.

Віддавайте перевагу кешуванню на вимогу, а не prefetch

Prefetch — це спроба ZFS допомогти для послідовного доступу. Для L2ARC він може бути шкідливим, бо заповнює кеш даними, які були прочитані один раз послідовно і більше не знадобляться.

Поширений підхід: увімкніть L2ARC, але не кешуйте prefetch. На Linux/OpenZFS це часто контролюється через l2arc_noprefetch. Точні значення за замовчуванням і поведінка залежать від версії; перевіряйте на своїй збірці.

Контролюйте швидкість наповнення

L2ARC наповнюється при виведенні з ARC. Є налаштування, що контролюють, скільки записується за інтервал і як швидко це нарощується. Якщо ви тиснете занадто сильно, ви:

  • Підвищите записовий трафік на NVMe (вплив на витривалість).
  • Витратите CPU на ведення обліку кешу.
  • Можливо, позмагатиметеся з реальним I/O робочого навантаження.

Персистентний L2ARC: корисно, але не боготворіть

Персистентний L2ARC зменшує прогрів після перезавантаження, зберігаючи заголовки кешу й вміст між перезапусками. Це може бути великим плюсом для систем, що перезавантажуються під час патчів і потребують передбачуваної продуктивності після рестарту. Але персистентність додає складності та сканування під час завантаження. Тестуйте перед впровадженням.

Практичні завдання: команди, виводи та рішення

Це реальні завдання, які можна виконати на Linux OpenZFS хості. Виводи репрезентативні. Ваші числа відрізнятимуться; рішення не повинні бути на вподобання.

Завдання 1: Перевірте стан пулу перед роботою з кешем

cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 02:11:43 with 0 errors on Sun Dec 22 03:10:12 2025
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
            sde                     ONLINE       0     0     0
            sdf                     ONLINE       0     0     0

errors: No known data errors

Що це означає: Ви не горите. Якщо бачите checksum errors або degraded vdevs — виправляйте спочатку це.

Рішення: Додавайте L2ARC тільки до стабільного пулу. Кеш-пристрій не врятує хворий пул.

Завдання 2: Перевірте, чи вже існує L2ARC

cr0x@server:~$ sudo zpool list -v tank
NAME         SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank        65.4T  41.2T  24.2T        -         -    22%    63%  1.00x  ONLINE  -
  raidz2   65.4T  41.2T  24.2T        -         -    22%    63%
    sda        -      -      -        -         -      -      -
    sdb        -      -      -        -         -      -      -
    sdc        -      -      -        -         -      -      -
    sdd        -      -      -        -         -      -      -
    sde        -      -      -        -         -      -      -
    sdf        -      -      -        -         -      -      -

Що це означає: Розділ cache відсутній, отже L2ARC немає.

Рішення: Продовжуйте з вибором і приєднанням NVMe або зупиніться, якщо проблему можна вирішити RAM або лейаутом.

Завдання 3: Підтвердіть ідентифікацію NVMe і його стан (перед тим, як ZFS торкнеться)

cr0x@server:~$ lsblk -o NAME,MODEL,SIZE,ROTA,TYPE,MOUNTPOINT | grep -E 'nvme|NAME'
NAME        MODEL                 SIZE ROTA TYPE MOUNTPOINT
nvme0n1     Samsung SSD 980 PRO  931.5G    0 disk

Що це означає: Ви збираєтесь використовувати /dev/nvme0n1, 1 TB, без ротації.

Рішення: Переконайтесь, що це не диск з ОС. Якщо NVMe також тримає root — зупиніться. Спільне використання можливе, але рідко розумне.

Завдання 4: Перевірте SMART NVMe і індикатори витривалості

cr0x@server:~$ sudo smartctl -a /dev/nvme0n1 | sed -n '1,35p'
smartctl 7.4 2023-08-01 r5530 [x86_64-linux-6.8.0] (local build)
=== START OF INFORMATION SECTION ===
Model Number:                       Samsung SSD 980 PRO 1TB
Serial Number:                      S5GXNF0R123456A
Firmware Version:                   5B2QGXA7
PCI Vendor/Subsystem ID:            0x144d
IEEE OUI Identifier:                0x002538
Total NVM Capacity:                 1,000,204,886,016 [1.00 TB]
Unallocated NVM Capacity:           0
Controller ID:                      6
Number of Namespaces:               1
Namespace 1 Size/Capacity:          1,000,204,886,016 [1.00 TB]

SMART/Health Information (NVMe Log 0x02)
Critical Warning:                   0x00
Temperature:                        44 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    2%
Data Units Written:                 14,512,331
Data Units Read:                    22,900,112

Що це означає: Диск здоровий, низький знос (Percentage Used).

Рішення: Якщо знос вже високий — не призначайте цей диск для інтенсивного кешування. Якщо мусите — обмежте швидкість наповнення і моніторте записи.

Завдання 5: Спостерігайте поточний розмір ARC і тиск на нього

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsize  c
12:10:01  8160  1432     17   902   11   420    5   110    1     46G  58G
12:10:02  7992  1470     18   961   12   401    5   108    1     46G  58G
12:10:03  8421  1522     18  1002   12   413    5   107    1     46G  58G

Що це означає: ARC ≈46G, target/limit ≈58G. Miss rate ≈18%. Це може бути нормально або погано, залежно від латентності пулу.

Рішення: Якщо ARC значно нижче свого таргету через брак пам’яті ОС, виправте тиск пам’яті спочатку. L2ARC не замінить RAM.

Завдання 6: Виміряйте, звідки зараз походять читання

cr0x@server:~$ sudo zpool iostat -v tank 1 3
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        41.2T  24.2T   8900    420   195M  6.8M
  raidz2    41.2T  24.2T   8900    420   195M  6.8M
    sda         -      -   1500     70  33.0M  1.2M
    sdb         -      -   1490     72  32.8M  1.1M
    sdc         -      -   1520     71  33.5M  1.1M
    sdd         -      -   1475     68  32.4M  1.1M
    sde         -      -   1460     69  32.1M  1.1M
    sdf         -      -   1455     70  31.9M  1.1M

Що це означає: Читання інтенсивно вдаряють по HDD vdevs. Якщо латентність висока і робочий набір повторно читається, L2ARC може допомогти.

Рішення: Якщо диски насичені і читання випадкові — кеш має сенс. Якщо читання малі і багато метаданих — розгляньте спеціальний vdev замість L2ARC.

Завдання 7: Прикріпіть NVMe як L2ARC

cr0x@server:~$ sudo zpool add tank cache /dev/nvme0n1
cr0x@server:~$ sudo zpool status 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
            sde                     ONLINE       0     0     0
            sdf                     ONLINE       0     0     0
        cache
          nvme0n1                   ONLINE       0     0     0

Що це означає: NVMe тепер — кеш-пристрій (L2ARC).

Рішення: Не святкуйте перемогу. Тепер моніторте прогрів, коефіцієнт попадань і записові навантаження на NVMe.

Завдання 8: Перевірте, чи L2ARC використовується (хіти та розмір)

cr0x@server:~$ arcstat 1 5 | sed -n '1,6p'
    time  read  miss  miss%  ...  l2hit  l2miss  l2miss%  l2bytes  arcsize  c
12:18:01  9010  1210     13  ...   2200     980       31     190G     47G  58G
12:18:02  9155  1198     13  ...   2350     960       29     191G     47G  58G
12:18:03  9033  1160     12  ...   2480     910       27     192G     47G  58G
12:18:04  9199  1205     13  ...   2605     920       26     194G     47G  58G
12:18:05  9122  1188     13  ...   2710     890       25     195G     47G  58G

Що це означає: L2ARC ≈195G заповнений і обслуговує хіти (l2hit). L2 miss% падає у міру прогріву.

Рішення: Якщо l2bytes залишаються крихітними годинами під сталою навантаженням — щось не так: швидкість наповнення, шаблон навантаження, або ви просто не виводите корисні блоки з ARC.

Завдання 9: Слідкуйте за NVMe I/O, щоб переконатися, що наповнення кешу не знищує латентність

cr0x@server:~$ iostat -x 1 3 | sed -n '1,25p'
Linux 6.8.0 (server)  12/26/2025  _x86_64_  (32 CPU)

Device            r/s     w/s   rMB/s   wMB/s  await  svctm  %util
nvme0n1         3200.0  180.0   125.0    40.0   0.7    0.2   68.0
sda              250.0   12.0     4.1     0.3  18.4    2.2   55.0
sdb              240.0   11.0     4.0     0.3  19.1    2.2   54.0

Що це означає: NVMe завантажений, але латентність (await) низька. HDD показують вищий await, звично.

Рішення: Якщо await на NVMe піднімається до кількох мілісекунд і конкурує з I/O додатків — зменшіть швидкість запису L2ARC або перегляньте підхід. Ваш кеш не має ставати найгарячішим пристроєм.

Завдання 10: Підтвердіть властивості dataset, що впливають на кеш

cr0x@server:~$ sudo zfs get -o name,property,value,source recordsize,primarycache,secondarycache,compression tank/vmstore
NAME          PROPERTY        VALUE     SOURCE
tank/vmstore  recordsize      128K      local
tank/vmstore  primarycache    all       default
tank/vmstore  secondarycache  all       default
tank/vmstore  compression     lz4       local

Що це означає: І ARC, і L2ARC дозволені (primarycache=all, secondarycache=all).

Рішення: Якщо dataset має secondarycache=none, L2ARC його не кешуватиме. Це може бути коректно для стрімінгових резервних копій або прихована помилка конфігурації.

Завдання 11: Виключіть стрімінгові набори даних з L2ARC, щоб уникнути забруднення

cr0x@server:~$ sudo zfs set secondarycache=none tank/backups
cr0x@server:~$ sudo zfs get -o name,property,value,source secondarycache tank/backups
NAME         PROPERTY        VALUE  SOURCE
tank/backups secondarycache  none   local

Що це означає: Dataset резервних копій не наповнюватиме L2ARC.

Рішення: Робіть так, коли великі послідовні читачі/записи витісняють корисні кешовані блоки. Залишайте кеш для навантажень, що «платять ренту».

Завдання 12: Перегляньте параметри модуля, пов’язані з L2ARC (Linux OpenZFS)

cr0x@server:~$ sudo sysctl -a 2>/dev/null | grep -E 'l2arc_|zfs\.arc_' | head
zfs.l2arc_noprefetch = 1
zfs.l2arc_write_max = 8388608
zfs.l2arc_write_boost = 33554432
zfs.arc_max = 62277025792
zfs.arc_min = 15569256448

Що це означає: Prefetch не кешується в L2ARC, і встановлені обмеження записів (байти за інтервал).

Рішення: Якщо l2arc_noprefetch = 0 і у вас послідовні навантаження — подумайте про ввімкнення. Якщо наповнення кешу надмірно агресивне — акуратно зменшіть l2arc_write_max і перевіряйте ефект.

Завдання 13: Тимчасово змініть налаштування L2ARC безпечно і перевірте ефект

cr0x@server:~$ sudo sysctl -w zfs.l2arc_write_max=4194304
zfs.l2arc_write_max = 4194304

Що це означає: Зменшено максимальну швидкість запису в L2ARC (тут до 4 MiB за інтервал; тривалість інтервалу залежить від реалізації).

Рішення: Використайте це, якщо записи NVMe конкурують із чутливими по латентності операціями. Перевірте iostat та p99-латентність застосунків після зміни.

Завдання 14: Переконайтесь, що ви не плутаєте SLOG з L2ARC

cr0x@server:~$ sudo zpool status tank | sed -n '1,35p'
  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
            sde                     ONLINE       0     0     0
            sdf                     ONLINE       0     0     0
        cache
          nvme0n1                   ONLINE       0     0     0

Що це означає: Присутній тільки cache vdev. Відсутність секції logs означає, що SLOG не налаштований.

Рішення: Якщо ваша проблема — синхронні записи (NFS з sync, бази даних з частими fsync), L2ARC цього не виправить. Розгляньте SLOG — уважно і тільки після вимірювань.

Завдання 15: Видаліть L2ARC (якщо він не допомагає) без драм

cr0x@server:~$ sudo zpool remove tank nvme0n1
cr0x@server:~$ sudo zpool status 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
            sde                     ONLINE       0     0     0
            sdf                     ONLINE       0     0     0

Що це означає: L2ARC від’єднаний. Структура пулу незмінна (cache vdev не зберігають унікальні дані).

Рішення: Якщо після видалення продуктивність не змінилась або покращилась — ваш кеш був шумом або шкодою. Перестаньте намагатися змусити його працювати і виправляйте справжнє вузьке місце.

Завдання 16: Оцініть тиск на пам’ять і поведінку звільнення (Linux)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           128Gi        94Gi       4.1Gi       1.2Gi        30Gi        26Gi
Swap:           16Gi       2.3Gi        13Gi

Що це означає: RAM інтенсивно використовується, available 26Gi, swap задіяний.

Рішення: Swap-активність на сторедж-боксі часто означає, що ARC стиснений або хост перевантажений (VMs, контейнери). Перед додаванням L2ARC подумайте про додавання RAM або зменшення сумісних навантажень. Накладні витрати метаданих L2ARC не врятують хост, що свопить.

Швидкий план діагностики: знайти вузьке місце за хвилини

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

Перше: визначте, чи у вас проблема з затримкою читань чи щось інше

  • Перевірте I/O пулу і проксі-метрики латентності: zpool iostat -v 1, iostat -x 1.
  • Якщо диски не завантажені й латентність низька — проблема може бути в CPU, мережі, блокуваннях додатку або поведінці синхронних записів.

Друге: перевірте ефективність ARC і тиск на пам’ять

  • Використайте arcstat для оцінки miss rate і стабільності розміру ARC.
  • Використайте free -h і слідкуйте за swap. Якщо хост свопить — виправте це. L2ARC не лікує голод по пам’яті.

Третє: підтвердіть, що робоче навантаження має тимчасову локальність

  • Шукайте повторні читання: поведінка буферного кешу БД, хвилі завантажень VM, повторювані збірки в CI.
  • Якщо переважно стрімінг — L2ARC буде генератором зносу.

Четверте: протестуйте малий L2ARC і виміряйте

  • Додайте NVMe L2ARC і дивіться l2hit, l2miss і p95/p99-латентність застосунку.
  • Прогрів важливий; оцінюйте за цикл робочого навантаження, а не за 10 хвилин.

П’яте: якщо це важкі метадані — розгляньте інший дизайн

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

Три міні-історії з корпоративного життя

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

У них був завантажений кластер віртуалізації на HDD RAIDZ2. Користувачі скаржилися на «випадкову повільність», здебільшого у понеділок вранці. Команда зберігання побачила read IOPS на пулі і вирішила «вирішити це правильно» великим NVMe L2ARC — кілька терабайтів, бо procurement любить круглі числа.

Встановили без проблем. Графіки виглядали захопливо: завантаження NVMe підскочило, read IOPS пулу впали. Всі відчули себе розумними приблизно добу.

Потім латентність почала повільно зростати. Не на HDD — на хості. Розмір ARC зменшився. Гіпервізор почав свопити під навантаженням. Струми запусків VM стали гіршими, не кращими, а хелпдеск вивчив нову лексику.

Невірне припущення було просте: «L2ARC — додатковий кеш, він не може зробити пам’ять гіршою». Насправді великий L2ARC поглинув метадані ARC і зменшив ефективний RAM-кеш. Система поміняла швидкі RAM-хіти на повільні NVMe-хіти та більше промахів. Вони видалили L2ARC, додали RAM до хостів і пізніше повернули менший кеш, таргетований на конкретні datasets. Продуктивність нормалізувалася і залишалася нудно стабільною.

Міні-історія 2: Оптимізація, що відбилася боком

Команда платформи даних виконувала аналітику на пулі ZFS на SSD. Хотіли прискорити звіти, і хтось запропонував L2ARC на запасному побутовому NVMe. «Це просто кеш; якщо він впаде — нічого не зламається». Це було технічно в вузькому сенсі вірно.

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

Через кілька тижнів NVMe почав видавати media errors. Не катастрофічно, але достатньо для алертів і I/O-хиків. Під час одного інциденту ресет пристрою спричинив тимчасові паузи, що виглядали як масштабний outage. Люди звинувачували ZFS. ZFS здебільшого знизував плечима; пристрій мав проблеми.

Післямова була неприємною, бо «оптимізація» не покращила p99 дашбордів. Виправлення було нудним: видалити L2ARC, оптимізувати запити, щоб зменшити обмін, і пізніше додати невеликий спеціальний vdev для метаданих та малих блоків. Дашборди покращилися, і NVMe перестав «прагнути вмерти» заради невимірної фічі.

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

Фінансова служба використовувала ZFS для зберігання VM і внутрішніх сервісів. Вони мали L2ARC на дзеркалізованих NVMe (так, дзеркалізованих — бо були слоти і вони цінували сон). Їхня політика змін була дуже сувора: кожна зміна зберігання вимагала базової лінії, план відкату і явну метрику успіху.

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

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

Це не було гламурно, але врятувало дні метушні.

Жарт №2: Єдина річ більш персистентна за L2ARC — це зацікавлений стейкхолдер з питанням «чому б нам просто не додати більше NVMe?»

Поширені помилки: симптом → причина → виправлення

1) Симптом: коефіцієнт попадань L2ARC близький до нуля

Причина: Навантаження — стрімінгове або з низькою локальністю повторних читань; або dataset має secondarycache=none; або кеш надто малий і відразу трешиться.

Виправлення: Перевірте властивості dataset за допомогою zfs get secondarycache. Виключіть стрімінгові набори. Якщо локальність низька — видаліть L2ARC і інвестуйте інакше.

2) Симптом: розмір ARC зменшується після додавання L2ARC, промахи зростають

Причина: Накладні витрати RAM для метаданих L2ARC зменшують ємність ARC; хост має тиск пам’яті; L2ARC надто великий.

Виправлення: Зменште розмір L2ARC (менший розділ/пристрій), додайте RAM або видаліть L2ARC. Підтвердіть через arcstat і free -h.

3) Симптом: високе навантаження NVMe, стрибки латентності, застосунок гіршає

Причина: Швидкість наповнення L2ARC надто агресивна; NVMe — побутовий диск з поганою поведінкою під навантаженням; наповнення кешу конкурує з роботою.

Виправлення: Зменшіть l2arc_write_max/l2arc_write_boost. Використайте більш передбачуваний NVMe. Розгляньте виключення шумових datasets з L2ARC.

4) Симптом: чудова продуктивність… поки не перезавантажиш, тоді кілька годин жах

Причина: Неперсистентний L2ARC потребує прогріву; навантаження сильно залежить від попадань у кеш.

Виправлення: Оцініть підтримку персистентного L2ARC у вашій версії ZFS. Якщо немає або воно небажане — плануйте перезавантаження і попередній прогрів або збільшіть RAM, щоб зменшити залежність від L2ARC.

5) Симптом: ви чекали швидших записів, але нічого не змінилося

Причина: L2ARC — це кеш читань. Записи залежать від поведінки ZIL/SLOG, лейаута пулу і семантики sync.

Виправлення: Виміряйте синхронні записи. Якщо потрібно — розгляньте SLOG з підходящим пристроєм і тестами. Не наслідуйте «NVMe = швидше» без вимірів.

6) Симптом: L2ARC допомагає деяким навантаженням, але резервні копії все гальмують

Причина: Забруднення кешу та тиск на вилучення через послідовні резервні читання/записи.

Виправлення: Встановіть secondarycache=none (іноді також primarycache=metadata) для backup datasets. Залишайте кеш для інтерактивних/гарячих навантажень.

7) Симптом: багато CPU в ядрі під навантаженням після ввімкнення L2ARC

Причина: Накладні витрати на ведення кешу плюс підвищена активність вилучень; можливо, дуже багато малих блоків або агресивне наповнення.

Виправлення: Зменшіть швидкість запису L2ARC; переконайтесь, що ви не кешуєте prefetch; розгляньте збільшення recordsize там, де доречно, або перегляньте шаблон I/O навантаження.

8) Симптом: NVMe зношується швидше, ніж очікували

Причина: Постійний обмін через низьку локальність; надмірно великий кеш з високою оборотністю; агресивні параметри запису.

Виправлення: Виміряйте швидкість записів, обмежте feed, виключіть стрімінгові datasets або видаліть L2ARC. Купуйте диски з вищою витривалістю, якщо навантаження це виправдовує.

Чеклісти / покроковий план

План A: Вирішіть, чи взагалі додавати L2ARC

  1. Підтвердіть, що це проблема читань. Якщо пул має обмеження по записах або sync, зупиніться і діагностуйте інше.
  2. Виміряйте miss rate ARC і запас RAM. Якщо хост має тиск по пам’яті — пріоритет за RAM і розміщення навантаження.
  3. Підтвердіть повторну локальність читань. L2ARC для «читань, що повертаються». Якщо їх немає — не кешуйте.
  4. Перевірте лейаут пулу і проблеми метаданих. Якщо метадані — вузьке місце, спеціальний vdev може перевершити L2ARC.

План B: Безпечне впровадження NVMe L2ARC

  1. Базова лінія перед змінами. Зніміть arcstat, zpool iostat, iostat -x і латентність додатків.
  2. Виберіть адекватний NVMe. Надавайте перевагу стабільній латентності і витривалості над піковою пропускною здатністю.
  3. Почніть з помірного розміру кеша. Доведіть цінність перед масштабуванням.
  4. Прикріпіть пристрій як cache. Підтвердіть через zpool status.
  5. Запобігайте забрудненню кеша. Встановіть secondarycache=none для стрімінгових datasets.
  6. Моніторте прогрів і навантаження пристрою. Слідкуйте за l2hit/l2miss і NVMe await.
  7. Тонуйте обережно. Зменшуйте швидкість запису L2ARC, якщо вона конкурує з реальним I/O.
  8. Задокументуйте відкат. Знайте, як виконати zpool remove кеш-пристрій і що означає «успіх».

План C: Операційні запобіжники, що тримають вас у безпеці

  • Алертуйте по зносу NVMe і media errors. L2ARC може бути важким для дисків; ставте його як змінний компонент.
  • Слідкуйте за коефіцієнтами попадань кеша з часом. Кеш, що був корисним, може стати непридатним після змін у застосунках.
  • Плануйте перезавантаження. Якщо L2ARC неперсистентний — плануйте рестарти на час, коли прогрів не зашкодить.
  • Змінюйте потроху. Якщо міняєте розмір кеша, налаштування і властивості datasets одночасно — ніколи не дізнаєтесь, що спрацювало.

FAQ

1) Чи те саме L2ARC й SLOG?

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

2) Чи потрібно дзеркалити пристрої L2ARC?

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

3) Чи може L2ARC погіршити продуктивність?

Так. Типові механізми: зменшення ARC (накладні RAM-метадані), конкуренція записів при наповненні кешу і забруднення кеша стрімінговими навантаженнями. «Кеш» не означає автоматично «швидше».

4) Скільки часу займає прогрів L2ARC?

Залежить від робочого набору, швидкості вилучення з ARC і обмежень feed L2ARC. Для завантажених систем це можуть бути години; для спокійніших — дні. Якщо потрібні миттєві виграші — купуйте більше RAM спочатку.

5) Чи кешувати prefetch у L2ARC?

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

6) Як запобігти руйнуванню кеша резервними копіями?

Встановіть secondarycache=none на backup datasets. В деяких середовищах також варто застосувати primarycache=metadata для стрімінгових наборів, щоб ARC зберігав метадані, але не масивні дані.

7) Чи варто вмикати персистентний L2ARC?

Якщо ваші навантаження чутливі до прогріву після перезавантаження і ваша версія ZFS підтримує це надійно — це може суттєво покращити якість життя. Протестуйте перезавантаження у стенді і слідкуйте за часом завантаження та використанням пам’яті.

8) У мене пул повністю на NVMe. Чи потрібен L2ARC?

Рідко. ARC у RAM все ще швидший за NVMe. Але якщо робочий набір величезний і багаторазово перечитується, і пул настільки завантажений, що відвантаження читань допомагає — L2ARC може бути корисним. Спочатку виміряйте; інакше ви просто додаєте складності.

9) Що краще: більше RAM чи більше L2ARC?

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

10) Як зрозуміти, чи L2ARC окупає себе?

Слідкуйте за p95/p99-латентністю і пропускною здатністю застосунку, не лише за коефіцієнтами попадань кеша. Зростання l2hit приємне, але бізнес-метрика — «менше повільних запитів». Якщо не можете показати покращення — видаліть кеш.

Практичні кроки далі

  1. Зніміть базову лінію сьогодні. Запишіть arcstat, zpool iostat -v і iostat -x у період, коли система «повільна».
  2. Визначте, чи робоче навантаження перечитується. Якщо це стрімінг — не будуйте святилище кеша.
  3. Виправте тиск пам’яті спочатку. Якщо є swap або ARC не досягає стабільного розміру — L2ARC відволікає від справжньої проблеми.
  4. Почніть з невеликого NVMe L2ARC і захистіть його. Виключіть стрімінгові datasets, уникайте кешування prefetch і тримайте швидкість запису в розумних межах.
  5. Вимірюйте результати, а не відчуття. Якщо p99-латентність покращилась і знос NVMe прийнятний — залишайте. Якщо ні — видаліть і переходьте до змін лейауту або збільшення RAM.
← Попередня
Гонка озброєнь DirectX: чому драйвери іноді випереджають кремній
Наступна →
«rm -rf /» — історії: команда, що стала жанром IT-жахів

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