ZFS ARC: як ZFS використовує оперативну пам’ять (і чому «вільна пам’ять» — міф)

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

Якщо ви довго експлуатуєте ZFS, рано чи пізно хтось панікуватиме через «зникнення» оперативної пам’яті.
Вам покажуть панель управління, де «вільна пам’ять» практично дорівнює нулю, і скажуть фразу, яку кожен SRE чує вночі:
«ZFS з’їдає всю нашу пам’ять».

Ось суть: ZFS повинен використовувати вашу оперативну пам’ять. ZFS ставиться до пам’яті як до педалі прискорення, а не до музейного експоната.
Хитрість не в тому, щоб тримати пам’ять «вільною». Хитрість у тому, щоб вона була корисною — без голодування додатків, без виклику інтенсивного свапінгу
і без плутання здорового кешування з витоком пам’яті.

ARC в одному реченні

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

Жарт №1: «Вільна пам’ять» — як порожнє місце в літаку: приємно дивитися, але ви все одно за нього платите.

Чому «вільна пам’ять» — міф (в робочих умовах)

В сучасній ОС невикористана пам’ять — це змарнована можливість. Ядро агресивно використовує пам’ять для кешів: файловий кеш,
кеш inode/dentry, slab-виділення та ARC ZFS. Це не примха ZFS; це базова економіка.
ОЗП — найшвидший рівень зберігання, який у вас є.

Плутанина виникає через дашборди та спрощені метрики. Багато графіків досі вважають «використану пам’ять» підозрілою, а
«вільну пам’ять» — безпечною. Це навпаки. Що вам потрібно:

  • Низька активність swap (особливо тривалий swap-in/out).
  • Здорове відновлення сторінок (без трешингу, без OOM kill’ів).
  • Стабільні затримки додатків під навантаженням.
  • Передбачувана поведінка ARC щодо вашого навантаження.

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

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

Що ARC насправді є (і чого він не є)

ARC не є Linux page cache (але конкурує з ним)

Якщо ви на Linux з OpenZFS, у вас фактично працюють дві системи кешування:
Linux page cache і ZFS ARC. ZFS використовує ARC для ZFS-керованого сховища. Linux використовує page cache для файлового I/O
і для всього іншого, що покладається на механізми кешування ядра.

Залежно від навантаження й шляху I/O у вас може з’явитись подвійне кешування або боротьба за пам’ять.
Наприклад, бази даних, які вже реалізують власне кешування, можуть платити за кешування тричі:
кеш додатка, ARC і (іноді) ефекти page cache у контексті direct vs buffered I/O.

ARC адаптивний (і вибагливий щодо того, що зберігати)

ARC — не тупий кеш «запам’ятай останні N блоків». Він використовує алгоритм адаптивної заміни, призначений балансувати:

  • Актуальність: «Я використовував це недавно, можливо, використаю знову».
  • Частота: «Я використовую це повторно протягом часу».

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

ARC кешує метадані, що може важити більше за дані

У багатьох виробничих розгортаннях ZFS кешування метаданих — це різниця між «швидко» і «чому ls зависає?».
Метадані включають dnode’и, непрямі блоки, структури каталогів та різні структури для пошуку.

Якщо ви коли-небудь бачили, як система зберігання падає під «навантаженням дрібних файлів», ви жорстко познайомились з метаданими.
Ви можете мати достатню пропускну здатність диска й все одно застопоритись, тому що система робить pointer-chasing на диску
за метаданими, які мали б бути в RAM.

Що живе в ARC: дані, метадані та речі, що дивують

Блоки даних проти блоків метаданих

ARC містить кешовані блоки вашого пулу. Деякі — це дані файлів. Деякі — метадані.
Співвідношення змінюється залежно від навантаження. Ферма віртуальних машин схильна до багаторазових читань і метаданих; архів медіафайлів
може переважно стрімити великі блоки одноразово; Git-сервер може бути насичений метаданими з піками.

Prefetch може допомогти, а може й підпалити вашу RAM

ZFS робить read-ahead (prefetch) у різних сценаріях. Коли це працює, послідовні читання стають плавною пропускною здатністю.
Коли це промахується — наприклад, коли ваше «послідовне» навантаження насправді є багатьма перемішаними потоками — воно може залити ARC даними,
які не будуть повторно використані.

