Сховище: NVMe проти SATA SSD — тест навантаження, який змінює все

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

Ваш додаток відчувається «повільним», і в кожного є улюблений підозрюваний. Команда бази даних звинувачує мережу. Платформна команда звинувачує базу даних. Постачальник каже «оновіть до NVMe». Тим часом ваші панелі показують CPU на 20% і пам’ять у запасі, але p95-латентність зростає, ніби запізнюється на зустріч.

Ось як рішення щодо зберігання приймають у реальному житті: за відчуттями, скріншотами й тим диском, що був у розпродажі. Виправлення нудне й безжальне: запустіть тест робочого навантаження, який імітує ваше продуктивне I/O, виміряйте правильні речі (перцентилі латентності, черги, хвостову поведінку) і дайте числам вирішити. NVMe проти SATA SSD перестає бути релігією і стає арифметикою.

Тест навантаження, який змінює все

Найбільша помилка в дебатах «NVMe проти SATA» — це бенчмаркінг неправильного навантаження. Люди запускають тест послідовного читання, отримують величезне число й оголошують перемогу. А потім продакшн все одно гальмує, бо реальне навантаження — це маленькі випадкові записи з sync, або змішані читання/записи з огидною хвостовою латентністю. Ваш бізнес не працює на пікових MB/s. Він працює на передбачуваних часах завершення.

Тест навантаження, який змінює все, простий:

  • Вимірюйте перцентилі латентності, а не лише середні значення.
  • Використовуйте реалістичні розміри блоків (часто 4K–16K для баз даних, 128K+ для стрімінгу/бакупів).
  • Включіть семантику sync, якщо ваш застосунок використовує fsync/FDATASYNC.
  • Варіюйте глибину черги і конкурентність, поки не побачите, де латентність вибухає.
  • Запускайте досить довго, щоб досягти стаціонарного стану (SSD мають кеші та алгоритми вирівнювання зносу; короткі тести брешуть).

Чому це змінює рішення: SATA SSD часто виглядають «добре» при низькій глибині черги і малій конкуренції. Багато продакшн-систем такими не є. Як тільки ви додаєте конкуренцію, фонову компактацію, чекпоінти, лог-записи та реальний трафік користувачів, SATA швидше досягає стіни. NVMe не лише піднімає стелю; він змінює форму кривої.

Ось ментальна модель: SATA — вузький коридор з одною чергою в один ряд. NVMe — склад з кількома навантажувальними доками й підйомниками, які не ділять один дверний отвір. Тест навантаження — це ви, що привозите достатньо вантажівок, щоб побачити, де справді вузьке місце.

NVMe проти SATA на практиці (не маркетинг)

Протокол і пропускна інфраструктура: навіщо потрібен NVMe

SATA SSD використовують протокол, спроєктований для обертальних дисків. Він працює, але це шар трансляції з успадкованими припущеннями: менше черг, неглибока глибина черги, більші витрати CPU на кожну I/O та модель хост-контролера, яка добре працює для «однієї лінії запитів», але гірше — для «тисяч одночасних операцій».

NVMe створювався з думкою про флеш із самого початку. Він підтримує багато черг подачі/завершення, глибокі черги, менші накладні витрати і чистий паралелізм. На сучасному сервері з багатьма ядрами це важливо. Сховище — це не лише пристрій; це конвеєр через ядро, драйвери, PCIe-фабрику, прошивку контролера та шари трансляції NAND. NVMe — це перший мейнстрім-протокол, де конвеєр не прикидається, що він у 2005 році.

Різниці в продуктивності, які ви реально відчуєте

Три речі визначають, чи відчуєте ви перевагу NVMe:

  1. Латентність під навантаженням: SATA може мати пристойну латентність при низькій глибині черги. Під навантаженням вона швидко накопичує чергу й хвостова латентність стає огидною.
  2. IOPS для малого випадкового I/O: NVMe зазвичай домінує тут, за умови, що диск і система адекватні.
  3. Змішані навантаження: NVMe зазвичай краще справляється з одночасними читаннями/записами без сильного взаємного впливу.

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

Надійність і операційна поведінка (частина, що болить о 3 ранку)

І NVMe, і SATA SSD можуть бути надійними. Обидва можуть виходити з ладу так, що спочатку виглядає як «додаток повільний», перш ніж «диск помер». Операційно NVMe дає багатшу телеметрію через SMART/лог-сторінки (залежно від інструментів) і часто кращу поведінку латентності під тиском. Але він також вводить інші режими відмов: флапи PCIe-лінку, проблеми прошивки, термальне тротлінгування й зміни драйверів ядра, які б’ють під час оновлень.

