Testy NVMe jak mierzyć IOPS i opóźnienia oraz wykrywać spadki wydajności dysku

0
171
1/5 - (3 votes)

Nawigacja:

Dlaczego wydajność NVMe bywa złudna – kontekst i typowe oczekiwania

Marketingowe MB/s kontra rzeczywista wydajność I/O

Specyfikacje dysków NVMe zwykle eksponują dwa parametry: maksymalny odczyt sekwencyjny i maksymalny zapis sekwencyjny wyrażone w MB/s lub GB/s. Na tej podstawie można odnieść wrażenie, że każdy nośnik NVMe „z definicji” jest wielokrotnie szybszy od SATA SSD, a już na pewno od dysków talerzowych. W praktyce takie wartości opisują dość wąski scenariusz – duże, sekwencyjne transfery, rozgrzany bufor i optymalne warunki termiczne.

Rzeczywiste obciążenia użytkowników i aplikacji rzadko są idealnie sekwencyjne. System operacyjny, baza danych, masowe logowanie zdarzeń czy wirtualizacja generują głównie operacje losowe o małych blokach. W takich scenariuszach kluczowe są IOPS (liczba operacji I/O na sekundę) oraz opóźnienia (czas obsługi pojedynczego I/O wyrażony w milisekundach lub mikrosekundach), a nie tylko „suwak” w MB/s.

Nadmierne skupienie na przepustowości sekwencyjnej prowadzi do złudzenia, że jeśli benchmark pokazuje 6–7 GB/s, to aplikacje biznesowe będą działały błyskawicznie. Tymczasem o komforcie pracy z systemem czy aplikacją często decyduje to, czy średnie opóźnienie operacji 4K mieści się w kilkuset mikrosekundach i czy rzadkie „piki” opóźnień nie wybijają użytkowników z rytmu.

Charakterystyka NVMe: wiele kolejek i zależność od platformy

NVMe zostało zaprojektowane z myślą o równoległości. Standard przewiduje wiele kolejek poleceń, z których każda może mieć znaczną głębokość. Pozwala to na efektywne wykorzystanie wielu rdzeni CPU oraz równoległą pracę wewnętrznych kanałów pamięci flash. Dlatego wydajność NVMe zależy bezpośrednio od liczby wątków generujących I/O oraz konfiguracji kolejek.

W środowisku z jednym wątkiem i płytką kolejką (np. queue depth = 1) różnica między dobrym SATA SSD a NVMe bywa mniejsza niż wynikałoby to z marketingu. NVMe pokazuje swój potencjał dopiero przy większym stopniu równoległości, gdy jednocześnie obsługiwanych jest wiele operacji. Co istotne, osiągnięcie wysokich IOPS może wymagać nie tylko odpowiednio skonfigurowanego narzędzia testowego, ale także właściwej affinity wątków, by uniknąć zbędnych migracji między rdzeniami CPU.

Na wynik wpływa również platforma sprzętowa: wersja PCIe, liczba linii przydzielonych dla danej karty, topologia płyty głównej (czy kontroler NVMe jest podłączony bezpośrednio do CPU, czy przez chipset), a nawet ustawienia BIOS/UEFI dotyczące zarządzania energią. Ten sam nośnik NVMe może na jednej platformie osiągać bardzo wysokie IOPS, a na innej wyraźnie niższe wartości, mimo identycznych nominalnych parametrów.

Co użytkownicy faktycznie chcą sprawdzić

Większość użytkowników nie interesuje się IOPS jako abstrakcyjnym parametrem. W praktyce chodzi o:

  • czas startu systemu – ile sekund upływa od włączenia komputera do gotowego pulpitu;
  • czas ładowania aplikacji i projektów – np. uruchamianie IDE, otwieranie dużych projektów, wczytywanie bibliotek;
  • stabilność pod obciążeniem – czy w trakcie kompilacji, eksportu wideo czy intensywnego działania bazy danych system nadal reaguje płynnie.

Aby ocenić te aspekty, suche MB/s z krótkiego benchmarku nie wystarczą. Konieczne jest podejście, które uwzględni opóźnienia w czasie, ich rozkład, wpływ temperatury, zapełnienia nośnika i to, jak zachowuje się dysk w miarę upływu godzin, a nie sekund.

Syntetyczny sprint kontra wielogodzinny maraton

Krótki benchmark, trwający kilkanaście czy kilkadziesiąt sekund, jest odpowiednikiem sprintu: pokazuje, do jakich wartości potrafi „wyskoczyć” nośnik NVMe przy korzystnych warunkach, często przy mocno wykorzystywanym buforze SLC i stosunkowo niskiej temperaturze. Dla części zastosowań jest to wystarczający test orientacyjny, ale nie mówi wiele o zachowaniu pod długotrwałym obciążeniem.

Przy wielogodzinnym zapisie duża część nośników NVMe przechodzi w tryb wyraźnie niższej prędkości po zapełnieniu bufora SLC lub osiągnięciu określonej temperatury (thermal throttling). Wówczas nominalne 3 GB/s zamienia się w relatywnie skromne wartości, a opóźnienia rosną. Długotrwałe testy stresowe, zbliżone do praktycznych wzorców dostępu, pozwalają zidentyfikować takie zjawiska i odróżnić je od chwilowych fluktuacji.

Różne nośniki danych komputerowych ułożone na szarej powierzchni
Źródło: Pexels | Autor: Andrey Matveev

Podstawowe pojęcia: IOPS, opóźnienie, throughput, QoS

IOPS – operacje na sekundę i związek z rozmiarem bloku

IOPS (Input/Output Operations Per Second) to liczba operacji wejścia/wyjścia realizowanych w ciągu sekundy. Kluczowa kwestia: pojedyncza operacja może mieć różny rozmiar, najczęściej 4K, 8K, 16K czy 128K. Dziesięć tysięcy IOPS przy blokach 4K oznacza inny transfer w MB/s niż ta sama liczba IOPS przy blokach 128K.

