Розмір ARC у ZFS: коли забагато кешу уповільнює все інше

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

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

Це та частина, яку більшість гайдів з налаштування пропускають: ARC не живе сам по собі. Він конкурує з page cache ядра, купами пам’яті додатків, ballooning у віртуальних машинах, лімітами контейнерів, метаданими файлових систем і просто «речами, які потрібні ОС, щоб вижити». Коли ARC стає надто великим (або занадто неохоче зменшується), це може викликати свопінг, затримки при прямому звільненні пам’яті, стрибки латентності та каскадні відмови, які змушують сумніватися, чи ваші графіки моніторингу — це все-таки продуктивність, чи модерне мистецтво.

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

ARC — це кеш ZFS у пам’яті для як даних файлів, так і метаданих. Це не «просто кеш для читання» у спрощеному сенсі. Це мультисписковий кеш (MRU/MFU плюс «примарні» списки-привиди), спроектований так, щоб адаптуватися до навантажень, що коливаються між потоковими читаннями і повторними читаннями, а також між доступами, орієнтованими на метадані, і тими, що орієнтовані на дані.

ARC також відіграє роль у тому, як ZFS уникає частих звернень до диска за метаданими — думайте про непрямі блоки, dnode, обходи директорій і загальну ланцюжок «де насправді мій файл?». Якщо ви бачили пул з великою сирою IOPS, але навантаження все одно повзе, часто винна латентність метаданих, а не пропускна здатність даних.

Чого ARC не є: це не Linux page cache (навіть якщо воно конкурує з ним), це не заміна пам’яті додатків і це не чарівний важіль «дай мені всю RAM», що робить будь‑яке навантаження швидшим. Завдання ARC — зменшити I/O до диска. Якщо ваша пляшка вантах не пов’язана з дисковим I/O, ARC може стати найдорожчим прес-пап’є в світі.

Жарт в один реченні №1: ARC схожий на стажера з величезним картотечним шафом — корисний, поки він не заїде в єдиний коридор і не перекриє вихід.

ARC, «брудні» дані і чому робота з записами все ускладнює

Поведіка записів у ZFS більше керується механізмом transaction group (TXG) і лімітами «брудних» даних, ніж розміром ARC, але пам’ять все одно залишається спільним полем бою. Сильні записувачі можуть накопичувати «брудні» сторінки, викликати поведінку ZIL/SLOG і асинхронний writeback у зону конкуренції за пам’ять.

Надвеликий ARC безпосередньо не «з’їдає брудні дані», але він зменшує запас місця для всього іншого, і це змінює поведінку ядра під тиском. Коли система щільна по пам’яті, writeback може стати імпульсивним, латентність — стрибкоподібною, і ви починаєте відлагоджувати «зберігання», коли корінь проблеми — звільнення пам’яті.

Чому надвеликий ARC шкодить: реальні механізми

Будьмо чесними: «більше кешу завжди краще» справджується лише якщо у вас безмежна RAM і немає інших споживачів. Продакшн‑системи — не фантастичні романи. У них є бюджети.

Механізм 1: ARC проти власного кешу ядра і поведінки reclaim

На Linux ядро теж кешує сторінки. З ZFS у вас може вийти два кеші: ARC (всередині ZFS) і page cache (для таких речей, як бінарні файли, бібліотеки, mmap’и поза контекстом ZFS і іноді навіть побічні ефекти ZFS залежно від того, як ваше навантаження взаємодіє з системою). Якщо ARC займає забагато RAM, ядро може агресивно звільняти пам’ять в інших місцях, що призводить до затримок.

Симптоми: CPU проводить час у reclaim у ядрі, підвищене системне навантаження без фактичного завантаження CPU, і процеси застрягають у незупинному сні (D state). Користувачі тлумачать це як «диски повільні», бо все чекає на звільнення пам’яті, що виглядає як I/O wait.

Механізм 2: Своп-трещання: постійна плата за продуктивність

