Η Shopify μετέφερε τις κρατήσεις αποθεμάτων σε MySQL
Η Shopify μετέφερε το σύστημα κρατήσεων αποθεμάτων της από το Redis στη βάση δεδομένων MySQL που ήδη διατηρούσε το λογιστικό βιβλίο αποθεμάτων.
Η Shopify μετέφερε το σύστημα κρατήσεων αποθεμάτων της από το Redis στη βάση δεδομένων MySQL που ήδη διατηρούσε το λογιστικό βιβλίο αποθεμάτων. Μια οριοθετημένη ομάδα μεμονωμένα κλειδώσιμων σειρών μονάδων επιτρέπει σε ταυτόχρονες ολοκληρώσεις αγορών να χρησιμοποιούν το SKIP LOCKED για να επιλέγουν διαφορετικές επιλέξιμες μονάδες. Ο σχεδιασμός εξαρτάται επίσης από τα όρια συναλλαγών, τη διάταξη του πρωτεύοντος κλειδιού, τους κανόνες αναπλήρωσης και την παρατήρηση του χρόνου διατήρησης σύνδεσης κατά την ολοκλήρωση της αγοράς.
Διαβάστε την γραπτή έκδοση (Αγγλικά) ↗
Τι καλύπτει αυτό το βίντεο
- Το παλιό μοντέλο μετρητή ποσότητας του Redis χειριζόταν την ταυτόχρονη πρόσβαση, αλλά ο καθαρισμός κρατήσεων και η ενημέρωση του λογιστικού βιβλίου MySQL δεν μπορούσαν να μοιραστούν μια ενιαία τοπική ατομική συναλλαγή.
- Η αντικατάσταση χρησιμοποιεί μία γραμμή ανά διαθέσιμη μονάδα σε μια ομάδα με ανώτατο όριο 1.000 ανά συνδυασμό είδους/τοποθεσίας. Μια άδεια ομάδα μπορεί να ενεργοποιήσει ενσωματωμένη αναπλήρωση με ταυτόχρονα αιτήματα να περιμένουν πίσω από ένα κλείδωμα αναπλήρωσης.
- Το σύνθετο πρωτεύον κλειδί είναι (shop_id, inventory_item_id, inventory_group_id, id). Η Shopify μείωσε το κόστος κλειδώματος στο πρωτότυπό της και χρησιμοποίησε το READ COMMITTED για να αποφύγει τα κλειδώματα κενού που εμπόδιζαν την αναπλήρωση.
- Οι κρατήσεις διαγράφουν τις γραμμές της ομάδας πριν εισαγάγουν αρχεία κρατήσεων. Η δέσμευση απελευθερώνει τα κλειδώματα βάσης δεδομένων ενώ η αποθηκευμένη κράτηση παραμένει σε όλη τη διαδικασία πληρωμής. Η επιτυχής πληρωμή διεκδικεί το λογιστικό βιβλίο και αφαιρεί την κράτηση σε μια μεταγενέστερη ατομική συναλλαγή.
- Η τεκμηρίωση της MySQL αναφέρει το SKIP LOCKED ως μια ασυνεπή προβολή που παραλείπει τις κλειδωμένες γραμμές. Δεν καθορίζει πλήρη μέτρηση αποθέματος ή δίκαιη σειρά, εφαρμόζεται μόνο σε κλειδώματα επιπέδου γραμμής και είναι ανασφαλές για αναπαραγωγή βάσει εντολών.
- Το παράδειγμα πηγής περιλαμβάνει expires_at, αλλά η Shopify δεν τεκμηριώνει τον αλγόριθμο καθαρισμού λήξης της MySQL. Ο κλάδος απελευθέρωσης/λήξης του βίντεο είναι μια επεξηγηματική απαίτηση κύκλου ζωής.
- Ο χρόνος διατήρησης σύνδεσης σε άλλο κώδικα ολοκλήρωσης αγοράς ήταν ο τελικός περιορισμός της απόδοσης. Η Shopify έγραφε σκιώδώς και στα δύο συστήματα, συνέκρινε τα αποτελέσματα και μεταπήδησε σταδιακά με εφεδρική λειτουργία kill-switch του Redis.
Μεταφρασμένη μεταγραφή
Μεταφράστηκε από την πρωτότυπη αγγλική αφήγηση. Ο διαθέσιμος ήχος και οι υπότιτλοι ελέγχονται από το YouTube.
Γιατί να μεταφέρετε τις κρατήσεις σε MySQL;
0:00 Μια ολοκλήρωση αγοράς χρειάζεται το Redis για να παραμείνει γρήγορη. Η Shopify μετέφερε τις κρατήσεις αποθεμάτων σε MySQL χρησιμοποιώντας μία γραμμή ανά μονάδα σε ένα οριοθετημένη ομάδα. Γιατί να επιλέξετε MySQL; Πώς παρακάμπτετε τα κλειδώματα με ασφάλεια; Αυτό είναι το The Daily Diff, κάτω από την κουκούλα. Και γιατί οι γρήγορες αναζητήσεις εξακολουθούσαν να χτυπούν ένα όριο; Η Shopify είναι μια πλατφόρμα εμπορίου για πωλήσεις online και αυτοπροσώπως. Το Redis είναι ένα in-memory data store.
0:21 Η MySQL είναι μια σχεσιακή βάση δεδομένων, και η Shopify διατηρούσε ήδη το λογιστικό της βιβλίο αποθεμάτων εκεί. Μια κράτηση διακρατεί για λίγο το απόθεμα ενώ ο αγοραστής πληρώνει.
Γιατί ήταν επικίνδυνα δύο καταστήματα;
0:29 Το μοντέλο τους στο Redis μείωνε έναν μετρητή ειδών. Η διεκδίκηση μιας πληρωμένης παραγγελίας σήμαινε ενημέρωση του λογιστικού βιβλίου MySQL και καθαρισμό του Redis. Αυτές οι ξεχωριστές εγγραφές μπορούσαν να αφήσουν απόθεμα πωλημένο δύο φορές ή μη διαθέσιμο όταν θα έπρεπε να είναι πωλήσιμο. Το παλιό μοντέλο επίσης στερούνταν επίγνωσης τοποθεσίας. Η αντικατάσταση πρέπει να επιλέξει απόθεμα από κάπου που μπορεί να εκπληρώσει την παραγγελία. Μια αποθήκη σε λάθος ήπειρο αποτελεί εξαιρετική καταχώριση βάσης δεδομένων και μια τρομερή υπόσχεση παράδοσης. Προηγούμενες προσπάθειες MySQL χρησιμοποιούσαν μια γραμμή ποσότητας, οπότε οι ανταγωνιστικές ολοκληρώσεις αγοράς περίμεναν στην ουρά στο
Τι γίνεται η κλειδώσιμη μονάδα;
0:56 ίδιο κλείδωμα. Σκεφτείτε ένα βελούδινο σκοινί γύρω από ένα κελί υπολογιστικού φύλλου. Η προσθήκη περισσότερων εργαζομένων απλώς επιμηκύνει την ουρά. Η Shopify άλλαξε το αντικείμενο που μπορεί να κλειδωθεί. Κάθε διαθέσιμη μονάδα αποκτά τη δική της γραμμή. Μια κλειδωμένη ανάγνωση παρακάμπτει μονάδες που κρατάει μια άλλη συναλλαγή και επιλέγει άλλες επιλέξιμες μονάδες. Διαφορετικοί εργαζόμενοι μπορούν να αποκτήσουν διαφορετικές γραμμές, ενώ ο καυτός μετρητής παραμένει εκτός του δρόμου τους.
Τι συμβαίνει όταν αδειάζει η δεξαμενή;
1:15 Αυτή η ομάδα περιορίζεται σε χίλιες γραμμές ανά είδος και τοποθεσία. Η αναπλήρωση αντλεί από το λογιστικό βιβλίο. Εάν αδειάσει, η διαθεσιμότητα η διαδρομή αναπληρώνει ενσωματωμένα, με ανταγωνιστικά αιτήματα να περιμένουν πίσω από ένα κλείδωμα αναπλήρωσης. Άδεια δεξαμενή δεν σημαίνει άδεια αποθήκη. Οι κρατήσεις διαγράφουν τις επιλεγμένες γραμμές της ομάδας, και στη συνέχεια εισάγουν αρχεία κρατήσεων σε μια συναλλαγή. Η δέσμευση απελευθερώνει τα κλειδώματα της βάσης δεδομένων.
1:35 Η αναστροφή αναιρεί τις αλλαγές. Η κράτηση επιβιώνει την επεξεργασία πληρωμής ως αποθηκευμένη κατάσταση. Η επιτυχής πληρωμή διεκδικεί το λογιστικό βιβλίο και αφαιρεί την κράτηση ατομικά. Τα κλειδώματα βάσης δεδομένων δεν χρειάζεται ποτέ να "φυλάνε" τη φόρμα πληρωμής. Το σύνθετο πρωτεύον κλειδί τους ξεκινά με κατάστημα, είδος, ομάδα, μετά ταυτότητα μονάδας. Η αντιστοίχιση της αναζήτησης μείωσε το κλείδωμα ευρετηρίου στο πρωτότυπό τους. Χρησιμοποιούν επίσης "read committed" για να αποφύγουν τα κλειδώματα κενού που εμπόδιζαν την αναπλήρωση
1:57 της ομάδας, και μια συνεπή σειρά πινάκων για την αποφυγή κυκλικών αναμονών. Το δημοσιευμένο παράδειγμα καταγράφει χρόνο λήξης. Οι εγκαταλελειμμένες πληρωμές χρειάζονται τελικά την απελευθέρωση του αποθέματος, αλλιώς το καλάθι αγορών γίνεται ένας ιδιοκτήτης. Η ανάρτηση της Shopify αφήνει αυτόν τον αλγόριθμο καθαρισμού απροσδιόριστο, οπότε αυτό το διάγραμμα δείχνει την απαίτηση του κύκλου ζωής. Εδώ είναι το πρόβλημα.
Τι παραλείπει το SKIP LOCKED;
2:14 Το Skip locked αποκλείει τις κλειδωμένες γραμμές, οπότε το εγχειρίδιο αναφέρει το αποτέλεσμα ως ασυνεπή προβολή. Δεν παρέχει ούτε πλήρη καταμέτρηση αποθέματος ούτε δίκαιη σειρά. Κρατήστε την απόφαση διαθεσιμότητας και τους κανόνες αναπλήρωσης γύρω από αυτήν.
Πού ήταν το πραγματικό όριο;
2:26 Και αυτό το όριο; Άλλος κώδικας ολοκλήρωσης αγοράς κρατούσε τις συνδέσεις βάσης δεδομένων για πολύ καιρό. Η Shopify επισήμανε τους καλούντες και μέτρησε τον χρόνο διατήρησης σύνδεσης, στη συνέχεια καθάρισε τη διαδρομή ολοκλήρωσης αγοράς και επανεξέτασε την ταυτόχρονη εκτέλεση νημάτων. Οι γρήγορες αναζητήσεις μπορούν ακόμα να περιμένουν στην ουρά εκτός της αναζήτησης.
Γιατί να εφαρμόσω αυτόν τον σχεδιασμό;
2:38 Έγραψαν σκιωδώς και στα δύο συστήματα με το Redis ως αυθεντικό, συνέκριναν τα αποτελέσματα, και στη συνέχεια μεταπήδησαν σταδιακά με έναν διακόπτη απενεργοποίησης. Η ετυμηγορία μου είναι SHIP IT. Θα έστελνα το κοινό όριο συναλλαγής και αυτήν την αναστρέψιμη κυκλοφορία, με ολόκληρη τη διαδρομή ολοκλήρωσης αγοράς να είναι οργανομενη. Έχετε κάποια ερώτηση σχετικά με αυτό; Βάλτε την στα σχόλια. Και αυτή είναι η διαφορά για σήμερα.
2:54 Είμαι ο Νίκο από την Axrisi. Συγχωνεύστε υπεύθυνα.
Πηγές
- We replaced Redis with MySQL for inventory reservations—and it scaledShopify Engineering — Emilie Noel
- Simplified reservation SQL embedded in Shopify's articleShopify Engineering / CourtneySymons on GitHub Gist
- MySQL 8.0 — Locking ReadsOracle / MySQL Reference Manual
- MySQL 8.0 — Transaction Isolation LevelsOracle / MySQL Reference Manual
- What Is Shopify and How Does It Work?Shopify
- Redis quick startsRedis documentation
- What is MySQL?Oracle / MySQL Reference Manual



