PostgreSQL και ρυθμίσεις συνοχής εγγραφής για συγκεκριμένες συνδέσεις

Η μετάφραση του άρθρου ετοιμάστηκε ειδικά για τους φοιτητές του μαθήματος "Βάση δεδομένων". Ενδιαφέρεστε να αναπτυχθείτε προς αυτή την κατεύθυνση; Σας προσκαλούμε να Open Day, όπου μιλάμε αναλυτικά για το πρόγραμμα, τα χαρακτηριστικά της διαδικτυακής μορφής, τις ικανότητες και τις προοπτικές σταδιοδρομίας που περιμένουν τους αποφοίτους μετά την εκπαίδευση.

PostgreSQL και ρυθμίσεις συνοχής εγγραφής για συγκεκριμένες συνδέσεις

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

Γιατί το χρειάζομαι;

Το πώς θα πρέπει να συμπεριφέρεται το σύμπλεγμα εξαρτάται από την αίτησή σας. Πάρτε, για παράδειγμα, μια εφαρμογή πληρωμής λογαριασμών. Θα χρειαστείτε XNUMX% συνέπεια σε όλο το σύμπλεγμα, επομένως θα πρέπει να ενεργοποιήσετε τις σύγχρονες δεσμεύσεις έτσι ώστε η βάση δεδομένων σας να περιμένει να γίνουν όλες οι αλλαγές. Ωστόσο, εάν η εφαρμογή σας είναι ένα ταχέως αναπτυσσόμενο κοινωνικό δίκτυο, τότε πιθανότατα θα προτιμήσετε τη γρήγορη απόκριση σε σχέση με τη συνέπεια XNUMX%. Για να το πετύχετε αυτό, μπορείτε να χρησιμοποιήσετε ασύγχρονες δεσμεύσεις στο σύμπλεγμα σας.

Συναντήστε τον συμβιβασμό

Πρέπει να κάνετε αντισταθμίσεις μεταξύ της συνέπειας των δεδομένων και της απόδοσης. Η PostgreSQL απομακρύνεται από τη συνέπεια επειδή η προεπιλεγμένη διαμόρφωση είναι τότε προβλέψιμη και χωρίς απροσδόκητες εκπλήξεις. Τώρα ας δούμε τους συμβιβασμούς.

Ανταλλαγή 1: Απόδοση

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

Tradeoff 2: Συνέπεια

Το αποτέλεσμα σε περίπτωση αποτυχίας του ηγέτη σε αυτές τις δύο προσεγγίσεις θα είναι επίσης διαφορετικό. Εάν η εργασία εκτελείται ασύγχρονα, τότε εάν παρουσιαστεί τέτοιο σφάλμα, δεν θα δεσμευτούν όλες οι εγγραφές από τα αντίγραφα. Πόσα θα χαθούν; Εξαρτάται από την ίδια την εφαρμογή και την αποτελεσματικότητα της αναπαραγωγής. Η αναπαραγωγή σύνταξης θα αποτρέψει ένα αντίγραφο από το να γίνει ηγέτης εάν ο όγκος των πληροφοριών σε αυτό είναι 1 MB μικρότερος από τον αρχηγό, δηλαδή, έως και 1 MB εγγραφών θα μπορούσαν ενδεχομένως να χαθούν κατά τη διάρκεια της ασύγχρονης λειτουργίας.

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

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

Ανταλλαγή 3: Συντριβές

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

Μία σύνδεση ανά συναλλαγή;

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

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

Εξασφάλιση ελέγχου στην πράξη

Από προεπιλογή, η PostgreSQL παρέχει συνέπεια. Αυτό ελέγχεται από την παράμετρο διακομιστή synchronous_commit. Από προεπιλογή είναι στη θέση του on, αλλά έχει τρεις άλλες επιλογές: local, remote_write ή off.

Όταν ρυθμίζετε την παράμετρο σε off όλες οι σύγχρονες δεσμεύσεις διακόπτονται, ακόμη και στο τοπικό σύστημα. Η τοπική παράμετρος καθορίζει τη σύγχρονη λειτουργία για το τοπικό σύστημα, αλλά οι εγγραφές σε αντίγραφα εκτελούνται ασύγχρονα. Remote_write πηγαίνει ακόμη παραπέρα: οι εγγραφές σε αντίγραφα γίνονται ασύγχρονα, αλλά επιστρέφονται όταν το αντίγραφο έχει αποδεχτεί την εγγραφή αλλά δεν το έχει γράψει στο δίσκο.

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

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

SET SESSION synchronous_commit TO ON;  
// Your writes go here

Όλες οι επόμενες εγγραφές στη συνεδρία θα επιβεβαιώσουν τις εγγραφές στα αντίγραφα πριν επιστρέψουν ένα θετικό αποτέλεσμα στον συνδεδεμένο πελάτη. Εκτός φυσικά και αν αλλάξεις τη ρύθμιση synchronous_commit πάλι. Μπορείτε να παραλείψετε μέρος SESSION στην εντολή γιατί θα είναι στην προεπιλεγμένη τιμή.