Своп не злий; неконтрольований своп — це зло. Машина, яка починає свопити через надвеликий ARC, може потрапити в петлю зворотного зв’язку:

  • Підвищується тиск на пам’ять → ядро викидає холодні сторінки додатків на своп.
  • Підвищується латентність → додатки зависають і таймаутять.
  • Повторні операції збільшують навантаження пам’яті → ще більший тиск.
  • ARC може зменшитись, але не завжди досить швидко і не завжди передбачувано для ваших SLO.

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

Механізм 3: ВМ і контейнери: ARC може позбавити пам’яті гостей

На хостах віртуалізації (Proxmox, bhyve, KVM на ZoL) ARC не є «безкоштовним». Гіпервізор і гості теж потребують пам’яті. Ballooning і overcommit лише погіршують ситуацію, бо хост може виглядати нормальним доти, доки раптом ним не стане — тоді починається reclaim і своп, а гості одночасно кричать за пам’ять. Надвеликий ARC перетворює керований overcommit на інцидент на рівні хоста.

Механізм 4: Домінування метаданих: ARC зростає залежно від того, що ви торкаєтесь

ARC — це не однорідні «дані». Деякі навантаження орієнтовані на метадані: мільйони дрібних файлів, розпаковка шарів контейнерів, CI‑системи, менеджери пакетів, схеми на зразок maildir, бекапи, що обходять дерева. ARC охоче заповниться метаданими, які прискорюють ці обходи — поки не витіснить пам’ять, яку вашій базі даних або JVM потрібно для уникнення GC‑бурь.

Механізм 5: Неправильне читання «вільної пам’яті» приводить до поганих рішень

ZFS любить пам’ять. Linux теж любить використовувати пам’ять. Мало «вільної» пам’яті — нормально. Питання в тому, чи система може швидко забрати пам’ять під час потреби без свопінгу або зависань. ARC можна налаштувати, щоб воно було «добрим сусідом» — або воно може поводитися так, ніби платить оренду, а всі інші піднаймають у нього кімнату.

Факти та історичний контекст, що змінюють підхід до налаштування

  1. ARC було спроектовано, щоб перевершувати класичний LRU адаптацією між «недавно використаним» і «часто використаним» даними; це не дурний кеш, який можна описати одним коефіцієнтом.
  2. Початкове середовище ZFS очікувало великі об’єми RAM. Ранні розгортання ZFS часто працювали на системах, де «багато пам’яті» було за замовчуванням, і рекомендації з налаштування відображали ту культуру.
  3. На Linux ZFS живе поза нативною моделлю кешування VFS у важливих аспектах; тому взаємодія ARC/page-cache і поведінка reclaim є центральними для продуктивності.
  4. L2ARC з’явився тому, що диски були повільні, а RAM дорога. Сьогодні NVMe змінив розрахунки: іноді «додати RAM» дешевше, іноді L2ARC має сенс, а іноді нічого не допомагає, якщо вузьке місце в CPU.
  5. ARC тримає і дані, і метадані; при навантаженнях, орієнтованих на метадані, помірний ARC може бути кращим за велетенський ARC, що викликає свопінг.
  6. Історично ARC мав проблеми з поведінкою стиснення під час звільнення пам’яті під тиском. Поліпшення були, але не варто припускати, що воно завжди віддасть пам’ять саме тоді, коли вам потрібно.
  7. Dedup у ZFS відомий своєю жадібністю до пам’яті через DDT; люди плутають «ZFS потребує RAM» з «дай ARC усе», що неправильний висновок.
  8. Віртуалізація змінила стандартну розмову про ARC. У 2010 «сервер зберігання» часто був лише сервером зберігання. У 2025 це частіше сервер зберігання, що також тримає маленьке містечко ВМ.
  9. Стиснення зробило кешування більш цінним, бо стиснуті блоки — більше логічних даних на байт ARC — але це також означає, що CPU може стати першим обмежувачем.

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

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