Реальна наслідок: ви можете викинути корисні метадані, щоб звільнити місце для марних prefetched даних.
Потім все інше сповільнюється, і люди звинувачують «накладні витрати ZFS», коли це насправді забруднення кешу.

Стиснені блоки і помилки в математичних уявленнях про RAM

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

Dedup: «тримай мій пивко» в споживанні RAM

Дедуплікація в ZFS відома тим, що вона одночасно потужна і небезпечна. Таблиця дедуплікації (DDT) потребує швидкого доступу, а
швидкий доступ означає пам’ять. Якщо ви вмикаєте dedup без достатньої RAM для робочого набору DDT, ви можете перетворити систему зберігання
на генератор випадкових I/O з додатковим заробітком у вигляді страждань.

Жарт №2: Включити dedup на боксі, який голодує по RAM, — як усиновити тигра, бо вам потрапила вигідна ціна на корм для кішок.

Як ARC росте, зменшується і іноді відмовляється «відпускати» пам’ять

Розмір ARC — це переговори з ОС

ARC має цільовий діапазон розміру, керований налаштуваннями, такими як zfs_arc_min і zfs_arc_max.
Ядро застосовує тиск, коли іншим підсистемам потрібна пам’ять.
У добре налаштованій системі ARC росте, коли RAM доступна, і зменшується, коли вона потрібна в інших місцях.

У погано зрозумілій системі люди бачать ARC на «максимумі» і припускають, що це витік. Зазвичай це не так.
ARC поводиться за задумом: він знайшов вільну пам’ять і використав її, щоб пришвидшити читання.

Чому ARC іноді не зменшується «достатньо швидко»

Є випадки, коли стиснення ARC може відставати від раптового попиту пам’яті:
раптові сплески контейнерів, розширення heap у JVM, або екстрене розростання page cache для не-ZFS навантаження.
ARC відновлюваний, але не обов’язково миттєво відновлюваний, і шлях від «тиску» до «звільнених байт» може мати затримку.

Коли ця затримка зустрічається з агресивними навантаженнями, ви бачите свапінг, завантаження kswapd на CPU і сплески латентності в хвості.
Ось коли ARC стає політично непопулярним.

Особливий біль віртуалізації та «шумних сусідів»

У конфігураціях гіпервізора (або на великих хостах контейнерів) облік пам’яті стає заплутаним. Гості мають власні кеші.
Хост має ARC. Хост може також мати page cache для інших файлів. Якщо ви передозуете пам’ять або дозволяєте
ballooning/overcommit без запобіжних заходів, ARC стає козлом відпущення провини для фундаментально поганого планування ємності.

Факти та історія: як ми дійшли до цього

  • ZFS народився в Sun Microsystems як дизайн «storage pool + filesystem», а не як доданий менеджер томів.
  • ARC базується на алгоритмі Adaptive Replacement Cache, який покращив просте LRU балансуванням актуальності й частоти.
  • ZFS популяризував наскрізну перевірку контрольних сум для цілісності даних, що збільшує обсяг роботи з метаданими — і робить кешування метаданих ціннішим.
  • Філософія «використовувати RAM як кеш» передує ZFS; Unix-ядра давно використовують вільну пам’ять для кешування, але ZFS зробив це неможливим ігнорувати.
  • Рання порада для ZFS була «RAM — король» частково тому, що диски були повільніші й випадкові I/O були надзвичайно дорогими у порівнянні з RAM.
  • L2ARC (другорядний кеш) з’явився, щоб розширити кеш на швидкі пристрої, але це не безкоштовно: йому потрібні метадані в ARC, щоб бути корисним.
  • Dedup став скандальним бо він перемістив традиційно офлайн-оптимізацію у реальний час, із великим попитом на RAM.
  • OpenZFS приніс ZFS на Linux та інші платформи, де йому довелося співіснувати з різними VM та кеш-підсистемами, змінюючи реалії тонкої настройки.
  • NVMe змінив правила гри: диски стали достатньо швидкими, що погані рішення по кешуванню іноді менш помітні — поки ви не натрапите на хвостову латентність.

Три корпоративні міні-історії

Міні-історія №1: Інцидент, викликаний хибним припущенням («вільна пам’ять — це добре»)

Середня компанія експлуатувала кластер NFS на базі ZFS, який обслуговував домашні директорії та артефакти збірки.
Новий менеджер — розумний, швидкий і недавно навчений на іншому стеку — ввів зміну в «закріплення» пам’яті:
агресивно обмежити ARC, щоб «принаймні 40% RAM залишалось вільним». Це виглядало розумно в таблиці.

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

