Κ Σ Ι Εκλογή αρχηγού σε σύγχρονο δακτύλιο: Οι αλγόριθμοι LCR και HS Παναγιώτα Παναγοπούλου 1 Ο αλγόριθμος LCR (Le Lann, Chang, and Roberts) Ο αλγόριθμος LCR είναι ένας αλγόριθμος εκλογής αρχηγού σε ένα σύγχρονο κατανεμημένο δίκτυο τοπολογίας δακτυλίου. Θεωρούμε ότι οι n διεργασίες είναι αριθμημένες από 0 έως n 1 σύφωνα με τη φορά των δεικτών του ρολογιού (δεξιόστροφα). Έτσι, κάθε κόμβος (διεργασία) i {0, 1,..., n 1} του δικτύου έχει εισερχόμενο γείτονα τον i 1 και εξερχόμενο γείτονα τον i+1 (η αρίθμηση γίνεται modulo n). Οι διεργασίες έχουν μοναδικές ταυτότητες (UIDs), οι οποίες εν γένει δεν σχετίζονται με τους δείκτες τους i. Συμβολίζουμε με u i το UID της διεργασίας i. Ο αλγόριθμος LCR εκλέγει ως αρχηγό τη διεργασία i max {0, 1,..., n 1} που έχει το μεγαλύτερο UID, δηλαδή u imax u i i {0, 1,..., n 1}. Συμβολίζουμε με u max το μέγιστο UID στο δίκτυο, δηλαδή u max = u imax. 1.1 Περιγραφή του αλγορίθμου LCR Άτυπη περιγραφή του αλγορίθμου LCR. Κάθε διεργασία στέλνει το UID της στον εξερχόμενο γείτονά της. Όταν μια διεργασία λάβει ένα εισερχόμενο UID, το συγκρίνει με το δικό της UID. Αν το εισερχόμενο UID είναι μεγαλύτερο από το δικό της, προωθεί το UID που έλαβε στο δίκτυο (δηλαδή το στέλνει στον εξερχόμενο γείτονά της). Αν είναι μικρότερο, το αγνοεί (δεν το προωθεί). Αν είναι ίσο, η διεργασία εκλέγεται αρχηγός. Τυπική περιγραφή του αλγορίθμου LCR. σύμφωνα με το σύγχρονο δικτυακό μοντέλο. Δίνουμε τώρα μια πιο αναλυτική περιγραφή του αλγορίθμου Το αλφάβητο μηνυμάτων M είναι ακριβώς το σύνολο των UIDs. Για κάθε i, οι καταστάσεις στο σύνολο states i αποτελούνται από τις παρακάτω συνιστώσες: u, ένα UID, αρχικά το UID της i send, ένα UID ή null, αρχικά το UID της i status, με τιμές στο {unknown, leader, non_leader}, αρχικά unknown 1
Το σύνολο των αρχικών καταστάσεων start i αποτελείται από τη μοναδική κατάσταση που ορίζεται από τις παραπάνω αρχικοποιήσεις των μεταβλητών. Για κάθε i, η γεννήτρια μηνυμάτων msgs i ορίζεται ως εξής: στείλε την τρέχουσα τιμή του send στη διεργασία i + 1 Για κάθε i, η συνάρταση αλλαγής κατάστασης trans i ορίζεται ως εξής: send := null if το εισερχόμενο μήνυμα είναι το UID v then case v > u: v = u: v < u: endcase endif send := v, status := non_leader status := leader (μην κάνεις τίποτα) 1.2 Ορθότητα του αλγορίθμου LCR Για να αποδείξουμε ότι ο αλγόριθμος LCR που περιγράψαμε είναι σωστός, πρέπει να αποδείξουμε ότι ακριβώς μία διεργασία δίνει ως έξοδο status = leader. Θυμίζουμε ότι συμβολίζουμε με i max {0, 1,..., n 1} τη διεργασία με το μέγιστο UID και με u max την τιμή του UID της (δηλαδή το μέγιστο UID στο δίκτυο). Αρκεί να αποδείξουμε ότι (1) η διεργασία i max δίνει έξοδο leader στο τέλος του γύρου n και (2) κάθε άλλη διεργασία δίνει έξοδο non_leader μέχρι το τέλος του γύρου n. Για να είναι πιο σαφής η ανάλυση του αλγορίθμου, χρησιμοποιούμε το δείκτη i στο όνομα μιας συνιστώσας (μεταβλητής) μιας κατάστασης, ώστε να δείχνει την τιμή αυτής της συνιστώσας που ανήκει στη διεργασία i (δηλαδή οι u i, send i, status i αναφέρονται στις τιμές των μεταβλητών u, send, status της διεργασίας i). Λήμμα 1 Η διεργασία i max δίνει έξοδο leader στο τέλος του γύρου n. Απόδειξη. Παρατηρούμε ότι η αρχική τιμής της u imax είναι η u max, λόγω της αρχικοποίησης της μεταβλητής u της διεργασίας i max. Επίσης παρατηρούμε ότι οι τιμές των μεταβλητών u δεν αλλάζουν ποτέ στον αλγόριθμο και ότι είναι όλες μοναδικές (λόγω της υπόθεσης των μοναδικών ταυτοτήτων). Με βάση τον ψευδοκώδικα, αρκεί να αποδείξουμε ότι status imax = leader μετά από n γύρους. Για να το αποδείξουμε, αρκεί να δείξουμε ότι, για κάθε 0 r n 1, μετά από r γύρους, send imax+r = u max (θυμίζουμε ότι η πρόσθεση i max + r γίνεται modulo n). Αυτό σημαίνει ότι, μετά από r γύρους, το μέγιστο UID εμφανίζεται στη μεταβλητή send της διεργασίας που βρίσκεται στο δακτύλιο σε απόσταση r από την i max. Θα το αποδείξουμε με επαγωγή στο r. Επαγωγική βάση. Για r = 0 (δηλαδή μετά το γύρο 0, άρα όταν ξεκινά ο αλγόριθμος), η αρχικοποίηση δηλώνει ότι send imax+r = send imax+0 = send imax = u max μετά από 0 γύρους, άρα το ζητούμενο ισχύει. 2
Επαγωγική υπόθεση. Έστω ότι, μετά από r γύρους, ισχύει ότι send imax+r = u max (για κάποιο 0 r n 2). Επαγωγικό βήμα. Μετά από r + 1 γύρους, η διεργασία i max + r + 1 έχει λάβει το u max. Αυτό ισχύει επειδή, αμέσως μετά το γύρο r, ο εισερχόμενος γείτονάς της i max + r θέτει send imax+r = u max (από την επαγωγική υπόθεση). Έτσι, όταν γίνεται η ανταλλαγή μηνυμάτων κατά τη διάρκεια του γύρου r + 1, η i max + r + 1 παραλαμβάνει το u max και στη συνέχεια το συγκρίνει με το δικό της UID, δηλαδή με το u imax+r+1. Επειδή u imax+r+1 < u max, θέτει send imax+r+1 = u max. Άρα το ζητούμενο ισχύει μετά από r + 1 γύρους. Αποδείξαμε ότι, για κάθε 0 r n 1, μετά από r γύρους, send imax+r = u max. Για r = n 1, προκύπτει ότι μετά από n 1 γύρους, η διεργασία i max + n 1 θέτει send imax+n 1 = u max. Άρα η διεργασία i max +n 1 στέλνει στο γύρο n την τιμή u max στον εξερχόμενο γείτονάς της. Όμως ο εξερχόμενος γείτονας της i max + n 1 είναι η διεργασία i max. Άρα στο γύρο n η i max λαμβάνει το δικό της UID, άρα θέτει status imax = leader. Λήμμα 2 Κάθε διεργασία i i max θέτει status i = non_leader μέχρι το τέλος του γύρου n. Απόδειξη. Όπως και στο προηγούμενο λήμμα, μπορούμε να αποδείξουμε ότι, για κάθε 1 r n 1, μέχρι το τέλος του γύρου r, η διεργασία i max + r έχει θέσει status imax+r = non_leader, και η τιμή αυτή δεν αλλάζει. Οι λεπτομέρειες της απόδειξης αφήνονται ως άσκηση. 1.3 Πολυπλοκότητα του αλγορίθμου LCR Η χρονική πολυπλοκότητα του αλγορίθμου LCR είναι ακριβώς n γύροι. Η πολυπλοκότητα επικοινωνίας (δηλαδή το συνολικό πλήθος των μηνυμάτων που ανταλλάσσονται) είναι O(n 2 ) επειδή, στη χειρότερη περίπτωση, οι διεργασίες είναι διατεταγμένες στο δακτύλιο με τέτοιο τρόπο ώστε u 0 > u 1 > > u n. Έτσι, στον 1ο γύρο στέλνονται n μηνύματα (όλες οι διεργασίες στέλνουν στον εξερχόμενο γείτονά τους το UID τους). Στο δεύτερο γύρο στέλνονται n 1 μηνύματα (επειδή όλες, εκτός από την i max = 0 έλαβαν ένα μεγαλύτερο UID στον προηγούμενο γύρο). Στον τρίτο γύρο στέλνονται n 2 μηνύματα (επειδή όλες, εκτός από τις 0 και 1 έλαβαν ένα μεγαλύτερο UID στον προηγούμενο γύρο), κ.ο.κ. Έτσι, σε κάθε γύρο 1 r n 1, ακριβώς n r +1 διεργασίες στέλνουν μήνυμα στον εξερχόμενο γείτονά τους. Άρα συνολικά απαιτούνται n n r + 1 = r=1 n i = i=1 n(n + 1) 2 = O(n 2 ) μηνύματα. 2 Ο αλγόριθμος HS (Hisrchberg and Sinclair) Αν και η πολυπλοκότητα χρόνου του αλγορίθμου LCR είναι μικρή, το πλήθος των μηνυμάτων O(n 2 ) που απαιτεί θεωρείται μεγάλο. Θα παρουσιάσουμε εδώ τον αλγόριθμο HS που επιτυγχάνει πολυπλοκότητα επικοινωνίας O(n log n). Ο αλγόριθμος υποθέτει διεργασίες με μοναδικές ταυτότητες σε τοπολογία δακτυλίου, αλλά η επικοινωνία είναι αμφίδρομη. Με άλλα λόγια υποθέτουμε ότι ο δακτύλιος είναι μη κατευθυνόμενος. 3
Ο αλγόριθμος HS, όπως και ο LCR, εκλέγει ως αρχηγό τη διεργασία με το μέγιστο UID. Εδώ όμως κάθε διεργασία, αντί να στέλνει το UID της με σκοπό να ταξιδέψει σε όλο το δακτύλιο (όπως γίνεται στον LCR), το στέλνει με σκοπό να ταξιδέψει μια συγκεκριμένη απόσταση και να επιστρέψει πίσω σε αυτή (εφόσον δεν συναντήσει κάποιο μεγαλύτερο UID στη διαδρομή). Η διαδικασία αυτή επαναλαμβάνεται, αυξάνοντας διαδοχικά τις αποστάσεις στις οποίες ταξιδεύουν τα UIDs. 2.1 Περιγραφή του αλγορίθμου HS Κάθε διεργασία i λειτουργεί σε φάσεις 0, 1, 2,.... Σε κάθε φάση l, η διεργασία i στέλνει μηνύματα (tokens) με το UID της u i και προς τις δύο κατευθύνσεις (δηλαδή και στην i 1 και στην i + 1). Αυτά τα tokens έχουν σκοπό να ταξιδέψουν σε απόσταση 2 l και να επιστρέψουν στην αφετηρία τους i, εφόσον δεν συναντήσουν κάποιο μεγαλύτερο UID. Αν και τα δύο tokens επιστρέψουν, η διεργασία i προχωρά στην επόμενη φάση l +1. Ωστόσο, ενδέχεται να μην επιστρέψει κάποιο token. Καθώς ένα token u i προχωρά προς τα έξω, καθώς απομακρύνεται δηλαδή από την i, κάθε άλλη διεργασία j στο μονοπάτι του u i συγκρίνει το u i με το δικό της UID u j. Αν u i < u j τότε η j αγνοεί το token u i (δεν το προωθεί, το καταστρέφει). Αν u i > u j, η j προωθεί το token u i. Αν u i = u j, αυτό σημαίνει ότι η διεργασία j έχει λάβει το token με το δικό της UID ενώ αυτό προχωρά προς τα έξω (ενώ απομακρύνεται δηλαδή από την j), και τότε η διεργασία j εκλέγεται αρχηγός. Όλες οι διεργασίες προωθούν πάντα τα tokens όταν αυτά έχουν φορά προς τα μέσα, όταν δηλαδή επιστρέφουν στη διεργασία από την οποία ξεκίνησαν. Θα παραλείψουμε την τυπική περιγραφή του αλγορίθμου HS, καθώς απαιτεί διάφορες τεχνικές λεπτομέρειες στις οποίες δεν κρίνουμε σκόπιμο να εστιάσουμε. Ενδεικτικά αναφέρουμε ότι τα tokens πρέπει να έχουν ενδείξεις που θα υποδηλώνουν αν ταξιδεύουν προς τα έξω ή προς τα μέσα. Επίσης, πρέπει να έχουν μετρητές ώστε να υπολογίζουν την απόσταση που πρέπει να διανύσουν πριν αρχίσουν να επιστρέφουν στη διεργασία από όπου ξεκίνησαν. 2.2 Πολυπλοκότητα του αλγορίθμου HS Πολυπλοκότητα επικοινωνίας. Αναλύουμε αρχικά την πολυπλοκότητα επικοινωνίας του HS. Κάθε διεργασία στέλνει 2 tokens στη φάση 0, ένα προς κάθε κατεύθυνση, με σκοπό να ταξιδέψει απόσταση 2 0 = 1 και να επιστρέψει (εφόσον επιβιώσει, δηλαδή δεν συναντήσει μεγαλύτερο UID). Άρα η φάση 0 απαιτεί το πολύ 4n μηνύματα (2n tokens, επί 2 hops ώστε να ταξιδέψει το καθένα απόσταση 1 και να επιστρέψει). Στη φάση l > 0, μια διεργασία στέλνει tokens αν και μόνο αν έλαβε πίσω και τα δύο tokens που έστειλε στην προηγούμενη φάση l 1. Αυτό συμβαίνει αν και μόνο αν δεν νικήθηκε από κάποια άλλη διεργασία σε απόσταση 2 l 1 από αυτή (και στις δύο κατευθύνσεις) στο δακτύλιο, δηλαδή αν και μόνο αν η διεργασία έχει μεγαλύτερο UID από τις διεργασίες που βρίσκονται στις πρώτες 2 l 1 θέσεις δεξιά της και στις πρώτες 2 l+1 θέσεις αριστερά της στο δακτύλιο. Αυτό σημαίνει ότι μέσα σε κάθε ομάδα 2 l 1 + 1 διαδοχικών διεργασιών στο δακτύλιο, το πολύ μία στέλνει tokens στη φάση l. Άρα το πολύ n 2 l 1 + 1 διεργασίες συνολικά στέλνουν tokens στη φάση l. Τα tokens στέλνονται και προς τις δύο κατευθυνσεις, και καθένα από αυτά ταξιδεύει απόσταση το πολύ 2 l και επιστρέφει. Άρα το συνολικό πλήθος των μηνυμάτων 4
που στέλνονται στη φάση l είναι το πολύ 2 2 2 l n 2 l 1 + 1 2l+2 n = 8n. 2l 1 Το συνολικό πλήθος των φάσεων που απαιτούνται πριν εκλεγεί ο αρχηγός είναι το πολύ log n. Αυτό συμβαίνει επειδή, προκειμένου να εκλεγεί η i max αρχηγός, πρέπει να στείλει το token της ώστε να ταξιδέψει απόσταση 2 l n, έτσι ώστε να το λάβει καθώς αυτό έχει φορά προς τα έξω. Άρα πρέπει l log n, άρα απαιτούνται το πολύ log n log n + 1 φάσεις. Άρα συνολικά απαιτούνται το πολύ μηνύματα. 8n(log n + 1) = O(n log n) Πολυπλοκότητα χρόνου. Παρατηρούμε ότι κάθε φάση l (εκτός από την τελευταία) απαιτεί 2 2 l = 2 l+1 γύρους, αφού κάθε token πρέπει να ταξιδέψει απόσταση 2 l και να επιστρέψει. Η τελευταία φάση απαιτεί ακριβώς n γύρους. Η προτελευταία φάση είναι η φάση log n 1, επομένως το συνολικό πλήθος των γύρων που απαιτούνται είναι log n 1 l=0 log n 1 2 l+1 + n = 2 l=0 2 l + n 2 2 log n + n. Επομένως αν το n είναι δύναμη του 2 τότε η πολυπλοκότητα χρόνου είναι το πολύ 2n+n = 3n, διαφορετικά η πολυπλοκότητα χρόνου είναι το πολύ 2 2 log n+1 + n = 5n. 5