Η δεύτερη μέθοδος είναι καλή όταν θέλετε απλώς να βεβαιωθείτε ότι λαμβάνετε σύγχρονη αναπαραγωγή για μία μόνο συναλλαγή. Σε πολλές βάσεις δεδομένων παραγωγής NoSQL η έννοια των συναλλαγών δεν υπάρχει, αλλά υπάρχει στην PostgreSQL. Σε αυτή την περίπτωση ξεκινάτε μια συναλλαγή και μετά ορίζετε synchronous_commit в on πριν από την εκτέλεση της καταχώρησης για τη συναλλαγή. COMMIT θα πραγματοποιήσει τη συναλλαγή χρησιμοποιώντας οποιαδήποτε τιμή παραμέτρου synchronous_commit, το οποίο ορίστηκε εκείνη τη στιγμή, αν και είναι καλύτερο να ρυθμίσετε τη μεταβλητή εκ των προτέρων για να βεβαιωθείτε ότι οι άλλοι προγραμματιστές κατανοούν ότι οι εγγραφές δεν είναι ασύγχρονες.

BEGIN;  
SET LOCAL synchronous_commit TO ON;  
// Your writes go here
COMMIT;  

Όλες οι δεσμεύσεις συναλλαγών θα επιβεβαιωθούν τώρα ως γραμμένες σε αντίγραφα προτού η βάση δεδομένων επιστρέψει θετική απάντηση στον συνδεδεμένο πελάτη.

Διαμόρφωση PostgreSQL

Πριν από αυτό, φανταστήκαμε ένα σύστημα PostgreSQL με synchronous_commit, εγκατεστημένο σε local. Για να γίνει αυτό ρεαλιστικό από την πλευρά του διακομιστή, θα χρειαστεί να ορίσετε δύο επιλογές διαμόρφωσης διακομιστή. Μια ακόμα παράμετρος synchronous_standby_names θα έρθει στα δικά του όταν synchronous_commit θα είναι μέσα on. Καθορίζει ποια αντίγραφα είναι κατάλληλα για σύγχρονες δεσμεύσεις και θα το ρυθμίσουμε σε *, πράγμα που σημαίνει ότι εμπλέκονται όλα τα αντίγραφα. Αυτές οι τιμές συνήθως διαμορφώνονται σε αρχείο ρυθμίσεων προσθέτοντας:

synchronous_commit = local  
synchronous_standby_names='*'

Ρυθμίζοντας την παράμετρο synchronous_commit σε νόημα local, δημιουργούμε ένα σύστημα όπου οι τοπικοί δίσκοι παραμένουν σύγχρονοι, αλλά οι δεσμεύσεις αντιγράφου δικτύου είναι ασύγχρονες από προεπιλογή. Εκτός, φυσικά, εάν αποφασίσουμε να κάνουμε αυτές τις δεσμεύσεις σύγχρονες, όπως φαίνεται παραπάνω.

Εάν παρακολουθείτε την εξέλιξη Έργο κυβερνήτη, μπορεί να έχετε παρατηρήσει κάποιες πρόσφατες αλλαγές (1, 2), το οποίο επέτρεπε στους χρήστες του Governor να δοκιμάσουν αυτές τις παραμέτρους και να παρακολουθήσουν τη συνοχή τους.

Λίγα λόγια ακόμα...

Μόλις πριν από μια εβδομάδα, θα σας έλεγα ότι είναι αδύνατο να βελτιστοποιήσετε την PostgreSQL τόσο λεπτή. Τότε ήταν που ο Kurt, μέλος της ομάδας της πλατφόρμας Compose, επέμεινε ότι υπήρχε μια τέτοια ευκαιρία. Κάλυψε τις αντιρρήσεις μου και βρήκε στην τεκμηρίωση της PostgreSQL τα ακόλουθα:

PostgreSQL και ρυθμίσεις συνοχής εγγραφής για συγκεκριμένες συνδέσεις

Αυτή η ρύθμιση μπορεί να αλλάξει ανά πάσα στιγμή. Η συμπεριφορά για οποιαδήποτε συναλλαγή καθορίζεται από τη ρύθμιση που ισχύει τη στιγμή της δέσμευσης. Επομένως, είναι δυνατό και χρήσιμο για ορισμένες συναλλαγές να πραγματοποιούνται συγχρονισμένα και για άλλες ασύγχρονα. Για παράδειγμα, για να αναγκάσεις έναν multistatement η συναλλαγή για να κάνει δεσμεύει ασύγχρονα όταν η προεπιλεγμένη τιμή της παραμέτρου είναι αντίθετη, ορίστε SET LOCAL synchronous_commit TO OFF σε μια συναλλαγή.

Με αυτή τη μικρή τροποποίηση στο αρχείο διαμόρφωσης, δώσαμε στους χρήστες τον έλεγχο της συνέπειας και της απόδοσής τους.

Πηγή: www.habr.com

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