Симптом, що розгорнув інцидент, не був «високе використання диска». Це був неприємний тип:
зростання iowait, сплески затримок для простих метаданихних операцій і накопичення потоків NFS.
Пул не був перевантажений пропускною спроможністю. Він тону у випадкових читаннях метаданих, які раніше сиділи у ARC.

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

Урок: якщо ви ставитеся до RAM як до трофею, ZFS відноситиметься до ваших дисків як до шкіряного аркуша.

Міні-історія №2: Оптимізація, яка відстрілила назад (L2ARC повсюди)

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

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

Причина була не в SSD. Причина — у пам’яті. L2ARC потребує метаданих в ARC, щоб бути ефективним. Чим більший L2ARC,
тим більше накладних витрат ARC ви витрачаєте на індексацію. На хості, що вже був тісний по RAM, додатковий тиск змусив ARC
частіше витісняти саме ті метадані, які системі були найпотрібніші.

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

Урок: кешування не додається лінійно; це бюджет. Якщо ви витрачаєте його двічі, ви обанкрутієтеся в латентності.

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

Команда фінансових послуг експлуатувала ZFS для пайплайну інжестування файлів. Вони були не найгаласливішою командою, але дисциплінованою.
Їхня практика була болісно нудною: перед будь-яким «налаштуванням» вони збирали базовий набір метрик — статистику ARC, затримки I/O,
активність swap та налаштування per-dataset recordsize/compression. Кожна зміна супроводжувалась порівнянням «до/після».

Одного пополудня латентність інжесту подвоїлася. Легким об’єктом для звинувачення був ARC: «Може, кеш треше». Але їхня база показала інше.
Показник попадань ARC був стабільний. Витіснення не були підозрілими. Змінився тиск пам’яті: був розгорнутий новий sidecar-процес з необмеженим heap’ом.

Система не падала через те, що ARC був жадібним; вона падала через те, що хост був переповнений.
ARC робив усе можливе — зменшувався під тиском — але інший процес продовжував розширюватись, штовхаючи машину в свап.
Їхні графіки показали це чітко: swap-in/out піднявся першим, потім пішла латентність, потім CPU в reclaim.

Виправлення не було якимось загадковим тюнінгом ZFS. Це була ліміт ресурсів і відкат поганого деплойменту.
Нудна практика — збір базових показників і спостереження за правильними індикаторами — врятувала їх від погіршення шляхом сліпого
душіння ARC.

Урок: більшість «проблем пам’яті ZFS» насправді — це системні проблеми пам’яті в масці ZFS.

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

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

Завдання 1: Побачити реальну картину пам’яті (не паніку через «вільну RAM»)

cr0x@server:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:           251Gi       41Gi       2.1Gi       1.2Gi       208Gi       198Gi
Swap:           16Gi          0B        16Gi

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

Завдання 2: Перевірити, чи відбувається свапінг

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 2212140  10240 189512000  0    0    12    44  520  880  6  2 91  1  0
 1  0      0 2198840  10240 189625000  0    0     0     0  500  860  5  2 92  1  0
 4  1      0 2101020  10240 189540000  0    0   220   180 1100 1600 10  4 74 12  0
 3  0      0 2099920  10240 189520000  0    0   140   120  920 1300  8  3 81  8  0
 2  0      0 2103200  10240 189610000  0    0    30    60  600  900  5  2 91  2  0

Інтерпретація: Слідкуйте за si/so (swap in/out). Ненульові стабільні значення означають, що машина під тиском пам’яті.
Невеликий I/O wait (wa) не обов’язково вина ARC; корелюйте з пропусками ARC і затримкою диска.

Завдання 3: Прочитати розмір ARC і ліміти безпосередньо

cr0x@server:~$ grep -E '^(c|size|c_min|c_max|memory_throttle_count)' /proc/spl/kstat/zfs/arcstats
c                             4    214748364800
c_min                         4    10737418240
c_max                         4    214748364800
size                          4    198742182912
memory_throttle_count         4    0

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

Завдання 4: Перевірити попадання/промахи ARC (чи допомагає ARC?)

cr0x@server:~$ grep -E '^(hits|misses|demand_data_hits|demand_data_misses|demand_metadata_hits|demand_metadata_misses)' /proc/spl/kstat/zfs/arcstats
hits                           4    18230933444
misses                         4    1209933221
demand_data_hits               4    12055411222
demand_data_misses             4    902331122
demand_metadata_hits           4    5800122201
demand_metadata_misses         4    307602099

