Γιατί το NVMe μου είναι πιο αργό από το SSD μου;

Γιατί το NVMe μου είναι πιο αργό από το SSD μου;
Σε αυτό το άρθρο θα δούμε μερικές από τις αποχρώσεις του υποσυστήματος I/O και τον αντίκτυπό τους στην απόδοση.

Πριν από μερικές εβδομάδες αντιμετώπισα το ερώτημα γιατί το NVMe σε έναν διακομιστή ήταν πιο αργό από το SATA σε έναν άλλο. Κοίταξα τις προδιαγραφές του διακομιστή και συνειδητοποίησα ότι αυτή ήταν μια δύσκολη ερώτηση: το NVMe ήταν από το τμήμα χρηστών και το SSD από το τμήμα διακομιστή.

Προφανώς, δεν είναι δίκαιο να συγκρίνουμε προϊόντα από διαφορετικά τμήματα σε διαφορετικά περιβάλλοντα, αλλά αυτό δεν είναι μια πλήρης τεχνική απάντηση. Ας μελετήσουμε τα βασικά, ας κάνουμε πειράματα και ας απαντήσουμε στο ερώτημα που τίθεται.

Τι είναι το fsync και πού χρησιμοποιείται;

Για να επιταχυνθεί η εργασία με μονάδες δίσκου, τα δεδομένα αποθηκεύονται στην προσωρινή μνήμη, δηλαδή αποθηκεύονται σε πτητική μνήμη μέχρι να παρουσιαστεί μια βολική ευκαιρία για αποθήκευση των περιεχομένων του buffer στη μονάδα δίσκου. Τα κριτήρια για μια «ευκαιρία» καθορίζονται από το λειτουργικό σύστημα και τα χαρακτηριστικά της μονάδας δίσκου. Σε περίπτωση διακοπής ρεύματος, όλα τα δεδομένα στο buffer θα χαθούν.

Υπάρχουν πολλές εργασίες στις οποίες πρέπει να βεβαιωθείτε ότι οι αλλαγές σε ένα αρχείο έχουν εγγραφεί στη μονάδα δίσκου και όχι σε ενδιάμεσο buffer. Αυτή η διασφάλιση μπορεί να επιτευχθεί χρησιμοποιώντας την κλήση συστήματος fsync συμβατό με το POSIX. Η κλήση του fsync αναγκάζει μια εγγραφή από το buffer στη μονάδα δίσκου.

Ας δείξουμε την επίδραση των buffers με ένα τεχνητό παράδειγμα με τη μορφή ενός σύντομου προγράμματος στο 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;
}

Τα σχόλια εξηγούν καλά τη σειρά των ενεργειών στο πρόγραμμα. Το κείμενο "η απάντηση στο κύριο ερώτημα της ζωής, το Σύμπαν και όλα αυτά" θα αποθηκεύεται στην προσωρινή μνήμη από το λειτουργικό σύστημα και εάν κάνετε επανεκκίνηση του διακομιστή πατώντας το κουμπί Επαναφορά κατά τη διάρκεια των "υπολογισμών", το αρχείο θα είναι κενό. Στο παράδειγμά μας, η απώλεια κειμένου δεν είναι πρόβλημα, επομένως δεν χρειάζεται fsync. Οι βάσεις δεδομένων δεν συμμερίζονται αυτήν την αισιοδοξία.

Οι βάσεις δεδομένων είναι πολύπλοκα προγράμματα που λειτουργούν ταυτόχρονα με πολλά αρχεία, επομένως θέλουν να είναι σίγουροι ότι τα δεδομένα που γράφουν θα αποθηκευτούν στη μονάδα δίσκου, καθώς από αυτό εξαρτάται η συνοχή των δεδομένων μέσα στη βάση δεδομένων. Οι βάσεις δεδομένων έχουν σχεδιαστεί για να καταγράφουν όλες τις ολοκληρωμένες συναλλαγές και να είναι έτοιμες να χάσουν ρεύμα ανά πάσα στιγμή. Αυτή η συμπεριφορά απαιτεί τη χρήση του fsync συνεχώς σε μεγάλες ποσότητες.

Ποιο είναι το αποτέλεσμα της συχνής χρήσης του fsync;

