EPYC: як AMD перетворила сервери на шоурум

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

Ви купуєте сервер, очікуючи, що він працюватиме як надійний прилад: передбачувана латентність, нудні графіки, без сюрпризів опівночі.
Потім ви ставите в стійку коробку з AMD EPYC, запускаєте кілька десятків VM, додаєте NVMe — і раптом ваш тур по дата‑центру звучить як прогулянка по салону автомобілів:
«Подивіться на ці ядра. Подивіться на лінії. Подивіться на канали пам’яті».

Проблема в тому, що шоуруми оптимізовані під ефект «вау». Продакшн оптимізовано під «щоб нічого дивного не траплялося».
EPYC може поєднувати обидва підходи, але лише якщо ви розумієте, що він змінив у дизайні серверів — і де гострі краї, коли ваш робочий навантаження зустрічається з NUMA, топологією PCIe
та стеком зберігання, який ніколи не просив так багато паралельних черг.

Чому EPYC зробив сервери іншими

EPYC не просто дав операторам більше ядер. Він змінив уявлення про «збалансований» сервер. Довгий час дизайн серверів був низкою компромісів, які всі приймали:
недостатньо ліній PCIe, канали пам’яті швидко заповнювалися, і CPU змушували переходити на дорогі двопроцесорні конфігурації лише заради I/O.

EPYC з’явився і зробив одно-роз’ємні сервери більш привабливими, ніж варіант для економії. Більше ліній PCIe означало, що
ви могли підключити серйозні NVMe без гри в тетріс. Більше каналів пам’яті означало, що ви могли годувати ті ядра без миттєвого голодування по пропускній здатності.
А підхід з чіплетами дозволив AMD збільшувати кількість ядер без монолітного кристала розміром з ваше розчарування.

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

Факти й контекст, що пояснюють зсув

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

  1. 2017 — точка перелому: EPYC «Naples» (1‑ше покоління) з’явився і змусив покупців переглянути щільність в одному роз’ємі як серйозний вибір.
  2. Чіплети стали мейнстримом у серверах: мульти‑кристальна конструкція EPYC нормалізувала ідею, що латентність і локальність важливіші за «один великий кристал».
  3. Канали пам’яті знову стали критерієм при закупівлі: широкі конфігурації пам’яті EPYC винесли «пропускну здатність пам’яті за долар» на наради керівництва.
  4. Кількість ліній PCIe перестала бути дрібницею: платформи з великою кількістю ліній дозволили більше NVMe і NIC без додаткових CPU.
  5. Rome (2‑ге покоління) агресивно підняв кількість ядер: коли ядра ростуть, ліцензування ПЗ і накладні витрати на ядро стають операційними ризиками, а не лише статтями бюджету.
  6. Milan (3‑є покоління) покращив латентність та IPC: справа була не лише в кількості ядер; покращення однопоточної поведінки важили для баз даних і контрольних площин.
  7. Genoa (4‑те покоління) знову підняв планку I/O: DDR5 та PCIe Gen5 підвищили верхню межу, але зробили рішення по розводці й охолодженню більш критичними.
  8. Провайдери хмари підтвердили це публічно: великі розгортання дали сигнал «це не нішево», а це важливо, коли ви інвестуєте в екосистему прошивок, плат і підтримки.

Архітектура, якою можна користуватися (чіплети, NUMA, I/O)

Чіплети: те, що всі повторюють, і те, що має значення

«Чіплети» продають як стиль життя. У продакшні це історія про топологію. Кілька обчислювальних кристалів (CCD) підключені до I/O‑кристала,
і ваші потоки, алокації пам’яті та переривання тепер беруть участь у уроці географії. CPU вже не одне «сусідство»;
це місто з мостами.

Це впливає на три речі, які не можна ігнорувати:

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

NUMA: його не можна «вимкнути», можна тільки зневажити

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

Платформи EPYC зазвичай показують кілька NUMA‑вузлів на сокет залежно від налаштувань, як‑от NPS (NUMA per socket) і того, як ядро перераховує I/O.
Ви можете налаштувати менше NUMA‑доменів (простіше планування, потенційно вища локальна конкуренція) або більше доменів (більше можливостей локальності,
більше складності).

I/O‑кристал і надлишок ліній: прихований капкан

EPYC зробив I/O виглядати «вирішеним», бо можна підключити багато пристроїв. Але «кількість ліній» — це не те саме, що «I/O без конкуренції».
Комутатори, біфуркація, налаштування прошивки та маршрутизація переривань у ядрі все ще можуть перетворити чудову топологію на паркувальний майданчик.