Тікет почався невинно: «API раптово має піки латентності кожного дня близько 10:00». Це був хост ВМ із томами на ZFS для кількох сервісів. Он‑кол побачив, що диски на 20% завантажені і зробив висновок «не схоже на зберігання». Графіки показували «переважно використовану» пам’ять, але це ж нормальна поведінка Linux, правда?

Потім хтось помітив графік свопу: повільне зростання починаючи з 09:40, що досягло краю близько 10:05. О 10:10 API‑под-и перезапускалися через таймаути. Середнє навантаження хоста було високим, але CPU ні. Це запах reclaim‑шторму: завдання чекають на пам’ять і I/O, а не виконують роботу.

Неправильне припущення було тонким: «ARC зменшиться, коли потрібно». Воно зменшилося — зрештою. Але «зрештою» вимірювалося хвилинами, а хвилини для клієнтських API — вічність. Спусковим тригером була запланована робота, що обходила велике дерево дрібних файлів (багата метаданими), роздуваючи ARC метаданими саме в той момент, коли JVM потребували розширення кучи.

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

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

Інша команда мала ініціативу «прискорити збірки». CI‑рабеки повільно розпаковували контейнери та залежності з dataset на ZFS. Хтось прочитав, що «ZFS любить RAM», тому підняли ліміт ARC до небес і в бенчмарку побачили покращення показників кеш‑хітів.

У продакшні це стало катастрофою. Збірки стали швидшими перший день, а потім поступово — все більш нестабільними. Чому? Бо ранери виконували багато епhemeral‑роботи: короткоживучі процеси, кеші компілятора і тимчасові файли. Збільшений ARC штовхнув хост у пам’ятевий тиск, і ядро почало викидати і свопити саме ті сторінки, які були потрібні системі збірки. Рівень хітів виглядав добре, але повний час завдання погіршився. Рівень хітів — метрика марнославства, коли планувальник починає пейджити.

Найболючіше: уповільнення не корелювало прямо з «розміром ARC». Воно корелювало з конкуруючістю. З однією збіркою машина була в порядку. З десятьма — вона падала. Оце і робить інциденти з пам’яттю такими марнотратними для часу інженерів: ви не можете відтворити їх на ноутбуці, і дашборди не кричать «ARC це зробив».

Вони відкотили підвищення ARC, а потім зробили нудну зміну: розділили CI‑навантаження так, щоб розпаковування і компіляція не конкурували на тих самих хостах з іншими чутливими сервісами. Урок не в тому, щоб ніколи не збільшувати ARC. Урок: не оптимізуйте одну стадію, дестабілізуючи платформу, на якій вона працює.

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

Ця історія протилежна драмі. Фінансова організація запускала ZFS на наборі хостів баз даних. Команда мала практику: кожен билд хоста включав явні обмеження ARC, перегляд політики swap і «SLO запасу пам’яті». Це не було гламурно. Це було записано і застосовувалось через конфіг‑менеджмент.

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

Оскільки ARC вже був обмежений, система не увійшла в смерть‑спіраль. DB‑команда побачила алерт, підкоригувала внутрішнє розмірення кешу і запланувала апгрейд RAM у наступному циклі потужності. Ніякого інцидент‑бріджу, ніякої паніки, ніякого «чому load 200?».

Ось неприваблива істина: більшість чудових SRE‑виходів — нудні. Найкраще налаштування ARC — те, яке ви зробили місяцями раніше, тихо, і забули про нього аж до того моменту, коли воно запобігло виклику в 3 ранку.

Ментальна модель: що вимірювати, а не во що вірити

Коли люди сперечаються про розмір ARC, зазвичай вони сперечаються з ідеології:

  • Люди зі зберігання: «Використовуйте RAM для кешу!»
  • Розробники додатків: «Перестаньте красти мою пам’ять!»
  • SRE: «Мені байдуже, хто виграє, мені важливо, щоб латентність перестала стрибати.»