Można to w uproszczeniu zobrazować:

  • 10 000 IOPS przy 4K ≈ 10 000 × 4 KB ≈ 40 MB/s,
  • 10 000 IOPS przy 128K ≈ 10 000 × 128 KB ≈ 1 280 MB/s.

Dlatego interpretując IOPS, trzeba zawsze odnieść je do rozmiaru bloku. Ta sama wartość IOPS może oznaczać bardzo różne obciążenia, a dysk może zachowywać się odmiennie przy małych i dużych blokach. Dodatkowo na IOPS wpływa wzorzec dostępu (losowy vs sekwencyjny) oraz głębokość kolejki (queue depth, iodepth).

Opóźnienie: średnia, percentyle i „ogon” latencji

Opóźnienie (latencja) to czas od zainicjowania operacji I/O do jej zakończenia. Można je wyrażać w milisekundach (ms) lub mikrosekundach (µs). Średnia latencja jest użyteczna do ogólnej oceny, ale często zbyt „wygładza” problem. W praktyce kluczowe są również:

  • percentyle – np. p99 oznacza wartość, poniżej której mieści się 99% wszystkich opóźnień, p99.9 – 99,9%;
  • maksymalne opóźnienie – najwolniejsza odnotowana operacja;
  • rozkład opóźnień – czy większość operacji mieści się w wąskim przedziale, czy występuje długi „ogon” rzadkich, ale bardzo długich I/O.

Dla aplikacji interaktywnych i systemów real-time nawet niewielki odsetek bardzo wolnych operacji może być bardziej dotkliwy niż lekko podwyższona średnia. Stąd nacisk na QoS (Quality of Service), rozumiane jako stabilność opóźnień, a nie wyłącznie wartość średnia czy szczytowa przepustowość.

Przepustowość a IOPS – kiedy który parametr ma znaczenie

Przepustowość (throughput) wyrażana w MB/s lub GB/s jest kluczowa przy dużych, sekwencyjnych transferach – kopiowaniu plików wideo, obrazów dysków, archiwów. W takich sytuacjach liczba IOPS ma znaczenie pomocnicze, a liczy się głównie zdolność nośnika do utrzymywania wysokiej prędkości liniowej.

W obciążeniach losowych o małych blokach (bazy danych OLTP, system plików intensywnie korzystający z metadanych, wirtualne maszyny) priorytetowe są IOPS i latencja. Tu przepustowość jako taka bywa stosunkowo niska, ale użytkownik odczuwa płynność pracy właśnie przez to, jak szybko przetwarzane są małe, liczne operacje I/O.

Projektując scenariusze testowe, trzeba więc dopasować metryki do typu obciążenia: dla backupu – MB/s, dla bazy transakcyjnej – IOPS i latencje, dla środowiska mieszanych zadań – kombinacja obu z naciskiem na stabilność.

QoS dla dysków: stabilność, a nie tylko liczby szczytowe

QoS (Quality of Service) w kontekście nośników pamięci oznacza zwykle, jak bardzo stabilne są parametry IOPS i opóźnień w czasie. Dwa dyski mogą osiągać podobne maksymalne IOPS w krótkim benchmarku, ale:

  • pierwszy będzie utrzymywał zbliżone wartości przez wiele godzin z niewielką zmiennością latencji,
  • drugi będzie „pulsował”: okresy wysokiej wydajności przeplatane spadkami i skokami opóźnień.

Z perspektywy aplikacji biznesowej, systemu plików czy wirtualizacji istotniejsze jest to, by I/O nie „szarpało” – nawet kosztem niższego absolutnego maksimum. Dlatego podczas testów NVMe warto analizować nie tylko średnie z całego przebiegu, ale także serię odczytów w czasie, percentyle i zakresy wartości.

Jak rozmiar bloku, kolejki i wzorzec dostępu wpływają na wynik

Te same parametry nośnika NVMe potrafią przełożyć się na bardzo różne wyniki w zależności od konfiguracji testu:

  • rozmiar bloku – mniejsze bloki zwiększają liczbę operacji koniecznych do przetworzenia tej samej ilości danych, co podnosi znaczenie IOPS i opóźnień; większe bloki sprzyjają wysokim MB/s, ale mogą maskować problemy z opóźnieniami przy wielu małych operacjach;
  • queue depth / iodepth – płytka kolejka eksponuje „surową” latencję pojedynczej operacji, głębsza kolejka pozwala zapełnić wewnętrzny potencjał równoległości dysku, ale może spłaszczyć problemy z pojedynczymi wolniejszymi I/O;
  • wzorzec dostępu – sekwencyjny odczyt/zapis minimalizuje overhead związany z wyszukiwaniem bloków, losowy – obciąża wewnętrzną strukturę mapowania FTL i garbage collection.

Świadome dobranie tych parametrów do scenariuszy testowych pozwala zbliżyć się do realnych obciążeń i rzetelnie ocenić, czy obserwowane spadki wydajności NVMe wynikają z ograniczeń nośnika, czy z błędnej metodologii pomiaru.

Specyfika NVMe w porównaniu z SATA – co zmienia się w testowaniu

Równoległość i wiele kolejek NVMe

Tradycyjne interfejsy, takie jak SATA, korzystają z pojedynczej kolejki poleceń o ograniczonej głębokości. NVMe natomiast przewiduje wiele kolejek poleceń, z których każda może obsługiwać setki lub tysiące jednoczesnych I/O. Pozwala to na lepsze wykorzystanie wielordzeniowych procesorów oraz wewnętrznych zasobów pamięci flash.

W testach oznacza to, że aby „dotknąć” górnej granicy możliwości dysku NVMe, trzeba wygenerować wystarczająco równoległe obciążenie: wiele wątków, większą głębokość kolejki lub kombinację obu. Jednowątkowy test z queue depth = 1 potrafi pokazać głównie minimalne opóźnienia pojedynczych I/O, ale często nie oddaje pełnego potencjału nośnika.