Інший капкан — психологічний: команди починають підключати все підряд, бо можуть. Більше NVMe. Більше NIC. Більше HBA «на всякий випадок».
Платформа стає експериментом зі спільною шиною, і ви здивуєтесь, що QoS важко забезпечити.

Жарт №1: Сервер з 128 лініями — не «захищений від майбутнього». Це «захищений від спокуси майбутнього», і більшість з нас не витримує тесту.

Віртуалізація й консолідація: добре, дивно, виправно

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

Щільність ядер змінює режими відмов

Коли ви переходите з «кількох десятків потоків» до «сотень готових потоків», ваші вузькі місця зміщуються:

  • CPU не завжди ліміт; ліміт — пропускна здатність пам’яті. Особливо для аналітики, стиснення, шифрування та стеків зберігання, які багато копіюють.
  • Обробка переривань знову важлива. Швидка NIC з поганою IRQ‑афініті може виглядати як проблема CPU, поки ядра крутяться в softirq.
  • Контенція локів стає видимою. Часте програмне забезпечення масштабується до 64 ядер, а потім падає при 96, бо один глобальний лок перетворюється на турнікет.

Ліцензування та реалії «за ядро»

Ваша команда закупівель любитиме високі кількості ядер, поки не почне платити. Деяке корпоративне ПЗ досі цінить за ядро, за сокет,
за vCPU або з формулами, які створювалися, щоб зробити вас нещасними. EPYC полегшує купівлю більше обчислень, ніж ви можете раціонально ліцензувати.

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

Коли pinning корисний, а коли це косплей

Прикріплення CPU і NUMA — потужні інструменти. Вони також відмінний спосіб перетворити платформу віртуалізації на вручну підтримувану таблицю, яка ламається щоразу, коли додається NIC.

Pinning варто використовувати коли:

  • у вас латентнісно чутливі робочі навантаження (торгівельні системи, майже реального часу контрольні площини, певні бази даних)
  • у вас виділені хости для невеликої кількості великих VM
  • ви можете забезпечити послідовне розміщення і контролювати зсув хостів

Pinning зазвичай помилка коли:

  • середовище дуже динамічне (автоматичне масштабування, часті евакуації)
  • робоче навантаження орієнтоване на пропускну здатність і терпить варіації
  • команда не має спостереження за NUMA‑промахами і гарячими точками переривань

Сховище та PCIe: лінії не рівні пропускній здатності

Найпоширеніша історія EPYC у сфері зберігання проста: «Ми підключили багато NVMe і очікували лінійного масштабування.» Іноді його отримують.
Часто ж — бачать плоску криву. Плато — не моральна невдача. Це комбінація:

  • NUMA‑локальність (ваші NVMe‑переривання обробляються далеко від прикладних потоків)
  • топологія PCIe (uplink комутаторів, біфуркація, over‑subscription)
  • глибина черг та вибір планувальника I/O
  • поведінка файлової системи та RAID/ZFS при змішаних навантаженнях
  • взаємодія мережевого/сховищного стеку (особливо в Ceph, iSCSI, NVMe‑oF)

Паралелізм NVMe: CPU стає частиною шляху зберігання

NVMe швидкий, бо він паралельний. Це означає більше черг, більше переривань, більше CPU в роботі ядра.
На EPYC у вас достатньо ядер, щоб кинути їх на це — але ви все ще маєте розмістити цю роботу близько до правильного NUMA‑вузла,
і впевнитися, що ви не обмежені однією чергою, одним IRQ або одним CPU, який обробляє softirq.

Пропускна здатність пам’яті: мовчазний ліміт для сховища

Високошвидкісне сховище часто перетворюється на питання «наскільки швидко ми можемо переміщувати пам’ять». Контрольні суми, стиснення, шифрування, реплікація
і навіть просте копіювання можуть наситити пропускну здатність пам’яті задовго до того, як «використання CPU» виглядатиме страшно. Канали пам’яті EPYC допомагають,
але ви все одно можете голодувати, якщо ставите по одній DIMM на канал, змішуєте швидкості або неправильно конфігуруєте налаштування BIOS живлення.

Цитата про надійність (перефразована ідея)

Werner Vogels (перефразована ідея): «Все ламається постійно — проектуйте й експлуатуйте, якби це було за замовчуванням.»

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

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

Завдання 1: Підтвердити модель CPU, сокети та розклад ядер

cr0x@server:~$ lscpu
Architecture:                         x86_64
CPU op-mode(s):                       32-bit, 64-bit
CPU(s):                               128
Thread(s) per core:                   2
Core(s) per socket:                   64
Socket(s):                            1
NUMA node(s):                         4
Vendor ID:                            AuthenticAMD
Model name:                           AMD EPYC 9554 64-Core Processor
L3 cache:                             256 MiB
NUMA node0 CPU(s):                    0-31
NUMA node1 CPU(s):                    32-63
NUMA node2 CPU(s):                    64-95
NUMA node3 CPU(s):                    96-127