Ось модель, яка припинить суперечки: ARC цінний, коли воно зменшує дорогий I/O без виклику дорожчої поведінки пам’яті. Дорогий I/O — це випадкові читання на HDD, синхронні мережеві читання або метадані‑пошуки, що гальмують ваше навантаження. Дорожча поведінка пам’яті — це свопінг, затримки reclaim і хаотичне оновлення кешу, що підвищує навантаження CPU.

Сигнали того, що ARC допомагає

  • Високий показник хітів ARC та стабільна латентність.
  • Нижчі disk read IOPS і нижча латентність читань у порівнянні з базовою лінією.
  • Немає свопінгу, немає тривалого reclaim‑тиску.
  • Додатки мають достатньо пам’яті, щоб тримати свої власні кеші/гарячі набори в Resident.

Сигнали того, що ARC шкодить

  • Активність swap in/out під час нормального навантаження.
  • Зростання major page faults без відповідного покращення пропускної здатності.
  • Підвищення load average при високому відсотку проста CPU.
  • Зростання I/O wait, при тому що диски не насичені.
  • Часті викиди ARC з низькою корисністю хітів (churn кешу).

Швидкий план діагностики

Це послідовність «у вас є 15 хвилин до того, як нарада з інциденту перетвориться на інтерпретативний крик». Робіть кроки в порядку.

1) Підтвердіть, що це тиск на пам’ять, а не насичення диска

Перевірте swap, reclaim і застряглі задачі. Якщо swap активний і бачите показники reclaim — підозрівайте ARC негайно.

2) Перевірте розмір ARC щодо запасу хоста

Подивіться поточне використання ARC, обмеження ARC і загальновільну пам’ять. На хостах ВМ також перевірте виділення пам’яті гостям і ballooning.

3) Скоординуйте поведінку ARC з типом навантаження

Це метаданих‑важке навантаження (багато файлів, багато stat, розпаковка контейнерів) чи даних‑важке (великі послідовні читання)? Стратегія розміру ARC відрізняється.

4) Шукайте churn кешу

Самі по собі показники хітів не достатні. Якщо ARC постійно викидає і знову завантажує блоки, ви платите CPU і блокуваннями за малу користь.

5) Тільки тоді торкайтеся регуляторів

Не налаштовуйте в сліпу. Зберіть невеликий пакет: статистику ARC, vmstat, iostat, top і 5‑хвилинне вікно поведінки. Потім обережно зменшіть zfs_arc_max і спостерігайте.

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

Ось реальні команди, які ви можете виконати на Linux з OpenZFS або на FreeBSD (з незначними відмінностями в шляхах/sysctl). Я зверну увагу, де це важливо. Розглядайте виводи як ілюстративні; у вас числа будуть інші.

Task 1: Check current ARC size and limits (Linux)

cr0x@server:~$ grep -E "c_max|c_min|size" /proc/spl/kstat/zfs/arcstats
13 c_max                            4    34359738368
14 c_min                            4    4294967296
 7 size                             4    28776239104

Інтерпретація: ARC max — 32 GiB, min — 4 GiB, поточний розмір ≈26.8 GiB. Якщо це система з 32 GiB RAM, що запускає бази даних і ВМ, це вже не «кеш», це ворожий захоплення ресурсів.

Task 2: Check ARC efficiency quickly (arcstat)

cr0x@server:~$ arcstat 1 5
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
12:00:01   920    40      4     2   0    38   4     0   0   26.9G  32.0G
12:00:02   880    55      6     1   0    54   6     0   0   27.0G  32.0G
12:00:03   910    48      5     2   0    46   5     0   0   27.1G  32.0G
12:00:04   940    60      6     3   0    57   6     0   0   27.1G  32.0G
12:00:05   905    42      5     1   0    41   5     0   0   27.2G  32.0G

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

Task 3: Check system memory headroom (Linux)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:            64Gi        55Gi       1.2Gi       2.0Gi       7.8Gi       3.5Gi
Swap:           16Gi       2.6Gi        13Gi

