RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα

В τελευταίο άρθρο εξετάσαμε την ομαδοποίηση RabbitMQ για ανοχή σφαλμάτων και υψηλή διαθεσιμότητα. Τώρα ας σκάψουμε βαθιά στον Απάτσι Κάφκα.

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

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 1. Τέσσερα τμήματα κατανέμονται μεταξύ τριών μεσιτών

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

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα

Αποτυχία διαμερίσματος

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

Ο μεσίτης 3 αποχωρεί από το δίκτυο και εκλέγεται νέος αρχηγός για το τμήμα 2 στον μεσίτη 2.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 2. Ο Broker 3 πεθαίνει και ο ακόλουθος του στο broker 2 εκλέγεται νέος αρχηγός του partition 2

Τότε ο μεσίτης 1 φεύγει και το τμήμα 1 χάνει επίσης τον αρχηγό του, ο ρόλος του οποίου περνά στον μεσίτη 2.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 3. Απομένει ένας μεσίτης. Όλοι οι ηγέτες βρίσκονται σε έναν μεσίτη με μηδενικό πλεονασμό

Όταν ο μεσίτης 1 επανέρχεται στο διαδίκτυο, προσθέτει τέσσερις ακόλουθους, παρέχοντας πλεονασμό σε κάθε διαμέρισμα. Αλλά όλοι οι ηγέτες παρέμειναν στο broker 2.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 4. Οι ηγέτες παραμένουν στον μεσίτη 2

Όταν εμφανιστεί το broker 3, επιστρέφουμε σε τρία αντίγραφα ανά διαμέρισμα. Αλλά όλοι οι ηγέτες εξακολουθούν να είναι στο broker 2.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 5. Ανισόρροπη τοποθέτηση ηγετών μετά την αποκατάσταση των μεσιτών 1 και 3

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

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

Για να διορθωθεί αυτό, ο Κάφκα προσφέρει δύο επιλογές:

  • Επιλογή auto.leader.rebalance.enable=true επιτρέπει στον κόμβο ελεγκτή να εκχωρεί αυτόματα τους οδηγούς πίσω στα προτιμώμενα αντίγραφα και έτσι να αποκαθιστά την ομοιόμορφη κατανομή.
  • Ο διαχειριστής μπορεί να εκτελέσει το σενάριο kafka-preferred-replica-election.sh για χειροκίνητη αλλαγή.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 6. Ρεπλίκες μετά την επαναστάθμιση

Αυτή ήταν μια απλοποιημένη εκδοχή της αποτυχίας, αλλά η πραγματικότητα είναι πιο περίπλοκη, αν και δεν υπάρχει τίποτα πολύ περίπλοκο εδώ. Όλα καταλήγουν σε συγχρονισμένα αντίγραφα (In-Sync Replicas, ISR).

Συγχρονισμένα αντίγραφα (ISR)

Ένα ISR είναι ένα σύνολο αντιγράφων ενός διαμερίσματος που θεωρείται "συγχρονισμένο" (in-sync). Υπάρχει ηγέτης, αλλά μπορεί να μην υπάρχουν οπαδοί. Ένας ακόλουθος θεωρείται συγχρονισμένος εάν έχει κάνει ακριβή αντίγραφα όλων των μηνυμάτων του αρχηγού πριν λήξει το διάστημα replica.lag.time.max.ms.

Ένας ακόλουθος αφαιρείται από το σύνολο ISR εάν:

  • δεν υπέβαλε αίτημα επιλογής για το διάστημα replica.lag.time.max.ms (υποτίθεται νεκρός)
  • δεν κατάφερε να ενημερώσει κατά τη διάρκεια του διαστήματος replica.lag.time.max.ms (θεωρείται αργό)

Οι ακόλουθοι κάνουν αιτήματα δειγματοληψίας στο διάστημα replica.fetch.wait.max.ms, το οποίο είναι προεπιλεγμένο σε 500ms.

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

  • acks=0, η επιβεβαίωση δεν έχει σταλεί
  • acks=1, η επιβεβαίωση αποστέλλεται αφού ο αρχηγός γράψει ένα μήνυμα στο τοπικό του αρχείο καταγραφής
  • acks=all, η επιβεβαίωση αποστέλλεται αφού όλα τα αντίγραφα στο ISR έχουν γράψει το μήνυμα στα τοπικά αρχεία καταγραφής

Στην ορολογία του Κάφκα, εάν το ISR έχει αποθηκεύσει ένα μήνυμα, αυτό "δεσμεύεται". Το Acks=all είναι η πιο ασφαλής επιλογή, αλλά προσθέτει και επιπλέον καθυστέρηση. Ας δούμε δύο παραδείγματα αποτυχίας και πώς αλληλεπιδρούν οι διαφορετικές επιλογές «acks» με την έννοια ISR.

Acks=1 και ISR

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

Σε αυτό το παράδειγμα, ο κατασκευαστής έχει την τιμή acks=1. Η ενότητα κατανέμεται και στους τρεις μεσίτες. Το Broker 3 είναι πίσω, συγχρονίστηκε με τον ηγέτη πριν από οκτώ δευτερόλεπτα και τώρα είναι 7456 μηνύματα πίσω. Ο Broker 1 ήταν μόνο ένα δευτερόλεπτο πίσω. Ο παραγωγός μας στέλνει ένα μήνυμα και λαμβάνει γρήγορα μια απάντηση, χωρίς τα γενικά έξοδα αργών ή νεκρών οπαδών που δεν περιμένει ο αρχηγός.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 7. ISR με τρία αντίγραφα