Інтерпретація: Високі hits відносно misses — добре, але не поклоняйтесь коефіцієнту попадань.
Важлива латентність і навантаження диска. «Добрий» коефіцієнт може бути все ще занадто повільним, якщо ваші misses дорогі (випадкові HDD-зчитування),
а «поганий» коефіцієнт може бути прийнятним, якщо ваш пул на NVMe і ваше навантаження стрімить.

Завдання 5: Спостерігати ARC в реальному часі за допомогою arcstat (якщо встановлено)

cr0x@server:~$ arcstat 1 5
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
12:01:01   812    42      5    30   4     8   1     4   0   185G   200G
12:01:02   900    55      6    40   4    10   1     5   1   185G   200G
12:01:03  1100   220     20   190  17    18   2    12   1   184G   200G
12:01:04   980   180     18   150  15    20   2    10   1   184G   200G
12:01:05   860    60      7    45   5    10   1     5   1   184G   200G

Інтерпретація: Сплеск misses під час пакетного скану нормальний. Постійна буря misses у «стаді спокою»
часто означає, що ваш робочий набір не поміщається, preftech-забруднення або зміна навантаження (новий dataset, новий патерн доступу).

Завдання 6: Перевірити стрес від відновлення пам’яті (Linux)

cr0x@server:~$ cat /proc/pressure/memory
some avg10=0.00 avg60=0.05 avg300=0.12 total=1843812
full avg10=0.00 avg60=0.00 avg300=0.00 total=0

Інтерпретація: PSI memory «some» вказує на час, витрачений у стані блокувань через тиск пам’яті; «full» — гірше (задачі повністю заблоковані).
Зростаючий PSI разом зі свап-активністю і ARC на капі — сигнал переглянути бюджети пам’яті.

Завдання 7: Підтвердити здоров’я пулу та очевидні вузькі місця

cr0x@server:~$ zpool status -xv
all pools are healthy

Інтерпретація: Не тонюйте кеші на хворому пулі. Якщо у вас є помилки, resilvering або деградовані vdev’и, ваша «проблема ARC»
може бути «проблемою апаратного забезпечення».

Завдання 8: Спостерігати затримку I/O, а не лише пропускну здатність

cr0x@server:~$ zpool iostat -v 1 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
tank                        48.2T  21.6T   8200   1100   690M   120M
  raidz2-0                   48.2T  21.6T   8200   1100   690M   120M
    sda                          -      -   1020    130    85M    10M
    sdb                          -      -   1015    135    86M    11M
    sdc                          -      -   1040    140    86M    10M
    sdd                          -      -   1030    135    85M    10M

Інтерпретація: Це показує операції і пропускну здатність, але не затримку. Якщо «все відчувається повільно», комбінуйте це з інструментами на кшталт
iostat -x, щоб побачити await/util, і корелюйте з пропусками ARC.

Завдання 9: Перевірити затримку пристрою за допомогою iostat

cr0x@server:~$ iostat -x 1 3
Device            r/s     w/s   rMB/s   wMB/s  rrqm/s  wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm  %util
sda            1020.0   130.0    85.0    10.0     0.0     8.0   0.00   5.80   9.10   6.20   9.50    85.3    79.1  0.40  46.0
sdb            1015.0   135.0    86.0    11.0     0.0     9.0   0.00   6.20   9.40   6.10   9.60    86.7    83.1  0.41  46.5

Інтерпретація: Зростаючі r_await і високий %util під час сплесків misses ARC означають, що ваші диски платять за промахи кешу.
Якщо затримка вже низька (наприклад, NVMe), промахи ARC можуть бути не головним злочинцем.

Завдання 10: Визначити, які датасети налаштовані на дорожчу поведінку

cr0x@server:~$ zfs get -o name,property,value -s local,received recordsize,primarycache,secondarycache,compression tank
NAME  PROPERTY        VALUE
tank  compression     lz4
tank  primarycache    all
tank  recordsize      128K

Інтерпретація: primarycache=all означає, що і дані, і метадані кешуються в ARC.
Для деяких навантажень (бази даних, великі стріми) ви можете обрати metadata, щоб зменшити тиск на ARC.
Не робіть цього зі страху — виміряйте.