Інтерпретація: «available» — 3.5 GiB при вже використаному swap. При навантаженні це попереджувальний знак. ARC може сидіти на пам’яті, яку ОС і додатки потребують для стабільності.

Task 4: Detect swap thrash and reclaim pressure (vmstat)

cr0x@server:~$ vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  1 2684352 120000  80000 900000   20   80   200   150  900 1400 12 18 58 12  0
 6  2 2684800 110000  78000 880000  120  260   400   300 1100 2100 10 22 49 19  0
 7  3 2686000  90000  76000 860000  300  600   800   500 1300 2600  9 25 40 26  0

Інтерпретація: Ненульові si/so стійко означають активний свопінг. Зростання b (blocked procs) з підвищеним wa часто свідчить, що система чекає. Якщо це корелює з ARC поблизу max — ймовірний винуватець знайдено.

Task 5: Confirm disk isn’t the real bottleneck (iostat)

cr0x@server:~$ iostat -x 1 3
Device            r/s     w/s   rkB/s   wkB/s  avgrq-sz avgqu-sz   await  %util
nvme0n1          12.0    30.0    900    2200      80.0     0.20    2.10   12.5
nvme1n1          10.0    28.0    850    2100      78.5     0.18    2.00   11.0

Інтерпретація: Низьке %util і низьке await означають, що диски не насичені. Якщо латентність все одно погана — підозрюйте тиск на пам’ять або блокування, а не пропускну здатність дисків.

Task 6: Check ARC breakdown (data vs metadata)

cr0x@server:~$ grep -E "demand_data_bytes|demand_metadata_bytes|prefetch_data_bytes|prefetch_metadata_bytes" /proc/spl/kstat/zfs/arcstats
96 demand_data_bytes                4    12884901888
97 demand_metadata_bytes            4    13743895347
98 prefetch_data_bytes              4    1073741824
99 prefetch_metadata_bytes          4    268435456

Інтерпретація: Тут метадані великі — навіть більше ніж demand data. Це не обов’язково «помилка», але натякає на навантаження типу обходу дерев, дрібних файлів або образів віртуальних машин з великою метаданною активністю. Якщо ви позбавляєте додатки пам’яті, подумайте про обмеження ARC і/або зменшення джерел метаданного churn.

Task 7: Check for ARC shrink behavior and throttling

cr0x@server:~$ grep -E "arc_shrink|arc_no_grow|memory_throttle_count" /proc/spl/kstat/zfs/arcstats
171 arc_no_grow                     4    4821
198 memory_throttle_count           4    129

Інтерпретація: memory_throttle_count вказує, що ZFS доводилось обмежувати через тиск на пам’ять. Якщо це зростає під час інцидентів — ARC може сприяти загальній конкуренції ресурсів.

Task 8: Find your current ARC tunables (Linux module parameters)

cr0x@server:~$ sudo cat /sys/module/zfs/parameters/zfs_arc_max
34359738368
cr0x@server:~$ sudo cat /sys/module/zfs/parameters/zfs_arc_min
4294967296

Інтерпретація: Значення в байтах. Якщо ви їх не задавали, це можуть бути значення за замовчуванням, виведені з загальної RAM. За замовчуванням — не догма.

Task 9: Temporarily lower ARC max (Linux) to stop a fire

cr0x@server:~$ sudo sh -c 'echo 17179869184 > /sys/module/zfs/parameters/zfs_arc_max'
cr0x@server:~$ sudo cat /sys/module/zfs/parameters/zfs_arc_max
17179869184

Інтерпретація: Це обмежує майбутнє зростання; ARC не впаде миттєво до нового ліміту, але буде трендити вниз по мірі викидів. Слідкуйте за активністю свопу і латентністю. Якщо потрібне миттєве полегшення — ви в режимі інцидент‑реакції: зменшіть навантаження, перезапустіть найгірший процес або перемістіть робочі навантаження.

Task 10: Persist ARC limits (Linux, modprobe.d)