Κατά τη διάρκεια της κανονικής εισόδου/εξόδου, το λειτουργικό σύστημα προσπαθεί να βελτιστοποιήσει την επικοινωνία με τους δίσκους, καθώς οι εξωτερικές μονάδες δίσκου είναι οι πιο αργοί στην ιεραρχία της μνήμης. Επομένως, το λειτουργικό σύστημα προσπαθεί να γράψει όσο το δυνατόν περισσότερα δεδομένα σε μία πρόσβαση στη μονάδα δίσκου.

Ας δείξουμε τον αντίκτυπο της χρήσης του fsync με ένα συγκεκριμένο παράδειγμα. Έχουμε τους παρακάτω δίσκους SSD ως δοκιμαστικές μονάδες:

  • Intel® DC SSD S4500 480 GB, συνδεδεμένο μέσω SATA 3.2, 6 Gbit/s.
  • Samsung 970 EVO Plus 500GB, συνδεδεμένο μέσω PCIe 3.0 x4, ~31 Gbit/s.

Οι δοκιμές πραγματοποιούνται σε ένα Intel® Xeon® W-2255 με Ubuntu 20.04. Το Sysbench 1.0.18 χρησιμοποιείται για τη δοκιμή δίσκων. Ένα διαμέρισμα έχει δημιουργηθεί στους δίσκους, μορφοποιημένο ως ext4. Η προετοιμασία για τη δοκιμή περιλαμβάνει τη δημιουργία αρχείων 100 GB:

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

Τρέξιμο τεστ:

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

Τα αποτελέσματα των δοκιμών παρουσιάζονται στον πίνακα.

Δοκιμή
Intel® S4500
Samsung 970 EVO+

Ανάγνωση χωρίς fsync, MiB/s
5734.89
9028.86

Εγγραφή χωρίς fsync, MiB/s
3823.26
6019.24

Ανάγνωση με fsync, MiB/s
37.76
3.27

Εγγραφή με fsync, MiB/s
25.17
2.18

Είναι εύκολο να διαπιστωθεί ότι το NVMe από το τμήμα πελάτη είναι με σιγουριά στην κορυφή όταν το ίδιο το λειτουργικό σύστημα αποφασίζει πώς να εργαστεί με δίσκους και χάνει όταν χρησιμοποιείται το fsync. Αυτό εγείρει δύο ερωτήματα:

  1. Γιατί η ταχύτητα ανάγνωσης στη δοκιμή χωρίς fsync υπερβαίνει το φυσικό εύρος ζώνης του καναλιού;
  2. Γιατί ένας SSD τμήματος διακομιστή είναι καλύτερος στο χειρισμό μεγάλου αριθμού αιτημάτων fsync;

Η απάντηση στην πρώτη ερώτηση είναι απλή: το sysbench δημιουργεί αρχεία γεμάτα με μηδενικά. Έτσι, η δοκιμή πραγματοποιήθηκε πάνω από 100 gigabyte μηδενικών. Δεδομένου ότι τα δεδομένα είναι πολύ ομοιόμορφα και προβλέψιμα, μπαίνουν στο παιχνίδι διάφορες βελτιστοποιήσεις λειτουργικού συστήματος και επιταχύνουν σημαντικά την εκτέλεση.

Εάν αμφισβητείτε όλα τα αποτελέσματα του sysbench, μπορείτε να χρησιμοποιήσετε το 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

Δοκιμή
Intel® S4500
Samsung 970 EVO+

Ανάγνωση χωρίς fsync, MiB/s
45.5
178

Εγγραφή χωρίς fsync, MiB/s
30.4
119

Ανάγνωση με fsync, MiB/s
32.6
20.9

Εγγραφή με fsync, MiB/s
21.7
13.9

Η τάση για υποβάθμιση της απόδοσης του NVMe κατά τη χρήση του fsync είναι ξεκάθαρα ορατή. Μπορείτε να προχωρήσετε στην απάντηση στη δεύτερη ερώτηση.

Βελτιστοποίηση ή μπλόφα