Що це означає: У вас один сокет, але чотири NUMA‑вузли. Це рішення топології, а не просто факт.

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

Завдання 2: Перевірити відстань NUMA (локально vs віддалено)

cr0x@server:~$ numactl --hardware
available: 4 nodes (0-3)
node 0 cpus: 0-31
node 0 size: 192000 MB
node 0 free: 121500 MB
node 1 cpus: 32-63
node 1 size: 192000 MB
node 1 free: 118200 MB
node 2 cpus: 64-95
node 2 size: 192000 MB
node 2 free: 119100 MB
node 3 cpus: 96-127
node 3 size: 192000 MB
node 3 free: 120900 MB
node distances:
node   0   1   2   3
  0:  10  12  12  12
  1:  12  10  12  12
  2:  12  12  10  12
  3:  12  12  12  10

Що це означає: Доступ до віддаленої пам’яті дорожчий за локальний (відстань 12 проти 10). Не катастрофа, але реальна різниця.

Рішення: Для баз даних і демонів зберігання вирівняйте CPU/пам’ять по вузлу і намагайтеся тримати I/O‑переривання локальними.

Завдання 3: Перевірити швидкість пам’яті та заселення DIMM

cr0x@server:~$ sudo dmidecode -t memory | egrep -i 'Locator:|Size:|Speed:|Configured Memory Speed:'
Locator: DIMM_A1
Size: 64 GB
Speed: 4800 MT/s
Configured Memory Speed: 4800 MT/s
Locator: DIMM_B1
Size: 64 GB
Speed: 4800 MT/s
Configured Memory Speed: 3600 MT/s

Що це означає: Один DIMM знижується в частоті (сконфігурований на 3600). Це може тягнути за собою всю підсистему пам’яті.

Рішення: Виправте правила заселення (взаємопідходящі DIMM, правильні слоти). Не бенчмаркуйте, поки пам’ять не працює на очікуваній швидкості.

Завдання 4: Перевірити поведінку частоти CPU під навантаженням

cr0x@server:~$ sudo turbostat --Summary --quiet --show Busy%,Bzy_MHz,IPC,IRQ,POLL --interval 1 --num_iterations 3
Busy%  Bzy_MHz  IPC   IRQ   POLL
38.45  2850     1.35  6200  0
92.10  2975     1.02  18900 0
91.88  2400     0.98  20100 0

Що це означає: Частота падає при високому Busy% (термо/енергетична/політика прошивки). IPC теж падає, що вказує на пам’яткові стаги або контенцію.

Рішення: Перевірте профіль живлення в BIOS, охолодження та Linux‑governor. Якщо важлива пропускна здатність, уникайте консервативних налаштувань живлення.

Завдання 5: Перевірити драйвер/губернатор частоти CPU в Linux

cr0x@server:~$ cpupower frequency-info
analyzing CPU 0:
  driver: amd-pstate-epp
  CPUs which run at the same hardware frequency: 0
  available cpufreq governors: performance powersave
  current policy: frequency should be within 400 MHz and 3700 MHz.
                  The governor "powersave" may decide which speed to use
  current CPU frequency: 1580 MHz (asserted by call to hardware)

Що це означає: Ви в режимі powersave. На сервері з реальною роботою це часто буває випадково.

Рішення: Для критичних хостів визначте performance і підтвердіть, що терміки прийнятні.

Завдання 6: Підтвердити топологію PCIe і ширину лінків

cr0x@server:~$ lspci -tv
-[0000:00]-+-00.0  Advanced Micro Devices, Inc. [AMD] Device 14xx
           +-01.1-[01]----00.0  Samsung Electronics Co Ltd NVMe SSD Controller
           +-01.2-[02]----00.0  Samsung Electronics Co Ltd NVMe SSD Controller
           +-03.0-[03]----00.0  Mellanox Technologies MT28908 Family [ConnectX-6]
           \-04.0-[04]----00.0  Broadcom / LSI SAS3008 PCI-Express Fusion-MPT SAS-3

Що це означає: Пристрої на різних root‑портах — хороший знак. Але все одно потрібно перевірити погоджену швидкість/ширину лінка.

Рішення: Якщо NVMe домовився про x2 замість x4 (або Gen3 замість Gen4/5) — виправте кабелі/бекплейн/біфуркацію/BIO S перед тим, як звинувачувати ПЗ.