Завдання 11: Перевірити, чи навантаження обходить очікування кешу

cr0x@server:~$ zfs get -o name,property,value atime,sync,logbias,primarycache tank/vmstore
NAME         PROPERTY     VALUE
tank/vmstore atime        off
tank/vmstore sync         standard
tank/vmstore logbias      latency
tank/vmstore primarycache all

Інтерпретація: Налаштування, як-от sync і logbias, безпосередньо не змінюють ARC, але змінюють поведінку I/O.
Якщо записи повільні і створюють зворотний тиск, читання можуть постраждати, і «дебати навколо ARC» стануть відволіканням.

Завдання 12: Тимчасово встановити ліміт ARC (обережно) для експериментів

cr0x@server:~$ sudo sh -c 'echo $((64*1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max'
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_arc_max
68719476736

Інтерпретація: Це встановлює zfs_arc_max в 64 GiB (значення в байтах). Використовуйте це, щоб перевірити гіпотези щодо запасу пам’яті, а не як постійне «рішення».
Постійні налаштування слід робити через конфігурацію параметрів модуля дистрибутива, щоб зберегти їх після перезавантаження.

Завдання 13: Змусити питання — чи залежить продуктивність від розміру ARC або від затримки диска?

cr0x@server:~$ sudo sh -c 'echo $((128*1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max'
cr0x@server:~$ sleep 10
cr0x@server:~$ grep -E '^(size|c|c_max)' /proc/spl/kstat/zfs/arcstats
c                             4    137438953472
c_max                         4    137438953472
size                          4    132001234944

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

Завдання 14: Знайти пов’язані з ARC повідомлення ядра

cr0x@server:~$ dmesg -T | grep -i -E 'arc|spl|zfs' | tail -n 10
[Thu Dec 25 09:44:10 2025] ZFS: Loaded module v2.2.4-1
[Thu Dec 25 10:02:31 2025] ZFS: ARC size 197G, target 200G, min 10G, max 200G

Інтерпретація: Шукайте попередження про throttling пам’яті, помилки алокації або повторювані події відновлення.
Якщо логи галасливі, ви перейшли від «ARC великий» до «ARC воює з ядром».

Завдання 15: Визначити, чи ваше навантаження домінує метаданими

cr0x@server:~$ grep -E '^(demand_metadata_hits|demand_metadata_misses|demand_data_hits|demand_data_misses)' /proc/spl/kstat/zfs/arcstats
demand_data_hits               4    12055411222
demand_data_misses             4    902331122
demand_metadata_hits           4    5800122201
demand_metadata_misses         4    307602099

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

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

Коли вам пишуть «ZFS використовує всю RAM» або «ZFS повільний», у вас немає часу на філософські дискусії.
Потрібна коротка, надійна послідовність, яка швидко знайде вузьке місце.

Крок 1: Чи хост під тиском пам’яті або просто кешує?

  • Перевірте free -h і зосередьтесь на полі available, а не на free.
  • Перевірте vmstat 1 на предмет тривалих si/so > 0.
  • Перевірте PSI пам’яті (/proc/pressure/memory) на предмет зростання «some/full».

Якщо свап активний і PSI зростає, у вас проблема тиску пам’яті. ARC може бути причетним, але рідко — єдиним актором.

Крок 2: Чи повільні читання через промахи ARC, чи диски вже повільні?

  • Перевірте попадання/промахи ARC (/proc/spl/kstat/zfs/arcstats або arcstat).
  • Перевірте затримку диска (iostat -x 1) і поведінку пулу (zpool iostat 1).

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

Крок 3: Чи змінює робоче навантаження економіку кешу?

  • Шукайте великі сканування, бекапи, реіндексацію, ранкові бум-картки VM або реплікацію.
  • Визначте, чи зросли промахи метаданих (дрібні файли, мільйони inode’ів).
  • Перегляньте властивості датасету: primarycache, recordsize, compression, sync/logbias.

Багато «інцидентів ARC» насправді — «сталося пакетне завдання». Ваша реакція має бути ізолювати або запланувати пакетну задачу, а не назавжди калічити кеш.

Крок 4: Рішення: налаштувати ліміти ARC, змінити навантаження чи додати RAM

  • Якщо хост свапить: зарезервуйте запас (cap ARC) і виправте процес-споживач пам’яті.
  • Якщо диски насичені промахами: збільшуйте ефективний кеш (більше RAM, краща політика кешування, зменшення забруднення).
  • Якщо латентність в порядку: перестаньте чіпати це і переходьте до справжнього вузького місця.

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