Προηγουμένως, είπαμε ότι τα δεδομένα αποθηκεύονται σε buffer, αλλά δεν προσδιορίσαμε ποιο, καθώς αυτό δεν ήταν σημαντικό. Ακόμη και τώρα δεν θα εμβαθύνουμε στις περιπλοκές των λειτουργικών συστημάτων και θα επισημάνουμε δύο γενικούς τύπους buffer:

  • πρόγραμμα;
  • σκεύη, εξαρτήματα.

Το buffer λογισμικού αναφέρεται στα buffer που υπάρχουν στο λειτουργικό σύστημα και το buffer υλικού αναφέρεται στην πτητική μνήμη του ελεγκτή δίσκου. Η κλήση συστήματος fsync στέλνει μια εντολή στη μονάδα δίσκου για την εγγραφή δεδομένων από την προσωρινή μνήμη στην κύρια αποθήκευση, αλλά δεν έχει κανέναν τρόπο να επαληθεύσει ότι η εντολή εκτελείται σωστά.

Δεδομένου ότι ο SSD δείχνει τα καλύτερα αποτελέσματα, μπορούν να γίνουν δύο υποθέσεις:

  • ο δίσκος έχει σχεδιαστεί για παρόμοιο φορτίο.
  • ο δίσκος «μπλοφάρει» και αγνοεί την εντολή.

Η ανέντιμη συμπεριφορά της μονάδας μπορεί να παρατηρηθεί εάν πραγματοποιήσετε δοκιμή απώλειας ισχύος. Μπορείτε να το ελέγξετε με ένα σενάριο diskchecker.pl, αυτό ήταν δημιουργήθηκε σε 2005 χρόνου.

Αυτό το σενάριο απαιτεί δύο φυσικές μηχανές - έναν "διακομιστή" και έναν "πελάτη". Ο πελάτης γράφει μια μικρή ποσότητα δεδομένων στον υπό δοκιμή δίσκο, καλεί το fsync και στέλνει πληροφορίες στον διακομιστή σχετικά με το τι γράφτηκε.

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

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

Μετά την εκτέλεση του σεναρίου, πρέπει να απενεργοποιήσετε τον "πελάτη" και να μην επιστρέψετε την τροφοδοσία για αρκετά λεπτά. Είναι σημαντικό να αποσυνδέσετε το άτομο που ελέγχεται από το ηλεκτρικό ρεύμα και να μην εκτελέσετε απλώς μια σκληρή διακοπή λειτουργίας. Μετά από κάποιο χρονικό διάστημα, ο διακομιστής μπορεί να συνδεθεί και να φορτωθεί στο λειτουργικό σύστημα. Αφού φορτώσετε το λειτουργικό σύστημα, πρέπει να το ξεκινήσετε ξανά diskchecker.pl, αλλά με επιχείρημα επαληθεύει.

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

Στο τέλος του ελέγχου θα δείτε τον αριθμό των σφαλμάτων. Εάν υπάρχουν 0, τότε ο δίσκος έχει περάσει τη δοκιμή. Για να αποκλειστεί ένας τυχερός συνδυασμός περιστάσεων για το δίσκο, το πείραμα μπορεί να επαναληφθεί πολλές φορές.

Το S4500 μας δεν παρουσίασε σφάλματα όταν χάθηκε η ισχύς, που σημαίνει ότι είναι έτοιμο για φόρτους εργασίας με πολλές κλήσεις fsync.

Συμπέρασμα

Όταν επιλέγετε δίσκους ή ολόκληρες έτοιμες διαμορφώσεις, θα πρέπει να θυμάστε τις ιδιαιτερότητες των προβλημάτων που πρέπει να επιλυθούν. Με την πρώτη ματιά, φαίνεται προφανές ότι ο NVMe, δηλαδή ένας SSD με διασύνδεση PCIe, είναι ταχύτερος από τον «κλασικό» SATA SSD. Ωστόσο, όπως μάθαμε σήμερα, σε συγκεκριμένες συνθήκες και με ορισμένες εργασίες αυτό μπορεί να μην ισχύει.

Πώς δοκιμάζετε τα στοιχεία διακομιστή κατά την ενοικίαση από έναν πάροχο IaaS;
Σας περιμένουμε στα σχόλια.

Γιατί το NVMe μου είναι πιο αργό από το SSD μου;

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο