Varför är min NVMe långsammare än en SSD?

Varför är min NVMe långsammare än en SSD?
I den här artikeln kommer vi att titta på några av nyanserna i I/O-delsystemet och deras inverkan på prestanda.

För ett par veckor sedan ställdes jag inför frågan varför NVMe på en server var långsammare än SATA på en annan. Jag tittade på serverspecifikationerna och insåg att detta var en knepig fråga: NVMe var från användarsegmentet och SSD var från serversegmentet.

Uppenbarligen är det inte rättvist att jämföra produkter från olika segment i olika miljöer, men detta är inte ett komplett tekniskt svar. Låt oss studera grunderna, genomföra experiment och ge ett svar på den ställda frågan.

Vad är fsync och var används det?

För att påskynda arbetet med enheter buffras data, det vill säga lagras i flyktigt minne tills en lämplig möjlighet ger sig att spara innehållet i bufferten till enheten. Kriterierna för en "möjlighet" bestäms av operativsystemet och enhetens egenskaper. Vid strömavbrott kommer all data i bufferten att gå förlorad.

Det finns ett antal uppgifter där du måste vara säker på att ändringar i en fil skrivs till enheten och inte i en mellanbuffert. Denna garanti kan erhållas genom att använda det POSIX-kompatibla fsync-systemanropet. Att anropa fsync tvingar fram en skrivning från bufferten till enheten.

Låt oss demonstrera effekten av buffertar med ett artificiellt exempel i form av ett kort program i C.

#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(void) {
    /* Открываем файл answer.txt на запись, если его нет -- создаём */
    int fd = open("answer.txt", O_WRONLY | O_CREAT);
    /* Записываем первый набор данных */
    write(fd, "Answer to the Ultimate Question of Life, The Universe, and Everything: ", 71);
    /* Делаем вид, что проводим вычисления в течение 10 секунд */
    sleep(10);
    /* Записываем результат вычислений */
    write(fd, "42n", 3); 

    return 0;
}

Kommentarerna förklarar väl sekvensen av åtgärder i programmet. Texten "svaret på huvudfrågan om livet, universum och allt det där" kommer att buffras av operativsystemet, och om du startar om servern genom att trycka på Reset-knappen under "beräkningar", kommer filen att vara tom. I vårt exempel är textförlust inte ett problem, så fsync behövs inte. Databaser delar inte denna optimism.

Databaser är komplexa program som samtidigt arbetar med många filer, så de vill vara säkra på att data de skriver kommer att sparas på enheten, eftersom konsistensen av data inuti databasen beror på detta. Databaser är utformade för att registrera alla genomförda transaktioner och vara redo att tappa ström när som helst. Detta beteende kräver användning av fsync konstant i stora kvantiteter.

Vad är effekten av frekvent användning av fsync?

Under normal I/O försöker operativsystemet optimera kommunikationen med diskar, eftersom externa enheter är de långsammaste i minneshierarkin. Därför försöker operativsystemet att skriva så mycket data som möjligt i en åtkomst till enheten.

Låt oss demonstrera effekten av att använda fsync med ett specifikt exempel. Vi har följande SSD:er som testenheter:

  • Intel® DC SSD S4500 480 GB, ansluten via SATA 3.2, 6 Gbit/s;
  • Samsung 970 EVO Plus 500GB, ansluten via PCIe 3.0 x4, ~31 Gbit/s.

Tester utförs på en Intel® Xeon® W-2255 som kör Ubuntu 20.04. Sysbench 1.0.18 används för att testa diskar. En partition har skapats på diskarna, formaterad som ext4. Att förbereda för testet innebär att skapa 100 GB filer:

sysbench --test=fileio --file-total-size=100G prepare

Löpande tester:

# Без fsync
sysbench --num-threads=16 --test=fileio --file-test-mode=rndrw --file-fsync-freq=0 run

# С fsync после каждой записи
sysbench --num-threads=16 --test=fileio --file-test-mode=rndrw --file-fsync-freq=1 run

Testresultaten presenteras i tabellen.

Test
Intel® S4500
Samsung 970 EVO+

Läser utan fsync, MiB/s
5734.89
9028.86

Inspelning utan fsync, MiB/s
3823.26
6019.24

Läser med fsync, MiB/s
37.76
3.27

Inspelning med fsync, MiB/s
25.17
2.18

