Perché il mio NVMe è più lento di un SSD?

Perché il mio NVMe è più lento di un SSD?
In questo articolo esamineremo alcune delle sfumature del sottosistema I/O e il loro impatto sulle prestazioni.

Un paio di settimane fa mi sono imbattuto in una domanda sul perché NVMe su un server è più lento di SATA su un altro. Ho esaminato le caratteristiche dei server e ho capito che si trattava di una domanda trabocchetto: NVMe proveniva dal segmento utente e SSD proveniva dal segmento server.

Ovviamente non è corretto confrontare prodotti di segmenti diversi in ambienti diversi, ma questa non è una risposta tecnica esaustiva. Studieremo le basi, condurremo esperimenti e daremo una risposta alla domanda posta.

Cos'è fsync e dove viene utilizzato

Per velocizzare il lavoro con le unità, i dati vengono memorizzati nel buffer, ovvero archiviati nella memoria volatile fino a quando non si presenta un'opportunità conveniente per salvare il contenuto del buffer sull'unità. I criteri di opportunità sono determinati dal sistema operativo e dalle caratteristiche dell'unità. In caso di interruzione di corrente, tutti i dati nel buffer andranno persi.

Esistono numerose attività in cui è necessario essere sicuri che le modifiche nel file vengano scritte sull'unità e non si trovino in un buffer intermedio. Questa garanzia può essere ottenuta utilizzando la chiamata di sistema fsync conforme a POSIX. La chiamata fsync forza una scrittura dal buffer all'unità.

Dimostriamo l'effetto dei buffer con un esempio artificiale sotto forma di un breve programma in 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;
}

I commenti spiegano bene la sequenza di azioni nel programma. Il testo "la risposta alla domanda principale sulla vita, l'universo e tutto il resto" verrà memorizzato nel buffer del sistema operativo e se si riavvia il server premendo il pulsante Reset durante i "calcoli", il file sarà vuoto. Nel nostro esempio, la perdita di testo non è un problema, quindi fsync non è necessario. I database non condividono questo ottimismo.

I database sono programmi complessi che lavorano con molti file contemporaneamente, quindi vogliono essere sicuri che i dati che scrivono vengano archiviati sull'unità, poiché la coerenza dei dati all'interno del database dipende da questo. I database sono progettati per registrare tutte le transazioni completate ed essere pronti per un'interruzione di corrente in qualsiasi momento. Questo comportamento ti obbliga a usare costantemente fsync in grandi quantità.

Ciò che influisce sull'uso frequente di fsync

Con l'I/O normale, il sistema operativo cerca di ottimizzare la comunicazione del disco, poiché le unità esterne sono le più lente nella gerarchia della memoria. Pertanto, il sistema operativo tenta di scrivere quanti più dati possibile in un unico accesso all'unità.

Dimostriamo l'impatto dell'utilizzo di fsync con un esempio specifico. Abbiamo i seguenti SSD come soggetti di prova:

  • Intel® DC SSD S4500 480 GB, connesso tramite SATA 3.2, 6 Gb/s;
  • Samsung 970 EVO Plus 500 GB, connesso tramite PCIe 3.0 x4, ~31 Gbps.

I test vengono condotti su un Intel® Xeon® W-2255 con Ubuntu 20.04. Per testare i dischi, viene utilizzato sysbench 1.0.18. I dischi hanno una singola partizione formattata come ext4. La preparazione per il test consiste nel creare file da 100 GB:

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

Prove in esecuzione:

# Без 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

I risultati del test sono presentati nella tabella.

Test
Intel® S4500
Samsung970 EVO+

Leggi senza fsync, MiB/s
5734.89
9028.86

Scrivi senza fsync, MiB/s
3823.26
6019.24

Lettura con fsync, MiB/s
37.76
3.27

Registrazione con fsync, MiB/s
25.17
2.18

È facile vedere che NVMe dal segmento client guida con sicurezza quando il sistema operativo stesso decide come lavorare con i dischi e perde quando viene utilizzato fsync. Ciò solleva due domande:

  1. Perché la velocità di lettura supera la larghezza di banda fisica del collegamento nel test senza fsync?
  2. Perché un SSD del segmento server è migliore nella gestione di un gran numero di richieste fsync?

La risposta alla prima domanda è semplice: sysbench genera file con riempimento zero. Pertanto, il test è stato eseguito su 100 gigabyte di zeri. Poiché i dati sono molto uniformi e prevedibili, entrano in gioco varie ottimizzazioni del sistema operativo che accelerano notevolmente l'esecuzione.

Se metti in dubbio tutti i risultati di sysbench, puoi usare 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
Samsung970 EVO+

Leggi senza fsync, MiB/s
45.5
178

Scrivi senza fsync, MiB/s
30.4
119

Lettura con fsync, MiB/s
32.6
20.9

Registrazione con fsync, MiB/s
21.7
13.9

La tendenza al calo delle prestazioni in NVMe quando si utilizza fsync è chiaramente visibile. Puoi passare alla seconda domanda.

Ottimizzazione o bluff

In precedenza abbiamo detto che i dati sono memorizzati in un buffer, ma non abbiamo specificato in quale, poiché non era importante. Anche ora non approfondiremo le complessità dei sistemi operativi e individueremo due tipi generali di buffer:

  • programma;
  • hardware.

Il buffer software si riferisce ai buffer presenti nel sistema operativo e il buffer hardware si riferisce alla memoria volatile del controller del disco. La chiamata di sistema fsync invia un comando all'unità per scrivere i dati dal suo buffer alla memoria principale, ma non ha modo di controllare la corretta esecuzione del comando.

Poiché l'SSD ha prestazioni migliori, si possono fare due ipotesi:

  • il disco è progettato per un carico di un piano simile;
  • il disco "bluffa" e ignora il comando.

Il comportamento disonesto dell'unità può essere notato se si esegue un test con un'interruzione di corrente. Puoi verificarlo con uno script. diskchecker.pl, который был creato nell'anno 2005.

Questo script richiede due macchine fisiche: "server" e "client". Il client scrive una piccola quantità di dati sull'unità sottoposta a test, chiama fsync e invia al server informazioni su ciò che è stato scritto.

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

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

Dopo aver eseguito lo script, è necessario diseccitare il "client" e non restituire l'alimentazione per diversi minuti. È importante scollegare il soggetto del test dall'elettricità e non solo eseguire un arresto forzato. Dopo qualche tempo, il server può essere connesso e caricato nel sistema operativo. Dopo aver avviato il sistema operativo, è necessario ricominciare diskchecker.pl, ma con un argomento verificare.

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

Alla fine del controllo, vedrai il numero di errori. Se sono 0, il disco ha superato il test. Per escludere una combinazione di circostanze che abbia successo per il disco, l'esperimento può essere ripetuto più volte.

Il nostro S4500 non ha mostrato errori di perdita di potenza, il che significa che è pronto per carichi con molte chiamate fsync.

conclusione

Quando si scelgono dischi o intere configurazioni già pronte, è necessario tenere presente le specifiche delle attività che devono essere risolte. A prima vista, sembra ovvio che NVMe, ovvero un SSD con interfaccia PCIe, sia più veloce di un "classico" SSD SATA. Tuttavia, come abbiamo capito oggi, in determinate condizioni e con determinati compiti potrebbe non essere così.

Come si testano i componenti del server durante il noleggio da un provider IaaS?
Ti aspettiamo nei commenti.

Perché il mio NVMe è più lento di un SSD?

Fonte: habr.com

Aggiungi un commento