Το Broker 2 αποτυγχάνει και ο παραγωγός λαμβάνει ένα σφάλμα σύνδεσης. Αφού περάσει η ηγεσία στον μεσίτη 1, χάνουμε 123 μηνύματα. Ο ακόλουθος στο broker 1 ήταν μέρος του ISR, αλλά δεν ήταν πλήρως συγχρονισμένος με τον ηγέτη όταν έπεσε.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 8. Τα μηνύματα χάνονται όταν κολλάει

Στη διαμόρφωση bootstrap.servers Ο κατασκευαστής έχει πολλούς μεσίτες στη λίστα και μπορεί να ρωτήσει έναν άλλο μεσίτη ποιος είναι ο νέος επικεφαλής του τμήματος. Στη συνέχεια, δημιουργεί μια σύνδεση με τον μεσίτη 1 και συνεχίζει να στέλνει μηνύματα.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 9. Η αποστολή μηνυμάτων συνεχίζεται μετά από ένα σύντομο διάλειμμα

Ο Broker 3 είναι ακόμα πιο πίσω. Υποβάλλει αιτήματα ανάκτησης αλλά δεν μπορεί να συγχρονιστεί. Αυτό μπορεί να οφείλεται σε αργή σύνδεση δικτύου μεταξύ μεσιτών, πρόβλημα αποθήκευσης κ.λπ. Καταργείται από το ISR. Τώρα το ISR αποτελείται από ένα αντίγραφο - τον αρχηγό! Ο κατασκευαστής συνεχίζει να στέλνει μηνύματα και να λαμβάνει επιβεβαιώσεις.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 10. Ο ακόλουθος στον μεσίτη 3 αφαιρείται από το ISR

Ο Broker 1 πέφτει και ο ηγετικός ρόλος πηγαίνει στον μεσίτη 3 με την απώλεια 15286 μηνυμάτων! Ο κατασκευαστής λαμβάνει ένα μήνυμα σφάλματος σύνδεσης. Η μετάβαση σε ηγέτη εκτός του ISR ήταν δυνατή μόνο λόγω του σκηνικού unclean.leader.election.enable=true. Εάν είναι εγκατεστημένο σε ψευδής, τότε η μετάβαση δεν θα γινόταν και όλα τα αιτήματα ανάγνωσης και εγγραφής θα απορρίπτονταν. Σε αυτήν την περίπτωση, περιμένουμε να επιστρέψει ο μεσίτης 1 με τα άθικτα δεδομένα του στο αντίγραφο, ο οποίος θα αναλάβει και πάλι την ηγεσία.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 11. Μεσίτης 1 πέφτει. Όταν παρουσιαστεί μια αποτυχία, χάνεται μεγάλος αριθμός μηνυμάτων

Ο παραγωγός συνδέει τον τελευταίο μεσίτη και βλέπει ότι είναι πλέον ο αρχηγός του τμήματος. Αρχίζει να στέλνει μηνύματα στον μεσίτη 3.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 12. Μετά από ένα σύντομο διάλειμμα, τα μηνύματα αποστέλλονται ξανά στην ενότητα 0

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

Acks=all και ISR

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

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 13. ISR με τρία αντίγραφα. Το ένα είναι αργό, με αποτέλεσμα να υπάρχουν καθυστερήσεις στην εγγραφή

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

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 14. Όλα τα αντίγραφα αποθηκεύουν μηνύματα και αποστέλλουν αποδοχή

Το Broker 3 μένει πλέον πιο πίσω και αφαιρείται από το ISR. Η καθυστέρηση μειώνεται σημαντικά επειδή δεν έχουν απομείνει αργά αντίγραφα στο ISR. Ο Broker 2 περιμένει τώρα μόνο τον μεσίτη 1 και έχει μέση καθυστέρηση 500 ms.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 15. Το αντίγραφο στον μεσίτη 3 αφαιρείται από το ISR

Στη συνέχεια ο μεσίτης 2 πέφτει και η ηγεσία περνά στον μεσίτη 1 χωρίς απώλεια μηνυμάτων.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 16. Μεσίτης 2 πέφτει

Ο κατασκευαστής βρίσκει έναν νέο ηγέτη και αρχίζει να του στέλνει μηνύματα. Η καθυστέρηση μειώνεται περαιτέρω επειδή το ISR αποτελείται πλέον από ένα αντίγραφο! Επομένως η επιλογή acks=όλα δεν προσθέτει πλεονασμό.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 17. Το αντίγραφο στον μεσίτη 1 παίρνει το προβάδισμα χωρίς να χάνει μηνύματα

Τότε το broker 1 κολλάει και το προβάδισμα πηγαίνει στον broker 3 με απώλεια 14238 μηνυμάτων!

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 18. Ο μεσίτης 1 πεθαίνει και η μετάβαση ηγεσίας με ακάθαρτο σκηνικό οδηγεί σε εκτεταμένη απώλεια δεδομένων