cr0x@server:~$ sudo tee /etc/modprobe.d/zfs.conf >/dev/null <<'EOF'
options zfs zfs_arc_max=17179869184
options zfs zfs_arc_min=2147483648
EOF
cr0x@server:~$ sudo update-initramfs -u

Інтерпретація: Це робить ліміти стійкими після перезавантаження. Механіка збереження відрізняється в дистрибутивах; головна думка: не покладайтеся на «хтось під час наступного інциденту нагадає echo у sysfs».

Task 11: FreeBSD: check and set ARC limits (sysctl)

cr0x@server:~$ sysctl kstat.zfs.misc.arcstats.size
kstat.zfs.misc.arcstats.size: 28776239104
cr0x@server:~$ sysctl vfs.zfs.arc_max
vfs.zfs.arc_max: 34359738368
cr0x@server:~$ sudo sysctl vfs.zfs.arc_max=17179869184
vfs.zfs.arc_max: 34359738368 -> 17179869184

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

Task 12: Check ZFS dataset recordsize and workload fit (because ARC isn’t magic)

cr0x@server:~$ zfs get recordsize,compression,primarycache tank/vmstore
NAME          PROPERTY      VALUE     SOURCE
tank/vmstore  recordsize    128K      default
tank/vmstore  compression   lz4       local
tank/vmstore  primarycache  all       default

Інтерпретація: Recordsize визначає, що кешується і наскільки ефективно. Для образів ВМ або баз даних неправильний recordsize може роздути кеш і підвищити read amplification. Розмір ARC не замінює базову гігієну dataset.

Task 13: Check primarycache/secondarycache policy (targeted relief)

cr0x@server:~$ zfs get primarycache,secondarycache tank/backup
NAME         PROPERTY        VALUE     SOURCE
tank/backup  primarycache    all       default
tank/backup  secondarycache  all       default
cr0x@server:~$ sudo zfs set primarycache=metadata tank/backup
cr0x@server:~$ zfs get primarycache tank/backup
NAME         PROPERTY      VALUE     SOURCE
tank/backup  primarycache  metadata  local

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

Task 14: Check for ZFS prefetch effects (useful or harmful)

cr0x@server:~$ sudo cat /sys/module/zfs/parameters/zfs_prefetch_disable
0
cr0x@server:~$ grep -E "prefetch_data_hits|prefetch_data_misses" /proc/spl/kstat/zfs/arcstats
68 prefetch_data_hits               4    105230
69 prefetch_data_misses             4    98210

Інтерпретація: Prefetch допомагає при послідовних читаннях, але може витрачати кеш при випадкових навантаженнях. Якщо передбачення часто промахуються і prefetch_data_bytes великі, ви можете кешувати здогадки замість фактів.

Task 15: Detect “everything is slow” due to blocked tasks

cr0x@server:~$ ps -eo state,pid,comm,wchan:32 --sort=state | head
D   2314  postgres         io_schedule
D   9881  java             balance_pgdat
D  11202  python3          zio_wait
R  21011  top              -

Інтерпретація: D state з balance_pgdat вкаже на тиск на reclaim пам’яті. Якщо ви бачите це під час інцидентів разом із ARC біля max — ви дивитесь на мотив і знаряддя злочину одночасно.

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

Покроковий план: правильно підібрати розмір ARC без здогадок

  1. Класифікуйте хост: appliance для зберігання, хост ВМ, сервер БД, універсальний. Бюджети ARC різняться.
  2. Встановіть цільовий запас (headroom): вирішіть, скільки RAM повинно залишатися доступним для ОС + додатків під піковим навантаженням. Запишіть це.
  3. Заміруйте базову лінію: зберіть 30 хвилин статистики ARC, активності swap, iostat і латентності додатків під типовим навантаженням.
  4. Виберіть початковий cap для ARC: консервативно. Для хостів ВМ і змішаних навантажень зазвичай правильніше залишати значний запас.
  5. Застосуйте кап тимчасово: змініть zfs_arc_max наживо, спостерігайте за покращенням swap/reclaim і будь‑яким падінням hit rate.
  6. Перевірте вплив на навантаження: дивіться p95/p99 латентність, не тільки throughput. Налаштування ARC — це про tail latency.
  7. Зробіть зміни постійними: через конфіг‑менеджмент, налаштування на завантаженні та план відкату.
  8. Переоцініть після змін: нові версії додатків, нові dataset, інша щільність ВМ — розмір ARC не встановлюють один раз і назавжди.