W praktyce konfiguruje się narzędzia takie jak fio tak, aby używały kilku lub kilkunastu wątków (jobs) i większej głębokości kolejki (iodepth), szczególnie przy losowym odczycie i zapisie. Dzięki temu wynik jest bardziej reprezentatywny dla rzeczywistych obciążeń wielowątkowych, np. wielu procesów w systemie serwerowym lub wielu maszyn wirtualnych korzystających z tego samego NVMe.

Zależność wydajności od wątków i CPU affinity

NVMe może przynosić duże korzyści, ale jednocześnie ujawnia niedoskonałości konfiguracji CPU. Gdy wiele wątków generuje intensywne I/O, pojawia się:

  • obciążenie rdzeni związane z obsługą przerwań i kolejek NVMe,
  • koszt migracji wątków między rdzeniami (zwłaszcza w systemach NUMA),
  • wpływ planisty systemowego na kolejność obsługi zadań.

Aby testy były miarodajne, często stosuje się przypisywanie wątków (CPU affinity) do konkretnych rdzeni i dopasowanie ich do kolejek NVMe, o ile sterownik i system to umożliwiają. W przeciwnym razie wynik może bardziej odzwierciedlać ograniczenia CPU i planisty niż realne możliwości samego dysku.

W systemach produkcyjnych problem może ujawnić się w subtelny sposób: w godzinach szczytu, gdy CPU jest dodatkowo obciążony innymi procesami, rosną nie tyle IOPS, co opóźnienia I/O. Diagnostyka w oparciu o same benchmarki syntetyczne, uruchamiane w spoczynku, nie pokaże takiego obrazu. Konieczna jest korelacja: obciążenie CPU, liczba aktywnych wątków oraz statystyki NVMe.

Rola PCIe i ustawień BIOS/UEFI

Interfejs PCI Express pełni kluczową rolę w wydajności NVMe. Nośnik podłączony jako x4 Gen3 może mieć inne możliwości niż ten sam kontroler pracujący jako x4 Gen4 lub ograniczony do x2 z powodu konstrukcji laptopa. Również topologia płyty głównej (czy slot M.2 jest połączony z CPU, czy z chipsetem) ma znaczenie.

Do tego dochodzą ustawienia BIOS/UEFI, w szczególności:

Ustawienia zasilania, ASPM i zarządzanie energią

Tryby oszczędzania energii potrafią w znaczący sposób zmienić obraz wydajności NVMe. Kontroler potrafi przechodzić w stany niskiego poboru (np. APST – Autonomous Power State Transition), a łącze PCIe może być usypiane przez ASPM (Active State Power Management). Z punktu widzenia testów I/O skutkiem są dodatkowe mikroopóźnienia przy „wybudzaniu” ścieżki danych.

Na poziomie BIOS/UEFI oraz systemu operacyjnego spotyka się profile „performance” i „power saving”. W kontekście testów NVMe oraz diagnozowania spadków wydajności, zwykle sensowniejsze jest ustawienie profilu wydajnościowego, obejmujące m.in.:

  • stałe taktowanie CPU (bez agresywnego zbijania częstotliwości),
  • ograniczenie najgłębszych stanów oszczędzania energii dla PCIe (lub całkowite wyłączenie ASPM przy problematycznych konfiguracjach),
  • konfigurację APST dla NVMe tak, by kontroler nie zasypiał zbyt agresywnie przy ciągłym obciążeniu.

W środowiskach serwerowych zwykle stosuje się profil „Performance” w firmware serwera i jednocześnie konfiguruje plan zasilania w systemie (np. „High performance” w Windows Server lub „performance governor” w Linux). W laptopach i stacjach roboczych często obserwuje się pozornie przypadkowe skoki latencji, które znikają po przełączeniu profilu z „balanced” na „high performance”. Dotyczy to zwłaszcza krótkich, interaktywnych operacji – ich wyniki w benchmarkach nie oddają pełni możliwości nośnika, o ile kontroler stale zasypia.

Aktualizacja firmware i specyficzne opcje NVMe

Producenci NVMe regularnie wydają aktualizacje firmware, które poprawiają stabilność, algorytmy garbage collection oraz zachowanie w sytuacjach skrajnych (wysokie wypełnienie, długotrwały zapis). Brak aktualnego firmware’u może powodować m.in.:

  • niestabilne opóźnienia przy mieszanych obciążeniach,
  • spadki IOPS po dłuższym ciągłym zapisie,
  • błędy w implementacji APST / power states.

Podczas testów bywa sensowne porównanie zachowania dysku przed i po aktualizacji firmware, zwłaszcza jeśli producent wprost wskazuje na zmiany w zakresie wydajności lub QoS. Trzeba jednak zabezpieczyć dane (backup) i przeczytać noty wydania – zdarza się, że aktualizacja jest jednostronna (brak możliwości powrotu) albo wymaga określonej wersji sterownika.

Niektóre dyski NVMe udostępniają w firmware dodatkowe funkcje, jak np. określone limity mocy (power limits), możliwość wyłączenia lub ograniczenia części stanów niskiego poboru energii, a nawet różne „profile” wydajnościowe. Narzędzia producenta lub standardowe utilsy NVMe (np. nvme-cli) umożliwiają ich odczyt i konfigurację. Dobrze jest odnotować te ustawienia przy prowadzeniu testów, aby wyniki z różnych sesji były porównywalne.

Młotek nad dyskiem twardym i SSD symbolizujący niszczenie danych
Źródło: Pexels | Autor: Andrey Matveev

Przygotowanie środowiska testowego – system, sterowniki, konfiguracja

Sterowniki NVMe i ich wpływ na wynik

Sterownik NVMe jest elementem pośredniczącym między systemem a kontrolerem dysku. W systemach Linux używany jest zwykle sterownik w jądrze (nvme), w Windows – domyślny driver Microsoft lub dedykowany sterownik producenta (np. Samsung, Intel, Kioxia). W praktyce różnice między nimi bywają subtelne, ale przy dużych obciążeniach mogą wpływać na:

  • maksymalną liczbę obsłużonych IOPS,
  • stabilność latencji przy wysokiej queue depth,
  • zachowanie w sytuacjach błędów i odzyskiwania.