Контрольний список A: «Чи шкодить ARC моїм додаткам?»

  1. Підтвердьте активність свапу:
    cr0x@server:~$ vmstat 1 10

    Шукайте тривалі si/so і зростаючий wa.

  2. Підтвердьте доступність пам’яті:
    cr0x@server:~$ free -h

    Якщо available низький і падає, у вас фактично не вистачає пам’яті.

  3. Перевірте кап і розмір ARC:
    cr0x@server:~$ grep -E '^(size|c_max|c_min|memory_throttle_count)' /proc/spl/kstat/zfs/arcstats

    Якщо ARC на капі і memory_throttle_count зростає, розгляньте зміни запасу.

  4. Корелюйте з латентністю додатків та логами OOM:
    cr0x@server:~$ dmesg -T | tail -n 50

    Якщо бачите OOM kills, розміри ARC — не корінь проблеми; це передозування.

Контрольний список B: «Чи ARC занадто малий для цього навантаження?»

  1. Виміряйте промахи ARC у вікні скарги:
    cr0x@server:~$ arcstat 1 30

    Постійні misses під час нормального навантаження — тривожний знак.

  2. Перевірте затримку диска одночасно:
    cr0x@server:~$ iostat -x 1 30

    Якщо awaits зростають під час бурі misses, пул платить за це.

  3. Протестуйте контрольоване збільшення zfs_arc_max (якщо є запас):
    cr0x@server:~$ sudo sh -c 'echo $((192*1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max'

    Дивіться, чи покращується латентність і падають misses. Якщо так — вирішення зазвичай «більше RAM або краща ізоляція».

Контрольний список C: «Тримати метадані теплими, зупинити забруднення кешу»

  1. Виявте сканоподібні задачі (backup, scrub, rsync, reindex) і заплануйте їх в непіковий час.
  2. Розгляньте primarycache=metadata для стрімових датасетів, які не отримують вигоди від кешування даних:
    cr0x@server:~$ sudo zfs set primarycache=metadata tank/archive

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

  3. Підтвердіть зміни статистикою ARC: промахи метаданих повинні впасти; IOPS диска мають стабілізуватись.

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

Помилка 1: Оповіщення по «вільній RAM»

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

Виправлення: Оповіщуйте про активність свапу (vmstat si/so), PSI пам’яті «full», OOM-події і затримки додатків.
Використовуйте поле «available», а не «free», у дашбордах.

Помилка 2: Обмеження ARC без вимірювання навантаження

Симптоми: Стрибок IOPS диска, уповільнення метаданихних операцій, «все відчувається повільним» у піку.

Виправлення: Відновіть розумний кап ARC; виміряйте промахи ARC і затримки диска.
Якщо потрібно місце для додатків, обмежуйте ARC на основі бюджету (додатки + ядро + запас), а не відсотка «вільної» пам’яті.

Помилка 3: Вважати коефіцієнт попадань ARC KPI

Симптоми: Люди святкують високий hit rate, поки хвостова латентність жахлива; або панікують через низький hit rate при стрімінгових навантаженнях.

Виправлення: Пріоритет — латентність і здоров’я свапу. Коефіцієнт попадань залежить від контексту.
Медіа-стрімер може мати низький hit rate і все одно бути швидким; метаданихний NFS-сервер — ні.

Помилка 4: Увімкнути dedup через «збереження місця»

Симптоми: Раптове падіння продуктивності, багато випадкових читань, тиск пам’яті, повільні записи, накладні витрати DDT.

Виправлення: Не вмикайте dedup без реальної моделі ємності/продуктивності та бюджету по пам’яті.
Якщо вже увімкнено і є проблеми, плануйте міграцію; «вимкнути» не є миттєвим для існуючих блоків.

Помилка 5: Кидати L2ARC на проблему на системі з дефіцитом RAM

Симптоми: Немає покращення або гірша латентність; тиск на ARC зростає; промахи метаданих не зникають.

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

Помилка 6: Ігнорувати шлях запису і звинувачувати ARC

Симптоми: Читання іноді повільні, але справжній тригер — синхронні записи, commit-затримки або насичений SLOG/write vdev.

Виправлення: Вимірюйте end-to-end: zpool iostat, затримку пристрою і шаблони записів додатка.
Виправте вузькі місця шляху запису; не маніпулюйте ARC, щоб компенсувати їх.