Більшість команд недооцінюють операційну поверхню «швидкого». Швидші пристрої підсилюють слабкі припущення. Якщо налаштування файлової системи неправильні, NVMe допоможе швидше дійти до неправильної висновку.

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

  • SATA — нащадок ATA/IDE, сімейство, створене для жорстких дисків та оптичних приводів, а не для низьколатентної флеш-пам’яті.
  • AHCI (спільний інтерфейс хоста для SATA) розроблявся в еру HDD, де очікування щодо черг і паралелізму були помірними.
  • NVMe 1.0 з’явився на початку 2010-х, спеціально щоб уникнути неефективності успадкованих стеків зберігання на SSD.
  • NVMe підтримує багато апаратних черг, що дозволяє краще масштабуватися по CPU-ядрах; це важливо на багатосокетних серверах.
  • Поводження SSD з «SLC-кешем» робить короткі бенчмарки недостовірними: багато споживчих і навіть деякі підприємницькі диски швидко «вибухають», а потім різко гальмують.
  • 4K випадковий запис історично — тест, що «змушує плакати», бо навантажує флеш-транслейшн-шари і write amplification.
  • TRIM/DISCARD важливі: без них стійка продуктивність може деградувати, бо у SSD менше вільного простору для управління.
  • Журнальні файлові системи і WAL баз даних спочатку оптимізувалися під HDD; SSD зміщують компроміси.

Метрики, які вирішують суперечку

Перцентилі латентності: дорослі числа

Середня латентність — те, що ви ставите на слайд. p95/p99/p99.9 — те, що відчувають ваші користувачі, що підсилюють retries, і за що SRE отримують пейджі. Головна перевага NVMe у продакшні часто не пікова пропускна здатність; це утримання хвостової латентності під контролем під час конкуренції.

Глибина черги і завантаження: де проявляється вузьке місце

Коли пристрій насичується, латентність зростає, бо запити чекають у черзі. Ви побачите підвищений await в iostat, глибші черги в iostat -x, і довші латентності в fio. SATA зазвичай насичується раніше для малого випадкового I/O. NVMe теж може насититися—усе може—але «коліно» кривої зазвичай далі.

IOPS проти пропускної здатності: перестаньте плутати

IOPS — це «скільки операцій за секунду». Пропускна здатність — це «скільки даних за секунду». Навантаження з 4K випадковими читаннями вимагає багато IOPS. Навантаження з 1MB послідовних читань — це витрати на пропускну здатність. Якщо ви виміряли не те, ви купите неправильний диск.

Write amplification і стаціонарний стан

SSD виконують внутрішню збірку сміття. Вони переміщують дані, щоб звільнити блоки, що означає: пристрій може записувати більше, ніж ви просили. При стійких записах — особливо випадкових — продуктивність може впасти після заповнення кешів. Будь-який бенчмарк, що не працює достатньо довго, щоб досягти стаціонарного стану, по суті є демо.

Парафразована ідея — Werner Vogels: «Проєктуйте з урахуванням відмов; передбачайте, що компоненти можуть ламатися, і будуйте системи, які продовжують працювати».

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

Розумне налаштування лабораторії (щоб ви не бенчмаркували page cache)

Правила взаємодії

  • Бенчмаркуйте сирий блочний пристрій або виділений тестовий файл з direct I/O, а не ваш page cache.
  • Використовуйте розмір більший за RAM. Якщо у сервера 64GB RAM, не тестуйте з 4GB.
  • Закріпіть середовище: governor масштабування CPU, фонова cron-робота, шумні сусіди (хост VM) та опції монтування файлової системи.
  • Визначте, що ви оптимізуєте: пропускну здатність, латентність, хвостову латентність або узгодженість під навантаженням.

Жарт 1: Бенчмарки сховища схожі на дієти: у кожного є план, поки кеш не спрацює.

Виберіть репрезентативні робочі навантаження

Кілька патернів охоплюють більшість реальних систем:

  • Дані OLTP: 4K–16K випадкові читання/записи, змішані, помірна до високої конкуренція, поведінка fsync/WAL.
  • Інжест логів: послідовні записи, періодичний fsync, поодинокі читання для індексації.
  • Хости VM/контейнерів: змішані випадкові I/O серед багатьох гостей, часто найгірший сценарій для хвостової латентності.
  • Аналітика/ETL: великі послідовні читання, деякі великі записи, сплески.
  • Об’єктне сховище/Ceph: багато дрібних операцій, накладні реплікації, взаємодія мережа+диск.

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

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