Завдання 7: Перевірити погоджену швидкість/ширину PCIe для пристрою

cr0x@server:~$ sudo lspci -s 01:00.0 -vv | egrep -i 'LnkCap:|LnkSta:'
LnkCap: Port #0, Speed 16GT/s, Width x4, ASPM L1, Exit Latency L1 <16us
LnkSta: Speed 8GT/s (downgraded), Width x4

Що це означає: Підтримує Gen4 (16GT/s), але працює на Gen3 (8GT/s). Це вдвічі зменшує пропускну здатність.

Рішення: Перевірте налаштування PCIe в BIOS, бекплейн, ретаймери та прошивки. Не «оптимізуйте» ядро, щоб компенсувати фізичне пониження.

Завдання 8: Виявити розподіл черг NVMe та переривань

cr0x@server:~$ cat /proc/interrupts | egrep 'nvme|mlx5' | head
  95:   1200331   0   0   0   IR-PCI-MSI 524288-edge nvme0q0
  96:    903221   0   0   0   IR-PCI-MSI 524289-edge nvme0q1
  97:    910554   0   0   0   IR-PCI-MSI 524290-edge nvme0q2
 110:   3321100   0   0   0   IR-PCI-MSI 327680-edge mlx5_comp0

Що це означає: Всі переривання потрапляють на CPU0 (перший стовпець) — класичний вбивця продуктивності.

Рішення: Увімкніть/перевірте irqbalance або прив’яжіть IRQs до локального NUMA‑вузла для пристрою. Часто це «безкоштовний» виграш по латентності.

Завдання 9: Перевірити локальність NIC та асоціацію NUMA

cr0x@server:~$ for dev in /sys/class/net/enp*; do echo -n "$(basename $dev) "; cat $dev/device/numa_node; done
enp65s0f0 2
enp65s0f1 2

Що це означає: NIC приєднана до NUMA‑вузла 2. Якщо ваше навантаження працює на вузлі 0 з пам’яттю на вузлі 0, ви платите за відстань.

Рішення: Для високопропускного мережевого навантаження (Ceph, NVMe‑oF, реплікація) розміщуйте мережеві потоки поруч із NUMA‑вузлом NIC.

Завдання 10: Виявити тиск на пропускну здатність пам’яті через perf‑лічильники

cr0x@server:~$ sudo perf stat -a -e cycles,instructions,cache-misses,dTLB-load-misses -I 1000 -- sleep 3
#           time             counts unit events
     1.000233062     5,210,332,110      cycles
     1.000233062     3,101,229,884      instructions
     1.000233062        92,110,553      cache-misses
     1.000233062         1,020,112      dTLB-load-misses
     2.000472981     5,401,223,019      cycles
     2.000472981     3,002,118,991      instructions
     2.000472981       120,004,221      cache-misses
     2.000472981         1,230,888      dTLB-load-misses

Що це означає: Зростання cache‑misses + падіння instructions per cycle натякає на тиск пам’яті або погану локальність.

Рішення: Подивіться на NUMA‑розміщення, huge pages, поведінку алокатора і локальність структури даних перед тим, як додавати ще ядра.

Завдання 11: Перевірити насичення дискового I/O і черги

cr0x@server:~$ iostat -x 1 3
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          22.10    0.00    9.20    3.10    0.00   65.60

Device            r/s     w/s   rMB/s   wMB/s  avgrq-sz avgqu-sz await  svctm  %util
nvme0n1        1200.0  800.0   420.0   310.0     620.0     9.80  6.20  0.35  99.8

Що це означає: Пристрій ~100% зайнятий і черга висока (avgqu‑sz). Await 6.2ms — високо для NVMe під таким навантаженням.

Рішення: Або пристрій насичений (нормально), або у вас проблема з перериваннями/NUMA, що змушує виглядати як насичення. Корелюйте з перериваннями і CPU softirq.

Завдання 12: Перевірити навантаження CPU через функції файлової системи чи ZFS (приклад: ZFS)

cr0x@server:~$ sudo zpool iostat -v 1 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
tank                        12.1T  10.7T   9800   6200   1.1G   820M
  mirror-0                  12.1T  10.7T   9800   6200   1.1G   820M
    nvme-SAMSUNG_MZQLB1T9-0     -      -   4900   3100   560M   410M
    nvme-SAMSUNG_MZQLB1T9-1     -      -   4900   3100   560M   410M

Що це означає: Високі операції і пропускна здатність; якщо CPU також високо завантажений, функції ZFS (стиснення, контрольні суми) можуть створювати завантаження CPU, а не диск‑бандл.

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

Завдання 13: Виявити перевантаження softirq (мережевий/сховищний шлях)