Δεν ήταν δυνατή η εγκατάσταση της επιλογής ακάθαρτος.αρχηγός.εκλογή.ενεργοποιώ σε νόημα αληθής. Από προεπιλογή είναι ίσο ψευδής. Ρυθμίσεις acks=όλα с unclean.leader.election.enable=true παρέχει προσβασιμότητα με κάποια πρόσθετη ασφάλεια δεδομένων. Αλλά όπως μπορείτε να δείτε, μπορούμε να χάσουμε μηνύματα.

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

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

Acks=all, min.insync.replicas και ISR

Με διαμόρφωση θέματος min.insync.replicas Αυξάνουμε το επίπεδο ασφάλειας δεδομένων. Ας περάσουμε ξανά από το τελευταίο μέρος του προηγούμενου σεναρίου, αλλά αυτή τη φορά με min.insync.replicas=2.

Έτσι, ο μεσίτης 2 έχει έναν ηγέτη ρεπλίκα και ο ακόλουθος στον μεσίτη 3 αφαιρείται από το ISR.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 19. ISR από δύο αντίγραφα

Ο μεσίτης 2 πέφτει και η ηγεσία περνά στον μεσίτη 1 χωρίς απώλεια μηνυμάτων. Αλλά τώρα το ISR αποτελείται από ένα μόνο αντίγραφο. Αυτό δεν πληροί τον ελάχιστο αριθμό για λήψη εγγραφών και επομένως ο μεσίτης απαντά στην προσπάθεια εγγραφής με σφάλμα NotEnoughReplicas.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 20. Ο αριθμός των ISR είναι κατά ένα μικρότερος από αυτόν που καθορίζεται στο min.insync.replicas

Αυτή η διαμόρφωση θυσιάζει τη διαθεσιμότητα για συνέπεια. Προτού επιβεβαιώσουμε ένα μήνυμα, διασφαλίζουμε ότι είναι γραμμένο σε τουλάχιστον δύο αντίγραφα. Αυτό δίνει στον κατασκευαστή πολύ μεγαλύτερη εμπιστοσύνη. Εδώ, η απώλεια μηνύματος είναι δυνατή μόνο εάν δύο αντίγραφα αποτύχουν ταυτόχρονα σε ένα σύντομο διάστημα έως ότου το μήνυμα αντιγραφεί σε έναν επιπλέον ακόλουθο, κάτι που είναι απίθανο. Αλλά αν είστε εξαιρετικά παρανοϊκοί, μπορείτε να ορίσετε τον παράγοντα αναπαραγωγής στο 5 και min.insync.replicas με 3. Εδώ τρεις μεσίτες πρέπει να πέσουν ταυτόχρονα για να χάσουν το ρεκόρ! Φυσικά, πληρώνετε για αυτήν την αξιοπιστία σε επιπλέον καθυστέρηση.

Όταν η προσβασιμότητα είναι απαραίτητη για την ασφάλεια των δεδομένων

Όπως στο περίπτωση με RabbitMQ, μερικές φορές η προσβασιμότητα είναι απαραίτητη για την ασφάλεια των δεδομένων. Εδώ είναι τι πρέπει να σκεφτείτε:

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

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

Η έννοια του ISR

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

Το νόημα το επιλέγουμε μόνοι μας replica.lag.time.max.ms ανάλογα με τις ανάγκες σας. Ουσιαστικά, αυτή η παράμετρος σημαίνει πόση καθυστέρηση είμαστε διατεθειμένοι να δεχτούμε πότε acks=όλα. Η προεπιλεγμένη τιμή είναι δέκα δευτερόλεπτα. Εάν αυτό είναι πολύ μεγάλο για εσάς, μπορείτε να το μειώσετε. Τότε η συχνότητα αλλαγών στο ISR θα αυξηθεί, αφού οι ακόλουθοι θα αφαιρούνται και θα προστίθενται συχνότερα.

Το RabbitMQ είναι απλώς ένα σύνολο κατόπτρων που πρέπει να αναπαραχθούν. Οι αργοί καθρέφτες εισάγουν πρόσθετο λανθάνοντα χρόνο και οι νεκροί καθρέφτες μπορούν να περιμένουν μέχρι να ανταποκριθούν τα πακέτα που ελέγχουν τη διαθεσιμότητα κάθε κόμβου (καθαρό tick). Το ISR είναι ένας ενδιαφέρον τρόπος για να αποφευχθούν αυτά τα ζητήματα καθυστέρησης. Αλλά κινδυνεύουμε να χάσουμε την απόλυση, καθώς το ISR μπορεί να συρρικνωθεί μόνο στον ηγέτη. Για να αποφύγετε αυτόν τον κίνδυνο, χρησιμοποιήστε τη ρύθμιση min.insync.replicas.

Εγγύηση σύνδεσης πελάτη

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

Στο RabbitMQ, οι πελάτες μπορούν να συνδεθούν σε οποιονδήποτε κόμβο και η εσωτερική δρομολόγηση στέλνει το αίτημα εκεί που πρέπει να πάει. Αυτό σημαίνει ότι μπορείτε να εγκαταστήσετε ένα load balancer μπροστά από το RabbitMQ. Ο Κάφκα απαιτεί από τους πελάτες να συνδεθούν στον κόμβο που φιλοξενεί τον αντίστοιχο οδηγό διαμερίσματος. Σε μια τέτοια περίπτωση, δεν μπορείτε να εγκαταστήσετε έναν εξισορροπητή φορτίου. Λίστα bootstrap.servers Είναι σημαντικό οι πελάτες να έχουν πρόσβαση και να βρίσκουν τους σωστούς κόμβους μετά από μια αποτυχία.