Завдання 1: Визначте, що насправді підключено (NVMe чи SATA, модель, прошивка)

cr0x@server:~$ lsblk -d -o NAME,MODEL,TRAN,SIZE,ROTA
NAME MODEL                      TRAN   SIZE ROTA
sda  Samsung_SSD_860_EVO_1TB     sata 931.5G    0
nvme0n1 Samsung_SSD_980_PRO_1TB  nvme 931.5G    0

Що це означає: У вас є і SATA, і NVMe пристрої. ROTA=0 підтверджує SSD (не обертовий). TRAN вказує на тип транспорту.

Рішення: Бенчмаркуйте правильний пристрій і припиніть сперечатися абстрактно. Також: зафіксуйте модель/прошивку; споживчий NVMe і корпоративний NVMe дуже по-різному поводяться під тривалим навантаженням.

Завдання 2: Перевірте ширину/швидкість PCIe (NVMe може бути тихо обмежений)

cr0x@server:~$ sudo nvme id-ctrl /dev/nvme0n1 | egrep -i 'mn|fr|rab|ieee'
mn : Samsung SSD 980 PRO 1TB
fr : 5B2QGXA7
rab : 6
ieee : 002538
cr0x@server:~$ sudo lspci -vv -s $(readlink -f /sys/class/nvme/nvme0/device | awk -F/ '{print $(NF-1)}') | egrep -i 'LnkCap|LnkSta'
LnkCap: Port #0, Speed 16GT/s, Width x4
LnkSta: Speed 8GT/s (downgraded), Width x2 (downgraded)

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

Рішення: Виправте платформу, перш ніж звинувачувати диск. Якщо ваш «NVMe» фактично на половині лінії, ви купили спортивну машину й встановили велосипедні шини.

Завдання 3: Подивіться, чи ядро вважає ваш диск постійно завантаженим

cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0 (server) 	02/04/2026 	_x86_64_	(16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.11    0.00    4.20    8.35    0.00   75.34

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz  aqu-sz  %util
sda              5.10    180.4     0.00   0.00   12.30    35.35   95.20   4200.0    10.00   9.50   45.60    44.12    4.38  99.20
nvme0n1         30.00   1200.0     0.00   0.00    0.85    40.00  110.00  5200.0     0.00   0.00    1.40    47.27    0.22  22.50

Що це означає: sda завантажений приблизно на 99% з високим write await; nvme0n1 рухається спокійно. CPU iowait непоказовий. Це вузьке місце зберігання на SATA-пристрої.

Рішення: Перемістіть «гарячий» шлях з SATA або зменшіть тиск запису (групування, менше fsync, кращий кеш). Якщо дані застосунку живуть на sda, NVMe десь інше не допоможе.

Завдання 4: Підтвердьте планувальник та налаштування запитів (особливо для SATA)

cr0x@server:~$ cat /sys/block/sda/queue/scheduler
[mq-deadline] none
cr0x@server:~$ cat /sys/block/nvme0n1/queue/scheduler
[none] mq-deadline kyber bfq

Що це означає: Для NVMe часто краще працює none. SATA SSD зазвичай поводяться добре з mq-deadline для контролю латентності під конкуренцією.

Рішення: Якщо латентність на SATA стрибає під навантаженням, спробуйте mq-deadline. Якщо ви намагаєтеся «оптимізувати» NVMe примусово вмикаючи BFQ, ви можете винаходити проблеми.

Завдання 5: Перевірте підтримку TRIM/discard і чи використовується вона

cr0x@server:~$ lsblk -D -o NAME,DISC-GRAN,DISC-MAX,DISC-ZERO
NAME     DISC-GRAN DISC-MAX DISC-ZERO
sda            512B       2G         0
nvme0n1          4K       2G         0
cr0x@server:~$ mount | egrep ' / |/data '
/dev/nvme0n1p2 on / type ext4 (rw,relatime)

Що це означає: Пристрої підтримують discard. Ваш монтування не показує discard; це не обов’язково погано. Онлайн-discard може додавати джиттер; періодичний fstrim часто кращий.

Рішення: Забезпечте режим TRIM (щотижневий fstrim або еквівалент). Тривала продуктивність без TRIM — це повільна аварія.

Завдання 6: Запустіть fstrim і спостерігайте поведінку (джиттер — це підказка)

cr0x@server:~$ sudo fstrim -v /data
/data: 312.6 GiB (335657148416 bytes) trimmed

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

Рішення: Плануйте trimming у часи низького трафіку або перевірте прошивку SSD/контролера. Якщо trim викликає помітні зупинки — це операційне обмеження, навколо якого ви плануєте.

Завдання 7: Виявіть затримку записів, спричинену файловою системою (dirty ratios і writeback)

cr0x@server:~$ sysctl vm.dirty_ratio vm.dirty_background_ratio vm.dirty_expire_centisecs
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10
vm.dirty_expire_centisecs = 3000

Що це означає: Ядро може буферизувати багато «брудних» даних перед примусовим записом. Це може породжувати періодичні стрибки латентності при флешуванні.

Рішення: Якщо ви бачите «кожні N секунд додаток гальмує», розгляньте налаштування dirty ratios або використання батчингу на рівні застосунку. NVMe може маскувати це; він не вилікує патерн.

Завдання 8: Виміряйте реальну латентність пристрою за допомогою fio (random read)

cr0x@server:~$ sudo fio --name=rr4k --filename=/dev/nvme0n1 --direct=1 --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --numjobs=4 --runtime=60 --time_based --group_reporting
rr4k: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, ioengine=libaio, iodepth=32
...
read: IOPS=420k, BW=1641MiB/s (1720MB/s)(98.5GiB/60001msec)
   slat (nsec): min=650, max=220k, avg=2100.3, stdev=1800.1
   clat (usec): min=45, max=3200, avg=290.4, stdev=110.2
    clat percentiles (usec):
     |  1.00th=[  90],  5.00th=[ 130], 10.00th=[ 160], 50.00th=[ 270],
     | 95.00th=[ 480], 99.00th=[ 760], 99.90th=[1200], 99.99th=[2000]

Що це означає: Сильні IOPS для випадкового читання і пристойна хвостова латентність. Зверніть увагу на перцентилі: p99.9 ≈ 1.2ms. Це число важить для ваших сервісів з високою конкуренцією.

Рішення: Якщо ваш додаток потребує великої випадкової читальної конкуренції, NVMe виправданий. Якщо в проді p99 гірший, вузьке місце вище пристрою (файлова система, шифрування, віртуалізація, тротлінг) або навантаження не читальне.

Завдання 9: Порівняйте з SATA, використавши той самий профіль fio (і дивіться на «коліно»)

cr0x@server:~$ sudo fio --name=rr4k --filename=/dev/sda --direct=1 --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --numjobs=4 --runtime=60 --time_based --group_reporting
rr4k: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, ioengine=libaio, iodepth=32
...
read: IOPS=68.5k, BW=268MiB/s (281MB/s)(16.1GiB/60004msec)
   clat (usec): min=80, max=18000, avg=1700.2, stdev=900.4
    clat percentiles (usec):
     |  1.00th=[ 220],  5.00th=[ 420], 10.00th=[ 520], 50.00th=[1500],
     | 95.00th=[3200], 99.00th=[5200], 99.90th=[9200], 99.99th=[15000]

Що це означає: SATA значно відстає по IOPS і хвостовій латентності при цьому навантаженні. p99.9 близько 10ms — це там, де розподілені системи починають «допомагати» повторними спробами й роблять гірше.

Рішення: Якщо ваш сервіс чутливий до хвостової латентності (більшість чутливі) і у вас є конкуренція, SATA стає неправильним дефолтом для гарячого шару.

Завдання 10: Протестуйте write-інтенсивні з sync (реальність WAL/логу)

cr0x@server:~$ sudo fio --name=syncwrite --directory=/data --direct=1 --rw=write --bs=4k --numjobs=1 --iodepth=1 --fsync=1 --size=2G --runtime=60 --time_based --group_reporting
syncwrite: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, ioengine=psync, iodepth=1
...
write: IOPS=4800, BW=18.8MiB/s (19.7MB/s)(1.10GiB/60001msec)
    clat (usec): min=110, max=32000, avg=205.3, stdev=410.2

Що це означає: Однопотокові синхронні записи обмежені латентністю fsync, а не глибиною черги. Навіть NVMe не перетворить fsync на безкоштовну цукерку; він просто зменшує біль, якщо диск і стек хороші.

Рішення: Якщо ви обмежені WAL, розгляньте: окремий пристрій для логів, груповий commit, налаштування чекпоінтів або диск з захистом від втрати живлення. Не чекайте, що «більше смуг» виправить синхронні патерни застосунку.

Завдання 11: Перевірте помилки пристрою та знос медіа (тихі відмови теж відмови)

cr0x@server:~$ sudo smartctl -a /dev/sda | egrep -i 'Reallocated|Pending|CRC|Power_On_Hours|Wear|Media'
Power_On_Hours          17342
UDMA_CRC_Error_Count    0
Reallocated_Sector_Ct   0
Current_Pending_Sector  0
cr0x@server:~$ sudo nvme smart-log /dev/nvme0n1
Smart Log for NVME device:nvme0n1 namespace-id:ffffffff
critical_warning                    : 0x00
temperature                         : 43 C
available_spare                     : 100%
available_spare_threshold           : 10%
percentage_used                     : 7%
data_units_read                     : 123,456,789
data_units_written                  : 98,765,432
media_errors                        : 0
num_err_log_entries                 : 0

Що це означає: Очевидних помилок немає; знос NVMe низький. Якщо ви бачите media errors або зростання записів у логах помилок, інциденти продуктивності часто — перша стадія.

Рішення: Замініть підозрілі диски на ранній стадії. Сховище виходить з ладу в дві фази: «дивна латентність» і «вниз». Ви повинні діяти на фазі перша.

Завдання 12: Перевірте налаштування write cache (і чи ви обманюєте себе)

cr0x@server:~$ sudo hdparm -W /dev/sda

/dev/sda:
 write-caching =  1 (on)

Що це означає: Write cache увімкнено. Це може бути нормально для SSD, але надійність залежить від захисту від втрати живлення і поведінки прошивки диска.

Рішення: Для баз даних, яким важлива довговічність, віддавайте перевагу дискам з PLP. Якщо ви не можете гарантувати це, не «оптимізуйте», довіряючи кешам, які не в змозі бути обґрунтованими.

Завдання 13: Перевірте device mapper / накладні витрати шифрування (поширено в реалі)

cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,MOUNTPOINT
nvme0n1        disk  931.5G
├─nvme0n1p1    part    512M /boot
└─nvme0n1p2    part    931G
  └─cryptdata  crypt   931G /data
cr0x@server:~$ sudo cryptsetup status cryptdata
/dev/mapper/cryptdata is active.
  type:    LUKS2
  cipher:  aes-xts-plain64
  keysize: 512 bits
  device:  /dev/nvme0n1p2
  sector size:  512
  offset:  32768 sectors
  size:    1953499136 sectors
  mode:    read/write

Що це означає: Шифрування знаходиться в шляху. На сучасних CPU з AES-NI це часто нормально, але це може стати CPU-обмеженням при високій пропускній здатності і додати варіативність латентності.

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

Завдання 14: Знайдіть процес, що створює I/O тиск (щоб перестати звинувачувати «диск»)

cr0x@server:~$ sudo iotop -o -b -n 3
Total DISK READ: 12.34 M/s | Total DISK WRITE: 145.67 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN  IO>    COMMAND
 9123 be/4  postgres    1.23 M/s   80.12 M/s  0.00 % 45.00 % postgres: checkpointer
 9050 be/4  postgres    0.00 B/s   30.45 M/s  0.00 % 20.00 % postgres: walwriter
 7711 be/4  root        0.00 B/s   25.10 M/s  0.00 % 12.00 % tar -cf /backup/data.tar /data

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

Рішення: Переплануйте бекапи, налаштуйте DB checkpointing або ізолюйте навантаження на різні пристрої. Не купуйте NVMe тільки для того, щоб tar змагався з базою даних опівдні.

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

Три корпоративні міні-історії (анонімізовано, правдоподібно і болісно)

1) Інцидент через неправильне припущення: «SATA SSD — це по суті NVMe для нашого додатку»