Konfigurując środowisko testowe, dobrze jest wykonać krótkie, orientacyjne testy zarówno na sterowniku systemowym, jak i – jeżeli jest dostępny – dedykowanym sterowniku producenta. Różnice w wynikach, nawet jeśli niewielkie, pozwalają lepiej zrozumieć, który komponent ogranicza wydajność w konkretnym scenariuszu.

System plików, tryb dostępu i wpływ cache

Testy można prowadzić bezpośrednio na urządzeniu blokowym (np. /dev/nvme0n1) albo na systemie plików (np. XFS, ext4, NTFS). Każde podejście mierzy coś innego:

  • test na urządzeniu blokowym – pokazuje „surowe” możliwości nośnika i kontrolera, bez wpływu struktury katalogów, alokatora bloków i dziennika (journal);
  • test na systemie plików – zbliża się do realnej pracy aplikacji, ale wprowadza dodatkowe zmienne (optymalizacja FS, parametry montowania, journaling).

System plików oraz cache systemowy potrafią maskować lub wyolbrzymiać problemy. Przykładowo, test sekwencyjnego odczytu małych plików może w istocie mierzyć wydajność cachu RAM, jeśli dane mieszczą się w pamięci i nie są skutecznie „wyrzucane” między przebiegami. Z drugiej strony, intensywny zapis przy synchronicznym journalu na niektórych systemach plików może mocniej obciążać NVMe niż analogiczny test bez systemu plików, przez co wyniki obu podejść nie będą porównywalne bez dodatkowego komentarza.

Aby wyniki miały sens, trzeba jasno zdefiniować, co ma być badane. Przy diagnozowaniu czystej wydajności NVMe zazwyczaj zaczyna się od testów na raw device, dopiero później przechodząc do pomiarów na systemie plików z konfiguracją zbliżoną do produkcyjnej.

Wyrównanie partycji, rozmiar bloków i sektorów logicznych

Nowoczesne systemy zazwyczaj prawidłowo wyrównują partycje do granic 1 MB lub 4 MB, co jest bezpieczne dla nośników flash. Zdarzają się jednak scenariusze migracji starych systemów, gdzie partycje są przesunięte lub oparte o nietypowe rozmiary sektorów. W efekcie pojedynczy logiczny zapis może wymagać od dysku modyfikacji dwóch lub więcej wewnętrznych bloków, co zwiększa latencję i generuje dodatkowe write amplification.

Przed rozpoczęciem testów warto przeanalizować:

  • czy partycje zaczynają się na granicy co najmniej 1 MB,
  • jaki jest logiczny rozmiar sektora widoczny w systemie (512e vs 4K),
  • czy nie używa się nietypowych ustawień, np. wymuszonych sektorów 512 B na nośniku zoptymalizowanym pod 4K.

Nieprawidłowe wyrównanie nie zniszczy nośnika od razu, ale przy długotrwałych obciążeniach losowych może drastycznie obniżyć IOPS i zwiększyć opóźnienia. W testach syntetycznych wygląda to jak „dziwnie wolny” dysk NVMe w porównaniu z identycznym modelem, ale świeżo zainicjalizowanym z prawidłowym wyrównaniem.

Wyłączenie zbędnych usług i zakłóceń w tle

System operacyjny w normalnej pracy wykonuje wiele zadań w tle: indeksowanie, skanowanie antywirusowe, aktualizacje, kompresję czy deduplikację. W testach NVMe takie aktywności potrafią:

  • wstrzykiwać losowe operacje I/O,
  • przenosić dane między nośnikiem a RAM (prefetching, caching),
  • okresowo podbijać wykorzystanie CPU.

Dlatego podczas pomiarów zwykle wyłącza się lub ogranicza działanie usług, które mogą wpływać na operacje dyskowe. Dotyczy to w szczególności: skanera antywirusowego (czasowo, na potrzeby testu), indeksowania wyszukiwania, narzędzi backupowych działających w tle, a w środowisku serwerowym – zadań cron/Task Scheduler, które intensywnie korzystają z I/O.

W praktyce dobrze jest podczas testu mieć uruchomiony monitoring (np. top, iotop, dstat, PerfMon), aby wychwycić nietypowe skoki obciążenia niepochodzące z samego narzędzia testowego. Bez tego łatwo zinterpretować chwilowy pik opóźnień jako problem z NVMe, podczas gdy faktyczną przyczyną jest np. aktualizacja bazy sygnatur antywirusa.

Stan zapełnienia dysku, TRIM i przygotowanie przed testem

Wydajność NVMe jest silnie zależna od stanu zapełnienia nośnika i tego, jak kontroler zarządza wolną przestrzenią. Świeżo po zainstalowaniu dysk bywa szybki, lecz po zapełnieniu i wielokrotnym nadpisaniu danych jego zachowanie może się zmienić. Wynika to z pracy wewnętrznego FTL (Flash Translation Layer) oraz garbage collection.

Przed poważniejszymi testami warto:

  • ustalić, czy kontroler ma wystarczającą ilość wolnej przestrzeni (overprovisioning),
  • przeprowadzić pełny lub częściowy zapis dysku, aby zasymulować stan „używany”,
  • upewnić się, że system regularnie wysyła komendy TRIM/UNMAP, dzięki czemu nośnik wie, które bloki są faktycznie wolne.

Brak TRIM w systemie (lub jego wyłączenie) powoduje, że z perspektywy dysku wszystkie zapisane kiedyś bloki wyglądają na zajęte. Kontroler musi wówczas intensywniej przemieszczać dane i czyścić bloki przed zapisem, co objawia się wzrostem opóźnień oraz spadkiem stabilności IOPS przy losowym zapisie. Podczas testów, zwłaszcza długotrwałych, dobrze jest obserwować, czy wyniki nie „rozjeżdżają się” wraz ze wzrostem zapełnienia.

Zbliżenie na serwerowy rack z macierzami dysków NVMe
Źródło: Pexels | Autor: panumas nikhomkhai