Kafka Consensus Architecture

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

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

Το Zookeeper αποθηκεύει την κατάσταση του συμπλέγματος:

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

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

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

Για κάθε ελεγκτή τμήματος:

  • ενημερώνει πληροφορίες στο Zookeeper σχετικά με το ISR και τον ηγέτη.
  • Στέλνει μια εντολή LeaderAndISR σε κάθε μεσίτη που φιλοξενεί ένα αντίγραφο αυτού του διαμερίσματος, ενημερώνοντας τους μεσίτες για το ISR και τον αρχηγό.

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

Κάθε ηγέτης είναι υπεύθυνος για τη στρατολόγηση ISR. Ρυθμίσεις replica.lag.time.max.ms καθορίζει ποιος θα μπει εκεί. Όταν αλλάζει το ISR, ο αρχηγός μεταδίδει νέες πληροφορίες στο Zookeeper.

Ο Zookeeper ενημερώνεται πάντα για οποιεσδήποτε αλλαγές, ώστε σε περίπτωση αποτυχίας, η διοίκηση να μεταβαίνει ομαλά σε νέο ηγέτη.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 21. Συναίνεση Κάφκα

Πρωτόκολλο αναπαραγωγής

Η κατανόηση των λεπτομερειών της αναπαραγωγής σάς βοηθά να κατανοήσετε καλύτερα πιθανά σενάρια απώλειας δεδομένων.

Ερωτήματα δειγματοληψίας, Log End Offset (LEO) και Highwater Mark (HW)

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

Ο ηγέτης και όλοι οι ακόλουθοι αποθηκεύουν την ετικέτα Log End Offset (LEO) και την ετικέτα Highwater (HW). Η ένδειξη LEO αποθηκεύει τη μετατόπιση του τελευταίου μηνύματος στο τοπικό αντίγραφο και το HW διατηρεί τη μετατόπιση της τελευταίας δέσμευσης. Να θυμάστε ότι για την κατάσταση δέσμευσης, το μήνυμα πρέπει να παραμένει σε όλα τα αντίγραφα ISR. Αυτό σημαίνει ότι ο LEO είναι συνήθως ελαφρώς μπροστά από τον HW.

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

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

Αποτυχία ηγέτη

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

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

Ένας ακόλουθος μπορεί να χρειαστεί να περικόψει το αρχείο καταγραφής για τους ακόλουθους λόγους:

  • Όταν ένας ηγέτης αποτυγχάνει, ο πρώτος ακόλουθος στο σετ ISR που είναι εγγεγραμμένος στο Zookeeper κερδίζει τις εκλογές και γίνεται ο ηγέτης. Όλοι οι ακόλουθοι στο ISR, αν και θεωρούνται "σε συγχρονισμό", ενδέχεται να μην έχουν λάβει αντίγραφα όλων των μηνυμάτων από τον πρώην ηγέτη. Είναι απολύτως πιθανό ο επιλεγμένος ακόλουθος να μην έχει το πιο ενημερωμένο αντίγραφο. Ο Κάφκα διασφαλίζει ότι δεν υπάρχει απόκλιση μεταξύ των αντιγράφων. Έτσι, για να αποφευχθούν αποκλίσεις, κάθε ακόλουθος πρέπει να περικόψει το αρχείο καταγραφής του στην τιμή HW του νέου ηγέτη τη στιγμή της εκλογής του. Αυτός είναι ένας άλλος λόγος για τον οποίο η ρύθμιση acks=όλα τόσο σημαντικό για τη συνέπεια.
  • Τα μηνύματα εγγράφονται περιοδικά στο δίσκο. Εάν όλοι οι κόμβοι συμπλέγματος αποτύχουν ταυτόχρονα, τότε αντίγραφα με διαφορετικές μετατοπίσεις θα αποθηκευτούν στους δίσκους. Είναι πιθανό ότι όταν οι μεσίτες επανέλθουν στο διαδίκτυο, ο νέος ηγέτης που θα εκλεγεί θα βρίσκεται πίσω από τους οπαδούς του επειδή αποθηκεύτηκε στο δίσκο πριν από τους άλλους.

Επανένωση με το σύμπλεγμα

Κατά την επανένταξή τους στο σύμπλεγμα, τα αντίγραφα κάνουν το ίδιο όπως όταν ένας αρχηγός αποτυγχάνει: ελέγχουν το αντίγραφο του αρχηγού και περικόβουν το αρχείο καταγραφής τους στο HW του (τη στιγμή της εκλογής). Συγκριτικά, το RabbitMQ αντιμετωπίζει εξίσου τους επανενωμένους κόμβους ως εντελώς νέους. Και στις δύο περιπτώσεις, ο μεσίτης απορρίπτει οποιαδήποτε υπάρχουσα κατάσταση. Εάν χρησιμοποιείται αυτόματος συγχρονισμός, τότε ο κύριος πρέπει να αναπαράγει απολύτως όλο το τρέχον περιεχόμενο στο νέο καθρέφτη με μια μέθοδο "αφήστε όλο τον κόσμο να περιμένει". Η κύρια μονάδα δεν δέχεται καμία λειτουργία ανάγνωσης ή εγγραφής κατά τη διάρκεια αυτής της λειτουργίας. Αυτή η προσέγγιση δημιουργεί προβλήματα σε μεγάλες ουρές.