cr0x@server:~$ mpstat -P ALL 1 2 | head -n 20
Linux 6.5.0 (server)  01/10/2026  _x86_64_  (128 CPU)

01:01:10 PM  CPU   %usr  %nice  %sys %iowait  %irq  %soft  %steal  %idle
01:01:11 PM  all  18.20   0.00  12.30    2.10  0.90  15.40    0.00  51.10
01:01:11 PM    0   2.00   0.00   5.00    0.00  0.00  70.00    0.00  23.00

Що це означає: CPU0 тоне в softirq. Це збігається з «всі переривання на CPU0».

Рішення: Виправте афініті IRQ. Якщо ви використовуєте DPDK або busy polling — перевірте конфігурацію і переконайтеся, що це навмисно.

Завдання 14: Перевірити експозицію топології віртуалізації (приклад KVM/QEMU)

cr0x@server:~$ virsh capabilities | egrep -n 'topology|numa|cells' | head
115:      <topology sockets='1' dies='1' clusters='1' cores='64' threads='2'/>
132:      <cells num='4'>
133:        <cell id='0'>

Що це означає: Хост має 4 NUMA‑вузли. Вашим VM можна виставити відповідність (або залишити невідповідними).

Рішення: Для великих VM відкривайте NUMA гостю і вирівнюйте vCPU/пам’ять. Для маленьких VM тримайте простоту, якщо не бачите вимірюваної вигоди.

Завдання 15: Перевірити свідчення термального/енергетичного обмеження

cr0x@server:~$ sudo journalctl -k --since "1 hour ago" | egrep -i 'thrott|powercap|edac|mce' | tail
Jan 10 12:35:22 server kernel: amd_pstate: limiting max performance due to platform profile
Jan 10 12:41:07 server kernel: EDAC amd64: ECC error detected on CPU#0 Channel:1 DIMM:0

Що це означає: Профіль платформи обмежує продуктивність, і у вас також є ECC‑помилки. Обидва можуть проявлятися як «випадкова повільність».

Рішення: Спочатку виправте терміки/профіль живлення; негайно замініть або пересадіть проблемні DIMM. Налаштування продуктивності на ненадійній пам’яті — самопошкодження.

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

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

По‑перше: розділіть «насичення ресурсів» від «топології/патології»

  • Перевірте розподіл CPU і softirq: mpstat -P ALL 1 та cat /proc/interrupts. Якщо один CPU завантажений softirq — зупиніться. Виправте афініті IRQ.
  • Перевірте використання диска і черги: iostat -x 1. Якщо %util ~100% з високим await — ви або дійсно прив’язані до пристрою, або маєте проблему локальності/переривань, яка робить це схожим на насичення пристрою.
  • Перевірте тиск пам’яті: vmstat 1 (дивіться si/so), і perf‑лічильники, якщо є. Якщо йде свапінг — все інше це фонова дія.

По‑друге: підтвердіть фізичні переговори й реальність прошивки

  • Пониження лінків PCIe: lspci -vv для Speed/Width. Виправляйте Gen3‑при‑Gen4‑підтримці проблеми перед зміною параметрів ядра.
  • Зниження частоти пам’яті: dmidecode для виявлення неправильно налаштованих DIMM. EPYC працюватиме, але ваша пропускна здатність пам’яті тихо зникне.
  • Тротлінг політики живлення: cpupower frequency-info і логи. Багато «таємних регресій» — це профілі живлення.

По‑третє: вирівняйте локальність для гарячого шляху

  • Відображення NUMA: numactl --hardware, NUMA‑вузол NIC через sysfs і локальність пристроїв зберігання.
  • Прив’язуйте лише те, що потрібно: для великих VM або виділених сервісів прикріплюйте CPU і пам’ять. Для всього іншого почніть із виправлення IRQ і живлення.
  • Міряйте хвостову латентність, а не середні значення: проблеми EPYC часто ховаються в p99, поки p50 виглядає нормально.

Жарт №2: Якщо ваш перший крок — «давайте підкрутимо sysctl», ви не діагностуєте — ви приправляєте.

Три корпоративні міні‑історії з полів

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

Платформна команда мігрувала флот хостів зі сховищем з старих двосокетних систем на блискучі одно‑сокетні сервери EPYC. План виглядав бездоганно:
менше сокетів, та сама оперативна пам’ять, більше ядер, більше NVMe. Вони очікували нижчу латентність і менше енергії. Перший тиждень був тихим. Потім щотижневе завдання вдарило:
конденсація бекапів разом з індексацією і клієнтським трафіком. Графіки латентності набули зубів.