Narzędzia do testów NVMe: fio, ioping, CrystalDiskMark, narzędzia producentów

fio – elastyczny standard w świecie Linux i nie tylko

fio (Flexible I/O Tester) jest jednym z najbardziej wszechstronnych narzędzi do testów I/O. Pozwala precyzyjnie definiować rozmiary bloków, wzorzec dostępu, głębokość kolejki, liczbę wątków, a także czas trwania testu czy sposób raportowania wyników. Dzięki temu można zbudować scenariusze bliskie rzeczywistym obciążeniom NVMe.

Podstawowe parametry fio, które są istotne przy testach NVMe, obejmują m.in.:

  • rw= – typ obciążenia (np. randread, randwrite, readwrite, randrw),
  • bs= – rozmiar bloku (np. 4k, 8k, 128k),
  • iodepth= – głębokość kolejki (np. 1, 32, 64),
  • numjobs= – liczba wątków/zadań generujących obciążenie,
  • direct=1 – tryb omijający cache systemowy (bezpośredni dostęp do urządzenia),
  • runtime= i time_based=1 – czas trwania testu.

Przykładowy test losowego odczytu 4K z queue depth 32 na surowym urządzeniu NVMe może wyglądać tak:

fio --name=randread_4k_qd32 
    --filename=/dev/nvme0n1 
    --rw=randread --bs=4k 
    --iodepth=32 --numjobs=4 
    --direct=1 --time_based=1 
    --runtime=60 --group_reporting

Tak skonfigurowany test pozwala ocenić zarówno łączną liczbę IOPS, jak i rozkład opóźnień. fio raportuje także percentyle latencji, co jest szczególnie użyteczne przy analizie QoS NVMe.

ioping – szybka ocena latencji

ioping to lekkie narzędzie służące głównie do szybkiego sprawdzania opóźnień dostępu do bloku danych. Działa podobnie do ping, ale zamiast pakietów sieciowych wysyła operacje I/O. Wynikiem jest seria czasów odpowiedzi, z których można wyciągnąć średnią, odchylenie standardowe oraz wartości minimalne i maksymalne.

ioping sprawdza się szczególnie w sytuacjach, gdy trzeba wstępnie określić, czy NVMe reaguje w przedziale kilkudziesięciu czy kilkuset mikrosekund przy lekkim obciążeniu. Jest mniej elastyczny niż fio, ale jego prostota ułatwia szybkie testy porównawcze – np. przed i po zmianie ustawień BIOS/UEFI lub profilu zasilania.

CrystalDiskMark – popularne narzędzie na Windows

CrystalDiskMark jest powszechnie używany na stacjach roboczych z Windows do szybkiego porównywania dysków. Oferuje kilka predefiniowanych scenariuszy testowych (sekwencyjny i losowy odczyt/zapis przy różnych rozmiarach bloków i queue depth), a wyniki przedstawia w przejrzystej formie graficznej.

Do testów NVMe istotne są głównie:

  • test sekwencyjny 1M Q8T1 – orientacyjna przepustowość przy większej głębokości kolejki,
  • test losowy 4K Q32T16 lub podobne – wskaźnik IOPS oraz latencji przy małych blokach,
  • powtarzalność wyników między kolejnymi przebiegami (stabilność).

CrystalDiskMark nie zastąpi specjalistycznych narzędzi w środowisku serwerowym, ale dobrze nadaje się do wykrycia oczywistych problemów: dysk NVMe działający jak typowy SATA SSD, radykalne różnice między odczytem a zapisem, czy też zauważalne spadki wyników po kolejnych przebiegach.

Narzędzia producentów i diagnostyka SMART/health

Producenci NVMe udostępniają własne programy, takie jak Samsung Magician, Intel MAS, WD Dashboard czy Toshiba/Kioxia SSD Utility. Zawierają one zazwyczaj:

  • podstawowe testy wydajności (sekwencyjny i losowy odczyt/zapis),
  • monitoring temperatury i stanu zdrowia dysku,
  • nvme-cli, smartctl i logi – jak powiązać wyniki testów z kondycją dysku

    Same liczby IOPS i latencji niewiele mówią bez kontekstu stanu nośnika. Przy NVMe kluczowe są logi kontrolera oraz atrybuty health/SMART. Na Linuksie najczęściej korzysta się z nvme-cli oraz smartctl z pakietu smartmontools.

    Podstawowe komendy diagnostyczne dla NVMe to m.in.:

    nvme smart-log /dev/nvme0
    nvme error-log /dev/nvme0
    nvme list
    smartctl -a /dev/nvme0
    

    Przy analizie spadków wydajności przydają się szczególnie:

  • zużycie TBW / procent życia – niektóre dyski po przekroczeniu określonego progu aktywują konserwatywne algorytmy zarządzania flash, co w praktyce obniża throughput zapisu i stabilność IOPS,
  • liczba błędów korekcji i media errors – rosnąca liczba błędów przekłamanych bloków może powodować skoki latencji (kontroler walczy o korekcję danych),
  • limity temperatury i throttle events – wejście w tryb thermal throttling prawie zawsze widać w historii logów jako przekroczenie progów temp.,
  • zarejestrowane błędy komend – timeouty lub reset kontrolera często korelują z okresowymi „dziurami” w wykresie IOPS.

Jeżeli w trakcie testu fio pojawiają się epizodyczne piki latencji, a w logach NVMe odnotowane są resetowane kolejki lub błędy dostępu do medium, źródło problemu zwykle leży niżej niż sam system plików: w firmware, zasilaniu, chłodzeniu albo wady sprzętowej. W takich przypadkach powtarzanie testów syntetycznych bez analizy logów prowadzi tylko do rejestrowania kolejnych, równie „dziwnych” przebiegów.

Jak poprawnie mierzyć IOPS i opóźnienia – scenariusze testowe

Dobór rozmiaru bloków i mieszanki odczyt/zapis