Помилка 7: Запускати змішані навантаження без ізоляції

Симптоми: Бекапи ламають інтерактивні навантаження; ранкові завантаження VM давлять файлові сервіси; churn кешу.

Виправлення: Ізолюйте навантаження по хостах, пулах або за графіком. Використовуйте політику кешу на рівні датасету там, де потрібно.
Розгляньте cgroups для обмеження пам’яті для «шумних» сервісів на Linux.

FAQ

1) Це погано, якщо ZFS використовує більшість моєї RAM?

Не саме по собі. Це погано, якщо система свапить, агресивно відновлює пам’ять (високе PSI «full») або додатки втрачають пам’ять і сповільнюються.
Якщо «available» пам’яті достатньо і свап тихий, використання RAM ARC — зазвичай функція.

2) Чому ARC не звільняє пам’ять миттєво, коли додатку потрібно?

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

3) Чи слід встановлювати zfs_arc_max на кожній системі?

Якщо хост виконує тільки ZFS-навантаження (наприклад, виділений NAS), значення за замовчуванням часто підходять.
Якщо це змішаний хост (бази даних, JVM, контейнери), встановлення капа може запобігти несподіваному конфлікту.
Правильна відповідь — бюджет пам’яті: що ваші додатки потребують у піку, плюс запас безпеки, плюс те, що ви можете виділити для ARC.

4) Який «добрий» коефіцієнт попадань ARC?

Залежить від навантаження. Для стрімінгових читань низький коефіцієнт може все ще забезпечувати високу пропускну здатність.
Для випадкових читань і навантажень, насичених метаданими, низький коефіцієнт зазвичай означає реальні проблеми.
Слідкуйте за трендами hits/misses і корелюйте з затримкою диска та видимою для користувача латентністю.

5) Чи ARC те саме, що L2ARC?

Ні. ARC знаходиться в RAM. L2ARC — це вторинний кеш на швидкому сховищі (SSD/NVMe). L2ARC може розширити кеш,
але йому потрібна RAM для метаданих і він мало допомагає для одноразових читань.

6) Якщо додати більше RAM, чи завжди ZFS стане швидшим?

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

7) Чому система показує низьку «вільну» пам’ять, навіть коли проста?

Бо ОС використовує RAM для кешів, щоб пришвидшити майбутню роботу. Простоюча система з великою кількістю кешу — нормальна.
Зосередьтесь на «available» пам’яті і свапі, а не на «free».

8) Чи можу я налаштувати ZFS так, щоб кешував лише метадані?

Так, на рівні датасету за допомогою primarycache=metadata. Це корисно для датасетів зі стрімовими читаннями,
які не отримують вигоди від кешування даних, але при цьому потребують швидкого обходу каталогів і пошуку файлів.
Виміряйте до і після — це може зіграти зворотний ефект для навантажень, що дійсно повторно використовують дані.

9) Як визначити, чи ARC треше?

Шукайте тривалі високі промахи ARC під час стабільного навантаження, зростаючу поведінку витіснення і сплески затримки диска, які корелюють з промахами.
Якщо система також свапить, ви можете потрапити в порочне коло: тиск викликає churn ARC, що збільшує I/O, що підвищує латентність.

10) Чому продуктивність впала відразу після великого бекапу або scrub?

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

Висновок

ZFS ARC — не витік пам’яті в одежі файлової системи. Це свідомий дизайн: використати RAM, щоб уникнути дискового I/O,
і адаптуватись до того, що робить робоче навантаження. Операційна помилка — вважати «вільну RAM» метрикою здоров’я і
трактувати розмір ARC як моральну невдачу.

Коли продуктивність погана, не сперечайтесь про філософію — вимірюйте. Перевірте тиск пам’яті, свап, промахи ARC,
затримку диска і визначте навантаження, що змінило гру. Потім вирішіть: обмежити ARC для запасу, налаштувати датасети
щоб уникнути забруднення, ізолювати навантаження або купити більше RAM. Найкращий тюнінг ZFS зазвичай простий:
дайте ARC робити свою роботу і переконайтесь, що решта системи не саботує її.

← Попередня
Ubuntu 24.04 завантажується в чорний екран або цикл перезавантажень: 6 виправлень
Наступна →
Електронна пошта «Адресу відправника відхилено»: виправлення автентифікації та політик

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