На чергуванні припустили, що «диски насичені». %util NVMe був високий, і черги виглядали жахливо. Вони додали більше дисків у наступну збірку хоста
і розширили дані ширше. Результат: та сама p99 латентність, але з більшою кількістю обладнання.

Реальна проблема була в локальності. NIC і половина NVMe висіли на топології PCIe, через яку ядро маршрутизувало переривання на CPU0.
CPU0 не був «завантажений» в просторі користувача; він тону в softirq і обробці переривань. Потоки зберігання працювали на іншому NUMA‑вузлі,
постійно перетинали фабрику, щоб завершити I/O. Система мала ядра в запасі — просто не там, де падала робота.

Виправлення було нудне й хірургічне: увімкнули irqbalance як базу, потім переоприділи афініті для NIC і черг NVMe, щоб тримати їх локальними для NUMA‑вузла пристрою.
Також підкоригували розміщення VM, щоб демони зберігання і їхня пам’ять лишалися поруч із тим вузлом.

Ключовий урок не в «irqbalance — добре». Він у тому, що хибне припущення полягало в тому, щоб трактувати насичення NVMe як властивість пристрою, а не як властивість кінцевого шляху.
В EPYC‑світі CPU і NUMA‑фабрика — частина вашого підсистеми зберігання, подобається вам це чи ні.

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

Команда обчислень, що керувала зайнятим кластером віртуалізації, вирішила прикріпити все. Їх логіка виглядала розумною: NUMA існує, отже pinning — добре,
отже закріплюємо все — краще. Вони прив’язали vCPU, пам’ять, IRQ і навіть кілька ядрових потоків для надійності.

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

Факап був операційний. Стратегія pinning вимагала суворої дисципліни розміщення, але у команди не було інструментів для її постійної перевірки.
Вони також створили фрагментацію: вільні ядра були, але не в тій NUMA‑формі, щоб розмістити нові VM. Планувальник почав відмовляти у розміщенні,
а люди почали робити ручні переноси. Ось коли ви розумієте, як швидко кластер перетворюється на артефакт під замовлення.

Вони розгорнули більшість змін назад. Pinning залишився для невеликого набору високовартісних VM з передбачуваним життєвим циклом. Для всього іншого вони покладались на
розумні значення за замовчуванням: huge pages там, де потрібно, irqbalance з цільовими переоприділеннями і політика хоста, яка не дозволяє живленню саботувати їх.

Урок: оптимізація, яка вимагає ідеальної експлуатації — не оптимізація; це борговий інструмент із змінними відсотками.

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

Компанія вивела нові EPYC‑хости для кластера зберігання. Нічого екзотичного: NVMe, швидкі NIC, стандартний Linux, стандартний моніторинг.
Вікно змін було вузьким, тому вони тримали образ ОС ідентичним між поколіннями і покладалися на автомати.

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

Рятівна практика була болісно нудною: у них була рутина, яка переглядала логи ядра на предмет виправлених апаратних помилок як частина щотижневої гігієни,
а не лише під час інцидентів. Оператор помітив ECC‑корекції та кілька повідомлень PCIe AER на проблемному хості. Без паніки, просто чіткий напрямок:
апарат чи прошивка, а не тюнінг додатків.

Вони запланували контрольоване техобслуговування, пересадили DIMM, оновили прошивку і замінили підозрілий модуль. Сплески зникли.
Без цієї гігієни команда витратила б тижні на «налаштування» афініті IRQ і параметрів зберігання, поки коробка тихо руйнувала довіру.

Урок: найприбутковіший трюк продуктивності — запобігати апаратним флюктуаціям, які прикидаються програмною проблемою.

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

EPYC не створює нових помилок. Він робить існуючі голоснішими. Ось ті, що я бачу регулярно, з конкретними виправленнями.

1) Симптом: сплески p99 під навантаженням; CPU «здається простим» у цілому

  • Корінь проблеми: переривання/softirq сконцентровані на кількох CPU; гарячий шлях CPU‑зв’язаний у просторі ядра.
  • Виправлення: перевірте /proc/interrupts; увімкніть irqbalance; прив’яжіть IRQs для NIC/NVMe до локальних NUMA‑CPU; перевірте RPS/XPS, якщо релевантно.

2) Симптом: пропускна здатність NVMe plateau далеко нижча за очікування

  • Корінь проблеми: PCIe‑лінк погоджений на нижчу швидкість (Gen3 проти Gen4/5) або меншу ширину; ретаймер/бекплейн/невідповідність BIOS.
  • Виправлення: lspci -vv LnkSta; виправте налаштування BIOS; оновіть прошивку; перевірте кабелі/бекплейн; повторно протестуйте перед тим, як налаштовувати ПЗ.