IOPS i latencja NVMe są silnie zależne od rozmiaru bloków. Drobne bloki (np. 4K) dają wysoką liczbę operacji na sekundę, ale relatywnie niską przepustowość w MB/s, natomiast duże bloki (128K i więcej) zwiększają throughput kosztem liczby operacji. W typowych scenariuszach wykorzystuje się zestaw kilku rozmiarów, np.:

  • 4K – symulacja drobnych, losowych I/O typowych dla baz danych, metadanych systemu plików, małych plików,
  • 16K–32K – częsty kompromis w aplikacjach serwerowych,
  • 64K–128K – zbliżenie do sekwencyjnych transferów przy backupach i odczycie dużych plików.

Odrębna kwestia to proporcja odczytu do zapisu. Nośnik zachowuje się inaczej przy czystym odczycie niż przy intensywnym zapisie losowym. Praktyczne profile to m.in.:

  • 100% read – odczyt dominujący (np. serwery treści statycznych, cache),
  • 70/30 read/write – typowe obciążenie wielu baz OLTP, systemów pocztowych i systemów ERP,
  • 50/50 – sytuacje mocno mieszane, w których ważna jest stabilność QoS,
  • 100% write – scenariusz najbardziej obciążający FTL, używany głównie do wywołania stanu „używanego” nośnika oraz badania garbage collection.

Przy projektowaniu testu należy dobrać nie tylko parametry, ale też ich uzasadnienie: czy chodzi o symulację konkretnej aplikacji, czy jedynie o sprawdzenie, czy nośnik zbliża się do deklarowanych przez producenta wartości granicznych.

Queue depth i liczba wątków – jak nie przeszacować możliwości dysku

NVMe została zaprojektowana z myślą o dużej równoległości. Producent podaje zazwyczaj wyniki IOPS dla losowego odczytu/zapisu 4K przy queue depth rzędu 32–256 i często przy kilku kolejkach jednocześnie. W praktyce wiele aplikacji wykorzystuje dużo mniejszą głębokość kolejki. Stąd różnica między „papierem” a rzeczywistością.

Przykładowe poziomy QD do testów:

  • QD=1 – opóźnienie przy braku kolejkowania, dobra miara „gołej” latencji NVMe,
  • QD=4–8 – umiarkowane obciążenie, często zbliżone do tego, co generuje pojedyncza aplikacja,
  • QD=32 i więcej – wykorzystywanie pełnego potencjału równoległości, charakterystyczne dla środowisk wirtualizacyjnych lub silników baz danych skonfigurowanych agresywnie.

Liczbę wątków numjobs w fio zwykle zestawia się z queue depth. Jeden z sensownych schematów to: kilka wątków (np. 4–8) z umiarkowanym QD (np. 8–16). Zbyt wysoka suma równoległych I/O może jednak dusić CPU lub scheduler I/O w jądrze, co zniekształca wyniki. Sytuacje, w których QD=256 daje „gorsze” IOPS niż QD=64, często sygnalizują właśnie wejście w granice możliwości systemu operacyjnego lub samej aplikacji testującej, a nie NVMe.

Czas trwania testu i faza rozgrzewki (warm-up)

Krótkotrwałe testy (np. po 10–15 sekund) pokazują głównie zachowanie kontrolera w stanie „burst”, z pełnymi buforami i jeszcze niewywołanym garbage collection. To bywa mylące. Dla realnej oceny QoS ważne jest zachowanie po ustaleniu stanu równowagi.

Standardową praktyką jest rozdzielenie testu na:

  • faza rozgrzewki – kilka do kilkunastu minut intensywnego I/O, dane z tego okresu można odrzucić albo raportować osobno,
  • faza pomiarowa – co najmniej kilka minut stabilnego obciążenia, z którego zbiera się metryki IOPS i latencji.

W fio realizuje się to poprzez osobne joby albo przez uruchomienie testu na dłużej i analizę tylko końcowego fragmentu. Zbyt krótkie testy dają ładne liczby w tabelce, ale nie pokażą, czy po 30 minutach obciążenia losowym zapisem losowe próby nie zaczynają sporadycznie trwać kilkanaście milisekund zamiast kilkuset mikrosekund.

Analiza percentyli latencji i ogona rozkładu

Średnia latencja jest wygodna, ale bywa myląca. Dwa nośniki mogą mieć podobną średnią, a zupełnie inną stabilność. Przy diagnozie QoS NVMe bardziej użyteczne są percentyle, szczególnie:

  • p95 – 95% operacji kończy się szybciej niż wskazana wartość,
  • p99 – 99% operacji mieści się w tym czasie,
  • p99.9 i dalej – istotne w środowiskach o wysokich wymaganiach SLA.

fio potrafi raportować percentyle bezpośrednio, np. przy włączeniu histogramu latencji. Jeżeli dla NVMe średnia latencja 4K randread wynosi 100 µs, ale p99 wynosi 5 ms, a p99.9 sięga 20 ms, oznacza to duży „ogon” rozkładu. W praktyce użytkownik odczuje to jako sporadyczne przywieszanie aplikacji, mimo „ładnych” wartości średnich.

Takie pogorszenie ogona rozkładu może wynikać z:

  • pracy garbage collection w tle przy wysokim zapełnieniu,
  • restrykcyjnego zarządzania termiką (thermal throttling),
  • współdzielenia PCIe z innymi urządzeniami generującymi burstowe transfery,
  • ręcznych limitów I/O w warstwie hypervisora lub systemu plików.

Z tego względu przy interpretacji testów NVMe zestawia się zazwyczaj co najmniej trzy wielkości: średnią, p99 oraz maksymalną latencję zaobserwowaną w danym odstępie czasu.

Testy losowe vs sekwencyjne – jak ich nie mylić

Wiele popularnych benchmarków prezentuje wyniki sekwencyjne i losowe w jednej tabeli, co może prowadzić do błędnych wniosków. NVMe osiągają bardzo wysoką przepustowość przy odczycie sekwencyjnym, jednak typowe obciążenie produkcyjne jest znacznie bardziej fragmentaryczne.

Przy projektowaniu scenariusza testowego zwykle przeprowadza się osobno:

  • sekwencyjny odczyt/zapis (np. rw=read, rw=write z dużym bs=128k i QD od kilku do kilkudziesięciu) – obraz maksymalnej przepustowości magistrali PCIe oraz kontrolera,
  • losowy odczyt (np. rw=randread, małe bloki 4K–8K) – faktyczny wskaźnik responsywności przy typowych operacjach metadanych i baz danych,
  • losowy zapis (np. rw=randwrite lub domieszka zapisu) – najbardziej obciążający element z punktu widzenia trwałości i stabilności IOPS.

Jeżeli sekwencyjny odczyt 128K QD32 osiąga zbliżoną do specyfikacji przepustowość, ale losowy odczyt 4K QD4 wypada bardzo słabo, źródła problemu należy szukać raczej w konfiguracji systemu plików, schedulerze I/O, trybie zasilania czy w wirtualizacji niż w samej przepustowości interfejsu PCIe.

Jak wykrywać spadki wydajności w czasie trwania testu

Stałe IOPS i stabilna latencja przez cały czas trwania testu są bardziej wartościowe niż imponujący pik na początku. Do wychwytywania spadków wydajności używa się dwóch podejść:

  • monitoring zewnętrzny – narzędzia takie jak iostat, dstat, vmstat, PerfMon lub dedykowane systemy monitoringu, które zbierają dane co kilka sekund,
  • szczegółowy log z narzędzia testowego – np. w fio --log_avg_msec=1000 oraz logi IOPS/latencji do plików CSV do późniejszej analizy.

Podejrzane są w szczególności:

  • powtarzające się okresowe „dołki” IOPS z jednoczesnym wzrostem latencji – cykliczne przebudowywanie tablic FTL lub kolizje z zadaniami systemowymi,
  • stopniowy spadek IOPS przy losowym zapisie wraz ze wzrostem zapełnienia testowego obszaru – brak TRIM lub zbyt mały overprovisioning,
  • gwałtowne skoki opóźnień korelujące z wzrostem temperatury – dysk wchodzi w throttling.

W praktyce, jeżeli log fio w formacie CSV zostanie wczytany do arkusza kalkulacyjnego lub narzędzia typu Grafana, nietrudno wskazać moment, od którego NVMe przestaje utrzymywać równą linię IOPS. To ten fragment testu jest najcenniejszy diagnostycznie, a nie pierwszy „idealny” kawałek krzywej.

Scenariusze „realistyczne” – łączenie testów syntetycznych z obciążeniem aplikacyjnym

Syntetyczne testy fio lub CrystalDiskMark są użyteczne, ale nie odzwierciedlają w pełni zachowania konkretnych aplikacji. Dobrym podejściem jest zestawienie dwóch rodzajów testów:

  • testów syntetycznych – z dobrze zdefiniowanymi parametrami, ułatwiających powtarzalność i porównania,
  • testów aplikacyjnych – np. benchmarków bazodanowych, sztucznych obciążeń serwera plików, testów narzędziami dostarczanymi z aplikacją.

Przykładowo, dla systemu bazodanowego można przygotować:

  • fio z profilem losowego odczytu/zapisu 70/30, 8K, QD=4–16, aby odtworzyć typowe I/O logów i tabel,
  • następnie uruchomić standardowy benchmark bazy (np. pgbench dla PostgreSQL, TPC-like dla innych) i w tym czasie monitorować IOPS oraz latencję NVMe.

Jeżeli dysk wypada dobrze w fio, ale aplikacja nadal obserwuje piki opóźnień, problem może leżeć w innych warstwach: blokadach w bazie, konfiguracji buforów, ograniczeniach narzędzi wirtualizacyjnych czy współdzieleniu tego samego NVMe przez wiele wirtualnych maszyn z nakładającymi się wzorcami I/O.

Testy degradacji (steady state) i wpływ zapełnienia

Nowy, częściowo pusty dysk NVMe niemal zawsze wypada lepiej niż ten sam nośnik po kilku miesiącach intensywnej pracy. Aby ocenić zachowanie w stanie „ustabilizowanym”, stosuje się tzw. testy degradacji lub steady state.

Typowy schemat obejmuje:

  1. preconditioning – wielokrotny zapis całego nośnika (np. kilkukrotne przejście pełnym zapisem sekwencyjnym, a następnie losowym),
  2. ustalenie poziomu zapełnienia – np. pozostawienie około 20–30% wolnej przestrzeni, jeśli taka jest zakładana w produkcji,
  3. długotrwały test losowy – utrzymywanie intensywnego obciążenia przez kilka godzin, aż IOPS i latencja przestaną wykazywać trend spadkowy.

Najczęściej zadawane pytania (FAQ)

Jak prawidłowo mierzyć IOPS dysku NVMe?

IOPS mierzy się, generując określony wzorzec obciążenia: rozmiar bloku (np. 4K), typ dostępu (losowy/sekwencyjny), kierunek (odczyt/zapis) oraz głębokość kolejki (queue depth). Narzędzia takie jak fio, Iometer czy CrystalDiskMark pozwalają to dokładnie ustawić i odczytać wynik jako liczbę operacji na sekundę.

Kluczowe jest, aby podawać IOPS zawsze łącznie z parametrami testu, np. „losowy odczyt 4K, QD32, 4 wątki”. Ta sama liczba IOPS przy blokach 4K i 128K oznacza zupełnie inną ilość przesyłanych danych, a więc inne obciążenie dla dysku i systemu.

Co jest ważniejsze przy NVMe: IOPS czy MB/s?

Dla dużych, sekwencyjnych transferów (kopiowanie plików wideo, obrazów ISO, backupy) ważniejsza jest przepustowość wyrażona w MB/s lub GB/s. W takim scenariuszu liczy się zdolność nośnika do utrzymania wysokiej prędkości liniowej przez dłuższy czas.