Το Kafka είναι ένα κατανεμημένο αρχείο καταγραφής και γενικά αποθηκεύει περισσότερα μηνύματα από μια ουρά RabbitMQ, όπου τα δεδομένα αφαιρούνται από την ουρά μετά την ανάγνωσή τους. Οι ενεργές ουρές πρέπει να παραμένουν σχετικά μικρές. Αλλά το Kafka είναι ένα κούτσουρο με τη δική του πολιτική διατήρησης, η οποία μπορεί να ορίσει μια περίοδο ημερών ή εβδομάδων. Η προσέγγιση αποκλεισμού ουράς και πλήρους συγχρονισμού είναι απολύτως απαράδεκτη για ένα κατανεμημένο αρχείο καταγραφής. Αντίθετα, οι οπαδοί του Κάφκα απλώς περικόπτουν το ημερολόγιο στο HW του ηγέτη (τη στιγμή της εκλογής του) εάν το αντίγραφό τους είναι μπροστά από τον ηγέτη. Στην πιο πιθανή περίπτωση, όταν ο ακόλουθος είναι πίσω, αρχίζει απλώς να κάνει αιτήματα ανάκτησης ξεκινώντας από το τρέχον LEO του.

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

Απώλεια συνδεσιμότητας

Το Kafka έχει περισσότερα στοιχεία από το RabbitMQ, επομένως έχει ένα πιο περίπλοκο σύνολο συμπεριφορών όταν το σύμπλεγμα αποσυνδέεται. Αλλά ο Kafka σχεδιάστηκε αρχικά για clusters, επομένως οι λύσεις είναι πολύ καλά μελετημένες.

Ακολουθούν διάφορα σενάρια αποτυχίας συνδεσιμότητας:

  • Σενάριο 1: Ο ακόλουθος δεν βλέπει τον αρχηγό, αλλά εξακολουθεί να βλέπει τον Zookeeper.
  • Σενάριο 2: Ο ηγέτης δεν βλέπει οπαδούς, αλλά εξακολουθεί να βλέπει τον Zookeeper.
  • Σενάριο 3: Ο ακόλουθος βλέπει τον αρχηγό, αλλά δεν βλέπει τον Zookeeper.
  • Σενάριο 4: Ο αρχηγός βλέπει τους οπαδούς, αλλά δεν βλέπει τον Zookeeper.
  • Σενάριο 5: Ο ακόλουθος είναι εντελώς ξεχωριστός και από τους άλλους κόμβους του Κάφκα και από το Zookeeper.
  • Σενάριο 6: Ο ηγέτης είναι εντελώς ξεχωριστός και από τους άλλους κόμβους του Κάφκα και από τον Zookeeper.
  • Σενάριο 7: Ο κόμβος ελεγκτή Kafka δεν μπορεί να δει άλλον κόμβο Kafka.
  • Σενάριο 8: Ο ελεγκτής Kafka δεν βλέπει τον Zookeeper.

Κάθε σενάριο έχει τη δική του συμπεριφορά.

Σενάριο 1: Ο ακόλουθος δεν βλέπει τον αρχηγό, αλλά εξακολουθεί να βλέπει τον Zookeeper

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 22. Σενάριο 1: ISR τριών αντιγράφων

Η αποτυχία συνδεσιμότητας διαχωρίζει το broker 3 από τους brokers 1 και 2, αλλά όχι από το Zookeeper. Το Broker 3 δεν μπορεί πλέον να στέλνει αιτήματα ανάκτησης. Αφού πέρασε ο καιρός replica.lag.time.max.ms αφαιρείται από το ISR και δεν συμμετέχει σε δεσμεύσεις μηνυμάτων. Μόλις αποκατασταθεί η συνδεσιμότητα, θα συνεχίσει την ανάκτηση αιτημάτων και θα ενταχθεί στο ISR όταν συναντήσει τον ηγέτη. Ο Zookeeper θα συνεχίσει να λαμβάνει ping και θα υποθέσει ότι ο μεσίτης είναι ζωντανός και καλά.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 23. Σενάριο 1: Ο μεσίτης αφαιρείται από το ISR εάν δεν ληφθεί αίτημα ανάκτησης από αυτόν εντός του διαστήματος replica.lag.time.max.ms

Δεν υπάρχει ανάρτηση split-brain ή node όπως στο RabbitMQ. Αντίθετα, μειώνεται ο πλεονασμός.

Σενάριο 2: Ο Leader δεν βλέπει οπαδούς, αλλά εξακολουθεί να βλέπει τον Zookeeper

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 24. Σενάριο 2. Ηγέτης και δύο ακόλουθοι

Μια βλάβη στη συνδεσιμότητα δικτύου χωρίζει τον ηγέτη από τους ακόλουθους, αλλά ο μεσίτης μπορεί να δει το Zookeeper. Όπως και στο πρώτο σενάριο, το ISR συρρικνώνεται, αλλά αυτή τη φορά μόνο στον ηγέτη καθώς όλοι οι ακόλουθοι σταματούν να στέλνουν αιτήματα ανάκτησης. Και πάλι, δεν υπάρχει λογική διαίρεση. Αντίθετα, υπάρχει απώλεια πλεονασμού για νέα μηνύματα μέχρι να αποκατασταθεί η συνδεσιμότητα. Ο Zookeeper συνεχίζει να λαμβάνει ping και πιστεύει ότι ο μεσίτης είναι ζωντανός και καλά.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 25. Σενάριο 2. Το ISR έχει συρρικνωθεί μόνο στον ηγέτη