3) Симптом: база даних повільніша після апгрейду «більше ядер»

  • Корінь проблеми: насичення пропускної здатності пам’яті, віддалений доступ до NUMA‑пам’яті або стіна масштабування через контенцію локів.
  • Виправлення: вирівняйте процес БД щодо CPU/пам’яті для NUMA‑вузла; підвищте локальність; розгляньте меншу кількість потоків; перевірте швидкість/заповнення пам’яті.

4) Симптом: кластер віртуалізації має випадкові «хороші» й «погані» хости

  • Корінь проблеми: непослідовні налаштування BIOS (режим NPS, профіль живлення), непослідовні драйвери/губернатори ядра або дрейф прошивки.
  • Виправлення: базовий набір BIOS/прошивки; застосуйте при провізуванні; аудит з lscpu, cpupower та інвентаризація DMI.

5) Симптом: CPU‑навантаження сховища вибухає після увімкнення стиснення/шифрування

  • Корінь проблеми: CPU стає вузьким місцем сховища; домінують пропускна здатність пам’яті і поведінка кеша; накладні витрати по ядру масштабуються погано.
  • Виправлення: виміряйте з perf/turbostat; налаштуйте рівень стиснення; забезпечте розподіл IRQ; перемістіть важкі демони на локальні вузли; розгляньте апаратне відвантаження лише якщо воно дійсне.

6) Симптом: «Ми прикріпили vCPU і стало гірше»

  • Корінь проблеми: pinning без вирівнювання пам’яті та I/O‑локальності; або операційний дрейф робить pinning несумісним після міграцій.
  • Виправлення: робіть pinning як повну політику (CPU + пам’ять + локальність пристроїв) для невеликого підмножини; інакше приберіть pinning і спочатку виправте переривання/живлення.

7) Симптом: часті дрібні затримки, важко відтворити

  • Корінь проблеми: виправлені ECC‑помилки, PCIe AER‑повтори або події термо/енергетичного обмеження.
  • Виправлення: перегляньте journalctl -k на EDAC/AER; вирішіть апаратні проблеми; не «налаштовуйте навколо» попереджень про надійність.

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

Покроково: введення нового EPYC‑хоста в продакшн без драми

  1. Стандартизуйте налаштування BIOS: профіль живлення, режим NPS, політика SMT, налаштування покоління PCIe. Документуйте вибір і чому.
  2. Валідуйте заселення пам’яті: правильні слоти, взаємопідходящі DIMM, очікувана сконфігурована швидкість. Негайно виправляйте downclocking.
  3. Перевірте погодження PCIe: перевірте всі NVMe і NIC на очікувану швидкість/ширину лінка; упевніться у відсутності мовчазних понижень.
  4. Задайте базову поведінку частоти CPU: підтвердіть governor/driver; запустіть короткий тест навантаження і перевірте, що частоти не колапсують несподівано.
  5. Підтвердіть форму NUMA: збережіть виводи lscpu і numactl --hardware в інвентарі хоста.
  6. Встановіть політику переривань: увімкніть irqbalance як базу, потім додайте цільові афініті для відомих гарячих точок (NIC, NVMe) якщо є докази.
  7. Запустіть smoke‑тест сховища: випадкові чит/запис з реалістичними глибинами черг; зафіксуйте p50/p95/p99 латентності, а не лише пропускну здатність.
  8. Запустіть мережевий smoke‑тест: перевірте лінійну швидкість, витрати CPU і розподіл IRQ; упевніться, що жодне ядро не завантажене softirq до упору.
  9. Встановіть моніторинг «здоров’я апаратури»: логи EDAC, MCE, AER. Сприймайте виправлені помилки як індикатори раніше проблеми.
  10. Лише потім налаштовуйте робочі параметри: кількість потоків, pinning, huge pages, параметри файлової системи тощо — на основі вимірювань.

Чекліст: вибір між одно‑ і дво‑сокетним EPYC

  • Обирайте одно‑сокетний, якщо потрібен великий I/O, помірна пам’ять і бажаєте простішого ліцензування та меншу складність доменів відмови.
  • Обирайте дво‑сокетний, якщо вам дійсно потрібен обсяг пам’яті або пропускна смуга за межами одного сокета, або ваше навантаження вимагає більше PCIe‑ендпоінтів без комутаторів.
  • Уникайте дво‑сокетного «просто тому що». Воно подвоює складність NUMA і збільшує зону ураження для штрафів віддаленої пам’яті.