Компанія була в процесі міграції зі старих обертальних дисків на SSD. Історія закупівлі була проста: SATA SSD дешевші, доступні й «достатньо швидкі». Хтось запустив швидкий тест послідовної пропускної здатності, побачив сотні MB/s і затвердив покупку. Платформна команда розгорнула новий флот реплік баз даних на SATA.

Два тижні все виглядало добре — бо трафік був невеликий. Потім стартувала маркетингова кампанія, і позначилася конкуренція читань. Першим симптомом не були «дискові алерти». Це було стрибкоподібне зростання p99-латентності API, за яким пішла хвиля повторних спроб між сервісами. Декілька робочих процесів на основі черг почали таймаути і повторно ставити завдання в чергу. Система не впала одномоментно; вона деградувала повільно і жорстоко, як зустріч, яка мала бути листом.

На хостах баз даних CPU був низький. Пам’ять була в запасі. Мережа виглядала нормально. Але iostat показував, що SATA-пристрій зафіксований на 100% завантаженні з await у десятках мілісекунд. On-call спочатку підозрювали деплой. Вони відкатили. Нічого не змінилося.

Корінь проблеми — неправильне припущення: «SSD це SSD». Навантаження було маленькими випадковими читаннями з достатньою паралельністю, щоб наситити SATA. Хвостова латентність підскочила, додаток повторився, і навантаження посилилося. Коли вони перевірили бенчмарк реалістичним fio-досьє (random read, concurrency, percentiles), різниця між SATA і NVMe була не тонкою; це була різниця між стабільністю і хаосом.