Det är lätt att se att NVMe från klientsegmentet är tryggt i täten när operativsystemet själv bestämmer hur det ska arbeta med diskar, och tappar när fsync används. Detta väcker två frågor:

  1. Varför överstiger läshastigheten i testet utan fsync kanalens fysiska bandbredd?
  2. Varför är en serversegment-SSD bättre på att hantera ett stort antal fsync-förfrågningar?

Svaret på den första frågan är enkelt: sysbench genererar filer fyllda med nollor. Således genomfördes testet över 100 gigabyte nollor. Eftersom data är mycket enhetliga och förutsägbara kommer olika OS-optimeringar in i spelet och påskyndar exekveringen avsevärt.

Om du ifrågasätter alla sysbench-resultat kan du använda fio.

# Без fsync
fio --name=test1 --blocksize=16k --rw=randrw --iodepth=16 --runtime=60 --rwmixread=60 --fsync=0 --filename=/dev/sdb

# С fsync после каждой записи
fio --name=test1 --blocksize=16k --rw=randrw --iodepth=16 --runtime=60 --rwmixread=60 --fsync=1 --filename=/dev/sdb

Test
Intel® S4500
Samsung 970 EVO+

Läser utan fsync, MiB/s
45.5
178

Inspelning utan fsync, MiB/s
30.4
119

Läser med fsync, MiB/s
32.6
20.9

Inspelning med fsync, MiB/s
21.7
13.9

Tendensen för NVMe-prestanda att försämras när du använder fsync är tydligt synlig. Du kan gå vidare till att svara på den andra frågan.

Optimering eller bluff

Tidigare sa vi att data lagras i en buffert, men vi specificerade inte vilken, eftersom detta inte var viktigt. Inte ens nu kommer vi att fördjupa oss i operativsystemens krångligheter och kommer att lyfta fram två allmänna typer av buffertar:

  • program;
  • hårdvara.

Programvarubufferten hänvisar till de buffertar som finns i operativsystemet, och hårdvarubufferten hänvisar till det flyktiga minnet hos diskkontrollern. Systemanropet fsync skickar ett kommando till enheten för att skriva data från dess buffert till huvudminnet, men har inget sätt att verifiera att kommandot exekveras korrekt.

Eftersom SSD visar de bästa resultaten kan två antaganden göras:

  • skivan är designad för en liknande belastning;
  • disken "bluffar" och ignorerar kommandot.

Det oärliga beteendet hos enheten kan märkas om du utför ett strömförlusttest. Du kan kontrollera detta med ett skript diskchecker.pl, som var Etablerade i 2005 år.

Detta skript kräver två fysiska maskiner - en "server" och en "klient". Klienten skriver en liten mängd data till disken som testas, anropar fsync och skickar information till servern om vad som skrevs.

# Запускается на сервере
./diskchecker.pl -l [port]

# Запускается на клиенте
./diskchecker.pl -s <server[:port]> create <file> <size_in_MB>

Efter att ha kört skriptet måste du stänga av strömmen till "klienten" och inte återställa strömmen på flera minuter. Det är viktigt att koppla bort den som testas från el, och inte bara utföra en hård avstängning. Efter en tid kan servern anslutas och laddas in i operativsystemet. När du har laddat operativsystemet måste du starta det igen diskchecker.pl, men med ett argument verifiera.

./diskchecker.pl -s <server[:port]> verify <file>

I slutet av kontrollen ser du antalet fel. Om det finns 0 har disken klarat testet. För att utesluta ett lyckligt sammanträffande för skivan kan experimentet upprepas flera gånger.

Vår S4500 visade inga fel när strömmen gick bort, vilket innebär att den är redo för arbetsbelastningar med många fsync-anrop.

Slutsats

När du väljer diskar eller hela färdiga konfigurationer bör du komma ihåg detaljerna för de problem som måste lösas. Vid första anblicken verkar det uppenbart att NVMe, det vill säga en SSD med PCIe-gränssnitt, är snabbare än den ”klassiska” SATA SSD:n. Men som vi har lärt oss idag, under specifika förhållanden och med vissa uppgifter kanske detta inte är fallet.

Hur testar man serverkomponenter när man hyr från en IaaS-leverantör?
Vi väntar på dig i kommentarerna.

Varför är min NVMe långsammare än en SSD?

Källa: will.com

Lägg en kommentar