Σενάριο 3. Ο ακόλουθος βλέπει τον αρχηγό, αλλά δεν βλέπει τον Zookeeper

Ο ακόλουθος χωρίζεται από τον Zookeeper, αλλά όχι από τον μεσίτη με τον αρχηγό. Ως αποτέλεσμα, ο ακόλουθος συνεχίζει να κάνει αιτήματα ανάκτησης και να είναι μέλος του ISR. Το Zookeeper δεν λαμβάνει πλέον ping και καταγράφει μια συντριβή μεσίτη, αλλά επειδή είναι μόνο ένας ακόλουθος, δεν υπάρχουν συνέπειες μετά την ανάκτηση.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 26. Σενάριο 3: Ο ακόλουθος συνεχίζει να στέλνει αιτήματα ανάκτησης στον αρχηγό

Σενάριο 4. Ο Leader βλέπει οπαδούς, αλλά δεν βλέπει Zookeeper

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 27. Σενάριο 4. Ηγέτης και δύο ακόλουθοι

Ο αρχηγός χωρίζεται από το Zookeeper, αλλά όχι από τους μεσίτες με οπαδούς.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 28. Σενάριο 4: Απομονωμένος ηγέτης από Zookeeper

Μετά από κάποιο χρονικό διάστημα, το Zookeeper θα καταγράψει μια αποτυχία μεσίτη και θα ειδοποιήσει τον ελεγκτή σχετικά. Θα επιλέξει έναν νέο ηγέτη μεταξύ των οπαδών του. Ωστόσο, ο αρχικός αρχηγός θα συνεχίσει να πιστεύει ότι είναι ο αρχηγός και θα συνεχίσει να δέχεται συμμετοχές από λαβές=1. Οι ακόλουθοι δεν του στέλνουν πλέον αιτήματα ανάκτησης, επομένως θα τους θεωρήσει νεκρούς και θα προσπαθήσει να συρρικνώσει το ISR στον εαυτό του. Αλλά επειδή δεν έχει σύνδεση με το Zookeeper, δεν θα μπορεί να το κάνει και σε εκείνο το σημείο θα αρνηθεί να δεχτεί περαιτέρω συμμετοχές.

Сообщения acks=όλα δεν θα λάβει επιβεβαίωση, γιατί πρώτα το ISR περιλαμβάνει όλα τα αντίγραφα και τα μηνύματα δεν φτάνουν σε αυτά. Όταν ο αρχικός αρχηγός προσπαθήσει να τους αφαιρέσει από το ISR, δεν θα μπορέσει να το κάνει και θα σταματήσει να δέχεται καθόλου μηνύματα.

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

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 29. Σενάριο 4. Ο ηγέτης στον μεσίτη 1 γίνεται ακόλουθος μετά την αποκατάσταση του δικτύου

Σενάριο 5: Ο ακόλουθος είναι εντελώς ξεχωριστός και από τους άλλους κόμβους του Κάφκα και από το Zookeeper

Ο ακόλουθος είναι εντελώς απομονωμένος τόσο από άλλους κόμβους Κάφκα όσο και από τον Zookeeper. Απλώς αφαιρείται από το ISR έως ότου αποκατασταθεί το δίκτυο και, στη συνέχεια, φτάνει με τους άλλους.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 30. Σενάριο 5: Ο απομονωμένος ακόλουθος αφαιρείται από το ISR

Σενάριο 6: Ο ηγέτης είναι εντελώς ξεχωριστός και από τους άλλους κόμβους του Κάφκα και από τον Zookeeper

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 31. Σενάριο 6. Ηγέτης και δύο ακόλουθοι

Ο ηγέτης είναι εντελώς απομονωμένος από τους οπαδούς του, τον ελεγκτή και τον Zookeeper. Για σύντομο χρονικό διάστημα θα συνεχίσει να δέχεται συμμετοχές από λαβές=1.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 32. Σενάριο 6: Απομόνωση του ηγέτη από άλλους κόμβους Kafka και Zookeeper

Δεν έχουν λάβει αιτήματα μετά τη λήξη replica.lag.time.max.ms, θα προσπαθήσει να συρρικνώσει το ISR στον εαυτό του, αλλά δεν θα μπορέσει να το κάνει επειδή δεν υπάρχει επικοινωνία με το Zookeeper, τότε θα σταματήσει να δέχεται εγγραφές.

Εν τω μεταξύ, ο Zookeeper θα επισημάνει τον απομονωμένο μεσίτη ως νεκρό και ο ελεγκτής θα εκλέξει νέο αρχηγό.

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 33. Σενάριο 6. Δύο αρχηγοί

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

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 34. Σενάριο 6: Οι κατασκευαστές αλλάζουν σε νέο ηγέτη

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

RabbitMQ vs Kafka: Ανοχή σφαλμάτων και υψηλή διαθεσιμότητα
Ρύζι. 35. Σενάριο 6: Ο αρχικός ηγέτης γίνεται ακόλουθος μετά την αποκατάσταση της συνδεσιμότητας δικτύου