Операційний чекліст: перед тим, як змінювати ARC у продакшні

  • Чи активний зараз swap? Якщо так — зменшіть ризик спочатку: знизьте навантаження або масштабуйте.
  • Чи є у вас віддалений доступ out‑of‑band? Інциденти з пам’яттю можуть зробити SSH «інтерактивним мистецтвом».
  • Чи знаєте ви, як швидко відкотити зміну?
  • Чи маєте ви 10‑хвилинне вікно спостереження зі стабільним навантаженням?
  • Чи захопили ви метрики «до» (ARC size, vmstat, iostat, латентність)?

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

Mistake 1: “ARC має бути якомога більшим.”

Симптоми: Використання swap повільно зростає за дні; p99 латентність стрибає під час cron‑задач; load average росте, коли CPU не навантажений; випадкові OOM‑кіли.

Виправлення: Обмежте zfs_arc_max, щоб залишити реальний запас. На хостах ВМ будьте суворішими, ніж на виділених storage‑машинах. Перевіряйте за допомогою vmstat і латентності додатків.

Mistake 2: Налаштування лише на основі hit rate

Симптоми: Hit rate покращився, але загальна продуктивність погіршилась; більше context switches; більше часу в ядрі; затримки помітні користувачам.

Виправлення: Розглядайте hit rate як допоміжну метрику. Пріоритет давайте активності swap, тиску reclaim, заблокованим задачам і хвостовій латентності.

Mistake 3: Ігнорування метаданно‑важких навантажень

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

Виправлення: Розгляньте контроль на рівні dataset, як-от primarycache=metadata для об’ємних даних, і обмежте ARC. Також проаналізуйте шаблони навантаження: чи можна планувати обходи дерев у непік?

Mistake 4: Overcommit хостів ВМ без бюджету для ARC

Симптоми: Хост свопить, гості теж balloon; шумні‑сусіди; непередбачувані паузи.

Виправлення: Трактуйте ARC як фіксовану резервацію. Встановіть кап і тримайте його стабільним. Моніторте «available» пам’ять хоста, а не тільки «used».

Mistake 5: Робити зміни, що не зберігаються

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

Виправлення: Збережіть через опції модуля (Linux) або loader/sysctl (FreeBSD) під контролем конфіг‑менеджменту з історією змін.

Mistake 6: Звинувачувати диски, коли правда — reclaim

Симптоми: Звіти «зберігання повільне», але iostat показує низьке завантаження і пристойну латентність. Load високий. Багато задач заблоковані.

Виправлення: Подивіться на vmstat, swap і процеси в D state. Якщо reclaim — питання, налаштування ARC — частина рішення.

Mistake 7: Встановлення занадто великого ARC min

Симптоми: Навіть під тиском ARC відмовляється зменшуватися достатньо; ризик OOM зростає; свопінг продовжується.

Виправлення: Тримайте zfs_arc_min помірним, якщо у вас немає виділеного storage‑апарата з передбачуваними потребами.

Жарт в одне речення №2: Встановити ARC min на «ніколи не зменшувати» — це як прикрутити офісне крісло до підлоги: стабільно, звісно, але тепер ви проводите зустрічі в коридорі.

Поширені питання

1) Скільки оперативної пам’яті віддати ARC?

Універсальної відповіді немає. Почніть з резервування достатньо для ОС і ваших основних робочих навантажень під пік (ВМ, бази даних, JVM). Потім виділіть залишок для ARC з консервативним лімітом. Виділені storage‑машини можуть дозволити собі більший ARC; хости з мішаним використанням — зазвичай ні.