Вони перемістили найгарячіші репліки на NVMe, залишили SATA для «холодних» реплік і пакетних робіт, і додали стандартний тест робочого навантаження до приймання апаратури. Справжній урок не «завжди купуйте NVMe». Урок — «завжди тестуйте те навантаження, яке ви справді запускаєте».

2) Оптимізація, яка обернулася проти: «Увімкнемо online discard скрізь»

Інша компанія мала флот SSD, що поступово втратив продуктивність запису протягом місяців. Хтось правильно виявив, що trimming не відбувається надійно. Найшвидше рішення здавалося вмикнути mount з опцією discard, щоб ядро робило TRIM онлайн.

Це спрацювало — певною мірою. Тривала продуктивність покращилась. Але варіативність латентності погіршилась. На деяких хостах кожні кілька хвилин p99-латентність стрибала, і «швидкий шлях» застосунку час від часу потрапляв на зависання 100ms. Інцидентні звіти дратували через те, що сплески були короткими, і система відновлювалась до того, як хтось встиг зафіксувати чистий профіль.

Вони зрештою зіставили сплески з активністю discard. Онлайн-discard додавало роботу в I/O-шлях і погано взаємодіяло з їхнім змішаним навантаженням: багато дрібних записів плюс періодичні великі видалення. Прошивка пристрою справлялась, але операційний результат — джиттер.

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

3) Нудна, але правильна практика, що врятувала день: «Ми бенчмаркуємо латентність перед апгрейдами»

Ця історія не драматична, тому й спрацювала. Команда, що оперує платформою контейнерів, мала рутину: перед оновленням ядра вони запускали невеликий набір тестів сховища на канарному вузлі. Не героїчні бенчмарки — просто кілька fio-профілів, що відображали їхні звичні PV-патерни, плюс швидка перевірка стану PCIe і NVMe SMART.

Одного тижня числа на канарі були гірші. Перцентилі random read латентності погіршилися, і пропускна здатність впала. Додаток не змінювався. Апаратура не змінювалася. Єдина зміна — нове ядро. Команда призупинила розгортання, розслідувала і виявила, що параметр драйвера/модуля змінив поведінку їхніх NVMe-пристроїв так, що латентність під конкуренцією зросла.

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

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

Плейбук швидкої діагностики

Якщо у вас є 15 хвилин, щоб знайти вузьке місце, зробіть це в такому порядку. Не будьте хитрі. Будьте швидкі й правильні.

Перше: доведіть, що це латентність сховища (не CPU, не мережа, не блокування)

  • Перевірте p95/p99 латентності застосунку і рівень помилок. Шукайте retries/timeouts.
  • На хості: iostat -xz 1 і дивіться %util і await.
  • Перевірте vmstat 1 на високий wa (iowait) і чергу виконання.

Друге: знайдіть який пристрій і який процес

  • lsblk щоб зіставити точки монтування з пристроями.
  • iotop -o щоб ідентифікувати топ записувачів/читачів.
  • pidstat -d 1 якщо потрібні I/O-рейт на процеси без інтерактивних інструментів.

Третє: вирішіть, чи це насичення, неправильне налаштування чи деградація

  • Насичення: %util близько 100%, зростаюче await, глибока aqu-sz. Виправте, перемістивши навантаження, додавши пристрої або зменшивши I/O.
  • Неправильне налаштування: невірний планувальник, RAID-налаштування, віртуалізаційні обмеження, накладні шифрування, опції монтування. Виправте стек.
  • Деградація: SMART-помилки, NVMe логи помилок, термальне тротлінгування, зниження PCIe-лінку. Замініть або виправте апарат/прошивку.