Σε αυτήν την περίπτωση, ο λογικός χωρισμός μπορεί να συμβεί για σύντομο χρονικό διάστημα, αλλά μόνο εάν λαβές=1 и min.insync.replicas επίσης 1. Ο λογικός διαχωρισμός τερματίζεται αυτόματα είτε μετά την αποκατάσταση του δικτύου, όταν ο αρχικός ηγέτης συνειδητοποιήσει ότι δεν είναι πλέον ο αρχηγός ή όταν όλοι οι πελάτες συνειδητοποιήσουν ότι ο ηγέτης έχει αλλάξει και αρχίζουν να γράφουν στον νέο ηγέτη - όποιο συμβεί πρώτο. Σε κάθε περίπτωση, κάποια μηνύματα θα χαθούν, αλλά μόνο με λαβές=1.

Υπάρχει μια άλλη παραλλαγή αυτού του σεναρίου όπου, λίγο πριν τη διάσπαση του δικτύου, οι οπαδοί έμειναν πίσω και ο ηγέτης συμπίεσε το ISR μόνο στον εαυτό του. Στη συνέχεια απομονώνεται λόγω απώλειας συνδεσιμότητας. Ένας νέος αρχηγός εκλέγεται, αλλά ο αρχικός αρχηγός συνεχίζει να δέχεται συμμετοχές, ακόμη και acks=όλα, γιατί δεν υπάρχει κανένας άλλος στο ISR εκτός από αυτόν. Αυτές οι εγγραφές θα χαθούν μόλις αποκατασταθεί το δίκτυο. Ο μόνος τρόπος για να αποφύγετε αυτή την επιλογή είναι min.insync.replicas = 2.

Σενάριο 7: Ο κόμβος ελεγκτή Kafka δεν μπορεί να δει άλλον κόμβο Kafka

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

Σενάριο 8: Ο ελεγκτής Kafka δεν βλέπει τον Zookeeper

Ο Zookeeper δεν θα λάβει ping από τον πεσμένο ελεγκτή και θα επιλέξει έναν νέο κόμβο Kafka ως ελεγκτή. Ο αρχικός ελεγκτής μπορεί να συνεχίσει να παρουσιάζεται ως τέτοιος, αλλά δεν λαμβάνει ειδοποιήσεις από το Zookeeper, επομένως δεν θα έχει καμία εργασία να εκτελέσει. Μόλις αποκατασταθεί το δίκτυο, θα συνειδητοποιήσει ότι δεν είναι πλέον ελεγκτής, αλλά έχει γίνει ένας κανονικός κόμβος Κάφκα.

Συμπεράσματα από τα σενάρια

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

Εάν ο αρχηγός αποχωριστεί από το Zookeeper λόγω απώλειας συνδεσιμότητας, αυτό θα μπορούσε να έχει ως αποτέλεσμα την απώλεια μηνυμάτων από λαβές=1. Η έλλειψη επικοινωνίας με τον Zookeeper προκαλεί μια σύντομη λογική διάσπαση με τους δύο ηγέτες. Αυτό το πρόβλημα επιλύεται από την παράμετρο acks=όλα.

Παράμετρος min.insync.replicas σε δύο ή περισσότερα αντίγραφα παρέχει πρόσθετη διασφάλιση ότι τέτοια βραχυπρόθεσμα σενάρια δεν θα οδηγήσουν σε χαμένα μηνύματα όπως στο Σενάριο 6.

Σύνοψη των χαμένων μηνυμάτων

Ας παραθέσουμε όλους τους τρόπους με τους οποίους μπορείτε να χάσετε δεδομένα στον Κάφκα:

  • Οποιαδήποτε αποτυχία του ηγέτη εάν τα μηνύματα επιβεβαιώθηκαν χρησιμοποιώντας λαβές=1
  • Οποιαδήποτε ακάθαρτη μετάβαση ηγεσίας, δηλαδή σε οπαδό εκτός ISR, ακόμη και με acks=όλα
  • Απομόνωση του αρχηγού από το Zookeeper εάν τα μηνύματα επιβεβαιώθηκαν χρησιμοποιώντας λαβές=1
  • Πλήρης απομόνωση του ηγέτη που έχει ήδη συρρικνώσει την ομάδα ISR στον εαυτό του. Όλα τα μηνύματα θα χαθούν, ακόμη και acks=όλα. Αυτό ισχύει μόνο αν min.insync.replicas=1.
  • Ταυτόχρονες αποτυχίες όλων των κόμβων διαμερισμάτων. Επειδή τα μηνύματα αναγνωρίζονται από τη μνήμη, ορισμένα ενδέχεται να μην έχουν ακόμη εγγραφεί στο δίσκο. Μετά την επανεκκίνηση των διακομιστών, ενδέχεται να λείπουν ορισμένα μηνύματα.

Οι ακάθαρτες μεταβάσεις ηγεσίας μπορούν να αποφευχθούν είτε με την απαγόρευσή τους είτε με την εξασφάλιση τουλάχιστον δύο απολύσεων. Η πιο ανθεκτική διαμόρφωση είναι ένας συνδυασμός acks=όλα и min.insync.replicas περισσότερα από 1.

Άμεση σύγκριση της αξιοπιστίας των RabbitMQ και Kafka