Чекліст: що виміряти перед тим, як звинувачувати EPYC

  • погоджена швидкість/ширина PCIe
  • сконфігурована швидкість пам’яті і заселення каналів
  • розподіл IRQ по CPU
  • час для softirq і гарячі точки по ядрах
  • розміщення процесу і його пам’яті по NUMA
  • gubernator живлення і свідчення тротлінгу
  • хвостова латентність (p99) під змішаним навантаженням

FAQ

1) Чи EPYC «кращий» за Intel для серверів?

Залежить від того, що означає «кращий». EPYC особливо сильний, коли потрібна висока щільність ядер, багато PCIe і добра пропускна здатність пам’яті за долар.
Але «кращий» у продакшні — це також зрілість прошивки, стабільність платформи і те, як ваше ПЗ поводиться з NUMA і високим паралелізмом.

2) Чому мій одно‑сокетний EPYC показує декілька NUMA‑вузлів?

Тому що платформа може бути сконфігурована як кілька NUMA‑доменів на сокет (режими NPS), і чіплет/I/O‑топологія виставляє межі локальності.
Ставтеся до цього як до реальності: латентність пам’яті та локальність I/O можуть відрізнятися по вузлах навіть в одному сокеті.

3) Чи варто вмикати SMT (аналог гіпертредингу) на EPYC?

Зазвичай так для навантажень на пропускну здатність, змішаних VM‑середовищ і загальних сервісів. Для строгих сценаріїв латентності або «шумних сусідів» тестуйте обидва режими.
SMT може покращити використання, але також може збільшити хвостову латентність при високій контенції.

4) Чому мій NVMe працює на Gen3, хоча підтримує Gen4/Gen5?

Поширені причини: BIOS змушує покоління, обмеження бекплейна/ретаймерів, змішані пристрої домовляються вниз, проблеми цілісності сигналу або застаріла прошивка.
Підтвердіть через lspci -vv і виправляйте фізичний/прошивковий рівень перед налаштуванням Linux.

5) Чи потрібно прив’язувати IRQ вручну, чи вистачить irqbalance?

Почніть з irqbalance. Якщо все ще бачите гарячі точки (один CPU завжди у softirq) або потрібна стабільна латентність, прив’яжіть IRQs для NIC/NVMe
до CPU, близьких до NUMA‑вузла пристрою. Ручне прив’язування без вимірювань має тенденцію перетворюватися на усталену народну практику.

6) Як найшвидше зрозуміти, чи обмежені ви пропускною здатністю пам’яті?

Шукайте низький IPC під навантаженням (turbostat), зростання cache‑misses (perf stat) і масштаб, що перестає покращуватися з додатковими потоками.
Також перевірте, чи пам’ять не знижена в частоті і чи канали заповнені правильно.

7) Чи завжди більше ядер краще для вузлів зберігання?

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

8) Чи варто налаштовувати більше NUMA‑вузлів на сокет (NPS) заради продуктивності?

Іноді. Більше NUMA‑вузлів може покращити локальність, якщо ваш планувальник і розміщення додатків NUMA‑свідомі, особливо для I/O‑важких навантажень.
Але це також підвищує операційну складність. Якщо у вас немає дисципліни розміщення — менша кількість NUMA‑вузлів може бути стабільнішою.

9) Яка найгірша звичка «tuning для EPYC»?

Трактувати топологію як необов’язкову. Якщо ігнорувати розподіл IRQ, розміщення пам’яті і погодження PCIe, ви витратите тижні на «налаштування» sysctl і кількості потоків,
поки справжнє вузьке місце буде стояти на видноті.

Наступні кроки, які не засоромлять вас

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

Практичні наступні кроки:

  1. Інвентаризуйте топологію на кожному хості: форма CPU/NUMA, NUMA‑вузли NIC і NVMe, погоджені швидкості PCIe. Зберігайте це в CMDB або метаданих провізування.
  2. Стандартизуйте BIOS і політику живлення по всьому флоту. Непослідовні профілі створюють «примарні хости», що витрачають час SRE.
  3. Зафіксуйте базову поведінку IRQ і softirq під репрезентативним навантаженням. Якщо один CPU — копач ядра, спочатку виправте це.
  4. Міряйте p99 до і після змін. Якщо ви відслідковуєте лише середні значення, ви будете оголошувати перемогу, поки користувачі продовжують повторні спроби.
  5. Використовуйте pining вибірково: залишайте його для навантажень, які цього заслуговують, і середовищ, які можуть це підтримувати.

Мета — не зробити ваші EPYC‑сервери вражаючими. Вони вже вражають. Мета — зробити їх нудними — і зберегти їх такими, коли навантаження стає жорстким.

← Попередня
Резервні копії MySQL проти SQLite: що простіше відновити під тиском
Наступна →
386: момент, коли ПК почали поводитися як сервер

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