2) Чому сервер показує майже ніякої вільної пам’яті? Чи це погано?

Не обов’язково. Linux агресивно використовує RAM для кешів. Ознака небезпеки — не «мало free», а «мало available» плюс активний swap, затримки reclaim або стрибки латентності.

3) Чи варто відключати swap на системах з ZFS?

Зазвичай ні. Малий контрольований swap може запобігти раптовим OOM. Мета — уникнути активного thrashing. Якщо swap активно використовується при нормальному навантаженні — виправляйте бюджет пам’яті (включно з обмеженнями ARC), а не грайтеся в whack‑a‑mole зі swap.

4) Чи дозволяє додавання L2ARC безпечно зменшити ARC?

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

5) Чому ARC не зменшується одразу після зниження zfs_arc_max?

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

6) Чи відрізняється розмір ARC для HDD-пулів і NVMe?

Так, бо цінність кешу залежить від вартості промаху. Випадкові читання на HDD дорогі; ARC дуже допомагає. NVMe‑промахи дешевші; ARC все ще корисний (особливо для метаданих), але ви можете зіткнутися з обмеженнями CPU або пам’яті перш ніж накопичите проблеми зі сховищем. Не позбавляйте систему пам’яті лише щоб уникнути 200‑мікросекундного NVMe‑читання.

7) Як зрозуміти, чи моє навантаження метаданно‑важке?

Подивіться розподіл ARC (demand metadata bytes vs demand data bytes) і спостерігайте за шаблонами навантаження: багато stat(), обходи директорій, відкриття дрібних файлів, шари контейнерів, інсталяції пакетів. Метаданно‑важкі навантаження виграють від кешування метаданих, але при цьому можуть стрімко роздути ARC.

8) Чи ставити primarycache=metadata для VM dataset?

Не за замовчуванням. Образи VM часто виграють від кешування даних, бо вони повторно читають блоки. Однак для бекапів, архівів або dataset, що записуються одноразово і рідко читаються, primarycache=metadata може повернути RAM без відчутної втрати продуктивності.

9) Який найбезпечніший спосіб змінити ліміти ARC у продакшні?

Змініть zfs_arc_max поступово, під час стабільного навантаження, з чітким планом відкату. Спостерігайте swap, vmstat і латентність принаймні кілька хвилин. Потім зафіксуйте налаштування через конфіг‑менеджмент і заплануйте рев’ю після зміни.

10) Я обмежив ARC і продуктивність погіршала. Я зробив щось не так?

Можливо, або ви просто виявили реальне вузьке місце (диск, мережа, CPU). Якщо латентність читань зросла і диски стали більш навантажені, ARC маскував повільне сховище. Якщо продуктивність погіршилася, але своп припинився, ви обміняли швидкість на стабільність — і це може бути правильним рішенням. Наступний крок — усунути щойно виявлене обмеження замість того, щоб сліпо надувати ARC назад.

Висновок

ARC — це інструмент продуктивності, а не привілей. Воно має боротися за пам’ять, але не повинно перемагати, ламаючи всю іншу систему. Надвеликий ARC не провалюється голосно; воно провалюється бічно — через своп, затримки reclaim, заблоковані задачі і хвостову латентність, які роблять абсолютно здорові диски підозрілими.

Підбирайте розмір ARC так само, як все в продакшні: визначте запас, вимірюйте реальні вузькі місця, робіть невеликі кроки і зберігайте нудні налаштування, які вбережуть вас від дзвінків на інцидент‑брідж. Найкращий кеш — той, що прискорює ваше навантаження, не перетворюючи ОС на суд із арбітражу пам’яті.

← Попередня
Скомпрометовано WordPress: покрокова реакція на інцидент, яка не погіршить ситуацію
Наступна →
Не принизлива сторінка 404: корисні посилання, пошук, легкий гумор

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