Για να διασφαλιστεί η αξιοπιστία και η υψηλή διαθεσιμότητα, και οι δύο πλατφόρμες εφαρμόζουν ένα πρωτεύον και δευτερεύον σύστημα αναπαραγωγής. Ωστόσο, το RabbitMQ έχει αχίλλειο πτέρνα. Κατά την επανασύνδεση μετά από αποτυχία, οι κόμβοι απορρίπτουν τα δεδομένα τους και ο συγχρονισμός αποκλείεται. Αυτή η διπλή σύγκρουση θέτει υπό αμφισβήτηση τη μακροζωία των μεγάλων ουρών στο RabbitMQ. Θα πρέπει να αποδεχτείτε είτε μειωμένο πλεονασμό είτε μεγάλους χρόνους αποκλεισμού. Η μείωση του πλεονασμού αυξάνει τον κίνδυνο μαζικής απώλειας δεδομένων. Αλλά εάν οι ουρές είναι μικρές, τότε για λόγους πλεονασμού, μπορούν να αντιμετωπιστούν σύντομες περίοδοι μη διαθεσιμότητας (λίγα δευτερόλεπτα) χρησιμοποιώντας επαναλαμβανόμενες προσπάθειες σύνδεσης.

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

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

  • fsync κάθε μερικές εκατοντάδες χιλιοστά του δευτερολέπτου
  • Η αποτυχία του mirror μπορεί να παρατηρηθεί μόνο αφού λήξει η διάρκεια ζωής των πακέτων που ελέγχουν τη διαθεσιμότητα κάθε κόμβου (net tick). Εάν ο καθρέφτης επιβραδύνει ή πέσει, αυτό προσθέτει καθυστέρηση.

Το στοίχημα του Κάφκα είναι ότι εάν ένα μήνυμα είναι αποθηκευμένο σε πολλούς κόμβους, μπορεί να αναγνωρίσει τα μηνύματα αμέσως μόλις φτάσουν στη μνήμη. Εξαιτίας αυτού, υπάρχει κίνδυνος απώλειας μηνυμάτων οποιουδήποτε τύπου (ακόμα και acks=όλα, min.insync.replicas=2) σε περίπτωση ταυτόχρονης αστοχίας.

Συνολικά, ο Kafka παρουσιάζει καλύτερη απόδοση λογισμικού και έχει σχεδιαστεί από την αρχή για clusters. Ο αριθμός των ακολούθων μπορεί να αυξηθεί σε 11 εάν είναι απαραίτητο για αξιοπιστία. Συντελεστής αναπαραγωγής 5 και ελάχιστος αριθμός αντιγράφων σε συγχρονισμό min.insync.replicas=3 θα κάνει την απώλεια μηνύματος ένα πολύ σπάνιο γεγονός. Εάν η υποδομή σας μπορεί να υποστηρίξει αυτήν την αναλογία αναπαραγωγής και το επίπεδο πλεονασμού, τότε μπορείτε να επιλέξετε αυτήν την επιλογή.

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

Ένα αντίδοτο για την ευπάθεια του RabbitMQ στις μεγάλες ουρές είναι να τις χωρίσει σε πολλές μικρότερες ουρές. Εάν δεν χρειάζεστε πλήρη παραγγελία ολόκληρης της ουράς, αλλά μόνο των σχετικών μηνυμάτων (για παράδειγμα, μηνύματα από έναν συγκεκριμένο πελάτη) ή δεν παραγγείλετε τίποτα, τότε αυτή η επιλογή είναι αποδεκτή: δείτε το έργο μου Rebalancer να χωρίσει την ουρά (το έργο είναι ακόμα σε πρώιμο στάδιο).

Τέλος, μην ξεχνάτε έναν αριθμό σφαλμάτων στους μηχανισμούς ομαδοποίησης και αναπαραγωγής τόσο του RabbitMQ όσο και του Kafka. Με τον καιρό, τα συστήματα έχουν γίνει πιο ώριμα και σταθερά, αλλά κανένα μήνυμα δεν θα είναι ποτέ 100% ασφαλές από απώλεια! Επιπλέον, ατυχήματα μεγάλης κλίμακας συμβαίνουν σε data centers!

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

Με ρωτούν συχνά: «Τι να διαλέξω, Kafka ή RabbitMQ;», «Ποια πλατφόρμα είναι καλύτερη;». Η αλήθεια είναι ότι εξαρτάται πραγματικά από την κατάστασή σας, την τρέχουσα εμπειρία σας κ.λπ. Διστάζω να πω τη γνώμη μου γιατί θα ήταν υπερβολική απλούστευση να προτείνουμε μία πλατφόρμα για όλες τις περιπτώσεις χρήσης και τους πιθανούς περιορισμούς. Έγραψα αυτή τη σειρά άρθρων για να σχηματίσετε τη δική σας γνώμη.

Θέλω να πω ότι και τα δύο συστήματα είναι ηγέτες σε αυτόν τον τομέα. Μπορεί να είμαι λίγο προκατειλημμένος γιατί από την εμπειρία μου με έργα τείνω να εκτιμώ πράγματα όπως η εγγυημένη παραγγελία μηνυμάτων και η αξιοπιστία.

Βλέπω άλλες τεχνολογίες που δεν έχουν αυτή την αξιοπιστία και την εγγυημένη παραγγελία, μετά κοιτάζω το RabbitMQ και το Kafka και συνειδητοποιώ την απίστευτη αξία και των δύο αυτών συστημάτων.

Πηγή: www.habr.com

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