Przy typowych obciążeniach systemu i aplikacji – małe, liczne operacje losowe (4K, 8K) – kluczowe są IOPS i opóźnienia. To one decydują, jak szybko startuje system, jak reaguje IDE czy przeglądarka podczas intensywnego obciążenia. W praktyce oba parametry są istotne, ale dla baz danych, VM i systemu plików pierwszeństwo ma IOPS i latencja.

Jak interpretować opóźnienia (latencję) dysku NVMe w testach?

Opóźnienie to czas obsługi pojedynczej operacji I/O, zwykle podawany w ms lub µs. Średnia latencja daje ogólny obraz, ale bywa myląca. Dwa dyski mogą mieć podobną średnią, a jednocześnie zupełnie inny „ogon” bardzo wolnych operacji.

Dlatego analizuje się także percentyle (np. p99, p99.9) oraz maksymalne opóźnienie. Jeśli p99 jest kilkukrotnie wyższe od średniej, aplikacje interaktywne mogą „przywieszać się” mimo pozornie dobrych wyników. Dla płynnej pracy istotne jest, aby większość operacji mieściła się w wąskim przedziale czasowym, bez częstych, skrajnych skoków.

Dlaczego mój dysk NVMe ma w testach mniejszą przewagę nad SATA niż w reklamach?

W scenariuszu z jednym wątkiem i płytką kolejką (queue depth = 1) przewaga NVMe nad dobrym SATA SSD bywa ograniczona. Standard NVMe zyskuje dopiero przy większej równoległości – wielu wątkach generujących I/O i większej głębokości kolejek. Reklamowe wartości zakładają właśnie taki, mocno równoległy scenariusz.

Dodatkowo wynik zależy od platformy: wersji PCIe, liczby linii, podłączenia kontrolera (bezpośrednio do CPU czy przez chipset) oraz ustawień zasilania w BIOS/UEFI. Ten sam nośnik może na jednej płycie osiągać bardzo wysokie IOPS, a na innej wyraźnie niższe wartości, mimo identycznych nominalnych parametrów.

Skąd biorą się spadki wydajności NVMe po kilku minutach lub godzinach testu?

Wielu producentów stosuje bufor SLC, który przy krótkich testach sztucznie „dopala” prędkości zapisu. Po jego zapełnieniu dysk przechodzi do wolniejszego trybu zapisu TLC/QLC i przepustowość może spaść kilkukrotnie. Długotrwałe testy ujawniają ten efekt, krótkie „sprinty” zwykle nie.

Drugim typowym powodem jest thermal throttling – po osiągnięciu określonej temperatury kontroler ogranicza wydajność, aby się nie przegrzać. W praktyce oznacza to, że po kilkunastu–kilkudziesięciu minutach ciągłego obciążenia latencje rosną, a transfery spadają do poziomu, który dysk jest w stanie utrzymać w dłuższej perspektywie.

Jak sprawdzić QoS (stabilność) dysku NVMe, a nie tylko maksymalne wyniki?

Aby ocenić QoS, stosuje się dłuższe testy (co najmniej kilkanaście–kilkadziesiąt minut, często godziny) z obciążeniem zbliżonym do realnego: mieszane odczyty/zapisy, małe i średnie bloki, zapełniony nośnik. Istotne jest monitorowanie nie tylko średniej latencji, ale całego rozkładu opóźnień, percentyli oraz zmian w czasie.

Dysk o dobrym QoS utrzymuje względnie stałe IOPS i stabilne opóźnienia, bez częstych „dziur” wydajności i skoków latencji. Jeśli wyniki „pulsują” – raz bardzo dobrze, raz wyraźnie gorzej – może to oznaczać agresywne GC, słaby firmware lub problemy termiczne.

Czy krótkie benchmarki NVMe (np. 30 sekund) mają sens?

Krótkie benchmarki dobrze pokazują potencjał szczytowy dysku NVMe w sprzyjających warunkach: świeży nośnik, zimna obudowa, pusty bufor SLC. Mogą być pomocne przy wstępnej weryfikacji, czy dysk działa prawidłowo i czy osiąga wartości zbliżone do deklarowanych w specyfikacji.

Nie mówią jednak zbyt wiele o zachowaniu pod długotrwałym, mieszanym obciążeniem – takim, z którym spotyka się system operacyjny, baza danych czy środowisko wirtualizacji. Aby wykryć spadki wydajności po zapełnieniu bufora czy występowanie długich „ogonów” latencji, potrzebne są dłuższe, bardziej realistyczne testy.

Kluczowe Wnioski

  • Deklarowane w specyfikacji MB/s dotyczą głównie dużych, sekwencyjnych transferów w idealnych warunkach (rozgrzany bufor, niska temperatura) i nie opisują typowych, losowych obciążeń systemu czy bazy danych.
  • O realnym odczuciu „szybkości” decydują przede wszystkim IOPS i opóźnienia małych operacji (np. 4K), a nie maksymalny throughput – to one wpływają na czas startu systemu, ładowanie aplikacji i płynność pracy pod obciążeniem.
  • NVMe ujawnia pełen potencjał dopiero przy większej równoległości (wiele wątków, głębsze kolejki); przy pojedynczym wątku i queue depth = 1 przewaga nad dobrym SATA SSD bywa znacznie mniejsza, niż sugeruje marketing.
  • Wydajność NVMe silnie zależy od platformy (wersja i liczba linii PCIe, sposób podłączenia do CPU lub chipsetu, ustawienia zasilania w BIOS/UEFI oraz affinity wątków), więc ten sam nośnik może dawać bardzo różne wyniki na różnych konfiguracjach.
  • Krótkie benchmarki są odpowiednikiem sprintu – pokazują szczytowe wartości przy korzystaniu z bufora SLC i niskich temperatur, ale nie ujawniają spadków wydajności po jego zapełnieniu ani skutków thermal throttlingu.
  • Do oceny dysku przy obciążeniach zbliżonych do produkcyjnych potrzebne są dłuższe testy, mierzące latencję w czasie (wraz z percentylami typu p99/p99.9) oraz wpływ temperatury i zapełnienia nośnika, a nie tylko jednorazowy pomiar średniego MB/s.