Четверте: валідуйте цілевим fio-тестом

Запустіть короткий fio-профіль, що відповідає вашій болі: випадкове читання під конкуренцією? sync-записи? змішане 70/30? Використайте --direct=1 і збирайте перцентилі. Якщо тест пристрою хороший, але продакшн поганий, вузьке місце вище блочного шару.

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

1) Симптом: «NVMe встановлено, але продуктивність виглядає як SATA»

Корінна причина: PCIe-лінк знижено (x1/x2, нижчий GT/s), неправильний слот, BIOS енергозбереження або спільна лінія чіпсету.

Виправлення: Перевірте lspci -vv стан лінку; перемістіть пристрій у слот, приєднаний до CPU; налаштуйте BIOS; перевірте кабелі/risers; повторно протестуйте.

2) Симптом: «fio виглядає шикарно, продакшн все одно повільний»

Корінна причина: Бенчмарк потрапив у page cache або використав нереалістичне навантаження; продакшн — sync-інтенсивний або змішаний; віртуалізація або cgroup обмежують I/O.

Виправлення: Використовуйте --direct=1, розмір > RAM і навантаження, що відповідає вашому додатку. Перевірте cgroup I/O ліміти і політики гіпервізора.

3) Симптом: періодичні стрибки латентності кожні кілька секунд/хвилин

Корінна причина: writeback flush-шторм, сплески журналу файлової системи, чекпоінти бази даних або джиттер online discard.

Виправлення: Налаштуйте writeback, змініть параметри DB checkpoint, приберіть discard і використовуйте запланований fstrim, або ізолюйте логи.

4) Симптом: високий iowait але низька завантаженість диска

Корінна причина: ви чекаєте на щось інше: мережеве сховище, зависання прошивки контролера, шари device mapper або перевантажена шляхом блокування файлової системи.

Виправлення: Підтвердьте реальний шлях пристрою. Для мережевого зберігання виміряйте мережеву латентність і серверні статистики. Для локального — перевірте dmesg на ресети і помилки.

5) Симптом: «Ми оновили до NVMe і отримали гірший p99»

Корінна причина: інший планувальник/налаштування, термальне тротлінгування, регресія прошивки або збільшена конкуренція, що виявила рівень контенції в додатку.

Виправлення: Перевірте температуру і тротлінг; порівняйте fio-перцентилі під контрольованим навантаженням; обмежте конкуренцію; перегляньте налаштування бази даних. Швидші диски можуть зробити блокування новим вузьким місцем.

6) Симптом: стійка пропускна здатність записів падає через кілька хвилин

Корінна причина: виснаження SLC-кеша і поведінка стаціонарного стану; диск заповнений; відсутній TRIM; споживчий диск під навантаженням підприємницького класу.

Виправлення: Залиште вільний простір (overprovision), забезпечте TRIM, оберіть enterprise SSD з витривалістю і стабільною продуктивністю запису, запускайте довші тести перед покупкою.

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

Покроково: як вибрати NVMe чи SATA для нового сервісу

  1. Класифікуйте навантаження: OLTP DB, інжест логів, хост VM, аналітика, об’єктне сховище.
  2. Виберіть 2–3 fio-профілі, що їм відповідають (розмір блоку, мікс, конкуренція, семантика sync).
  3. Запустіть на кандидатному обладнанні з тим самим ядром, файловою системою, шифруванням і опціями монтування, які ви будете використовувати.
  4. Записуйте перцентилі (p95/p99/p99.9), а не лише IOPS/BW.
  5. Знайдіть «коліно»: підвищуйте iodepth/numjobs, поки хвостова латентність не стрибне. Це межа безпечної експлуатації.
  6. Зіставте результати з SLO: якщо ваш додаток потребує p99 <5ms під навантаженням, а SATA дає 20ms p99.9 при реалістичній конкуренції — рішення очевидне.
  7. Визначте сегменти: NVMe для гарячих даних і логів; SATA SSD для теплих/холодних, бекапів, пакетних завдань, реплік.
  8. Операціоналізуйте: базові тести на канарях, моніторинг SMART/NVMe логів, розклад trim, управління прошивками.

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

  1. Запустіть iostat -xz 1 і iotop -o в час вікна інциденту.
  2. Зіставте гарячу точку монтування з пристроєм через lsblk.
  3. Перевірте фоні завдання (бекупи, компакти, scrubs).
  4. Перевірте стан пристрою (SMART/NVMe логи) і статус PCIe-лінку (NVMe).
  5. Запустіть цільовий fio-тест, що відповідає підозрюваному патерну на ураженому пристрої.
  6. Якщо fio гарний, але прод плохий: дивіться вгору по стеку (файлова система, шифрування, налаштування DB, cgroups, гіпервізор).
  7. Застосуйте найменші зміни, що усувають вузьке місце: перемістіть WAL, ізолюйте бекапи, налаштуйте чекпоінти або мігруйте гарячі дані на NVMe.
  8. Повторно протестуйте і зафіксуйте базову лінію, щоб наступний інцидент був коротшим.

Операційний чекліст: що моніторити постійно

  • p95/p99 латентності на межах сервісу; показники повторних спроб.
  • Диск: await, %util, розмір черги та мікс чит/записів по пристрою.
  • NVMe SMART: температура, percentage used, media errors, записи логів помилок.
  • Вільне місце файлової системи і успішність trim.
  • Часування фонових завдань: бекапи, компакти, scrubs.

FAQ

1) Чи NVMe завжди швидший за SATA SSD?

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

2) Чому мій послідовний бенчмарк показує незначні відмінності, а база даних працює значно швидше на NVMe?

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

3) Які опції fio запобігають бенчмаркуванню page cache?

Використовуйте --direct=1 і переконайтесь, що розмір тесту перевищує RAM, якщо ви тестуєте файл. Для сирих пристроїв використовуйте шлях до пристрою і будьте обережні, щоб не перезаписати реальні дані.

4) Яку глибину черги слід тестувати?

Тестуйте діапазон: 1, 4, 16, 32, 64 — плюс реалістичну конкуренцію (numjobs). Ви шукаєте «коліно», де перцентилі латентності вибухають. Це «коліно» часто є корисною межею для продакшн-роботи.

5) Чи може SATA SSD бути правильним вибором у продакшні?

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

6) Чи потрібен захист від втрати живлення (PLP) на NVMe?

Якщо вам важливі гарантії довговічності (бази даних, файлові системи зі строгими семантиками), PLP сильно бажаний. Без нього ви можете покладатися на леткі кеші більше, ніж усвідомлюєте.

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

SSD потребують вільних блоків для garbage collection і wear leveling. Менше вільного місця означає більше внутрішніх копіювань і вищу write amplification. Тримайте запас і перевіряйте trim.

8) Чи варто розділяти WAL/логи на NVMe, а дані лишати на SATA?

Часто так. WAL і логи чутливі до латентності і sync-інтенсивні. Помістивши логи на швидший низьколатентний пристрій, можна покращити час commit і зменшити конкуренцію. Протестуйте це — не припускайте.

9) Як зрозуміти, що я CPU-обмежений через шифрування, а не диск-обмежений?

Запустіть fio і слідкуйте за завантаженням CPU. Якщо пропускна здатність впирається, а диск не зайнятий, і CPU високе в kernel/crypto шляхах — ви CPU-обмежені. Розгляньте швидші CPU, налаштування або апаратне прискорення, залежно від середовища.

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

Зробіть три речі цього тижня:

  1. Опишіть своє навантаження в одному абзаці: розмір блоку, мікс чит/запис, вимоги до sync і очікувана конкуренція. Якщо ви не можете це описати, ви не зможете купити під нього обладнання.
  2. Створіть невеликий fio-набір (2–4 задачі) і запустіть його на одному SATA SSD і одному NVMe у вашому середовищі. Зафіксуйте p95/p99/p99.9 латентності.
  3. Встановіть базову лінію і захищайте її: запускайте набір на канарі перед змінами ядра/прошивки. Регресії сховища підступні; базові показники роблять їх голосними.

Якщо ви будуєте сервіси чутливі до латентності або запускаєте мультиорендні хости, за замовчуванням використовуйте NVMe для гарячого шляху і виправдовуйте SATA лише вимірюванням. Якщо ж ви працюєте з теплими/холодними шарами, бекапами або низькоконкурентними read-most навантаженнями, SATA може бути раціональним з точки зору вартості. У будь-якому випадку тест робочого навантаження закінчує дискусію — і запобігає відправленню інциденту зберігання як нової фічі.

← Попередня
Залежність від постачальника: історії жахів і як безболісно вийти
Наступна →
Виявлено IP-конфлікт: швидко знайдіть винуватця

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