Paxos (informatică) - Paxos (computer science)
Paxos este o familie de protocoale pentru rezolvarea consensului într-o rețea de procesoare nesigure sau falibile. Consensul este procesul de a conveni asupra unui rezultat între un grup de participanți. Această problemă devine dificilă atunci când participanții sau comunicările lor pot întâmpina eșecuri.
Protocoalele de consens sunt baza pentru abordarea de replicare a mașinilor de stat pentru calculul distribuit, așa cum sugerează Leslie Lamport și chestionat de Fred Schneider . Replicarea mașinii de stat este o tehnică pentru conversia unui algoritm într-o implementare distribuită tolerantă la erori. Tehnicile ad-hoc pot lăsa nerezolvate cazuri importante de eșecuri. Abordarea principială propusă de Lamport și colab. se asigură că toate cazurile sunt manipulate în siguranță.
Protocolul Paxos a fost prezentat pentru prima dată în 1989 și denumit după un sistem legislativ fictiv de consens utilizat pe insula Paxos din Grecia, unde Lamport a scris că parlamentul trebuie să funcționeze „chiar dacă legiuitorii au rătăcit continuu în și în afara camerei parlamentare”. Ulterior a fost publicat ca articol de revistă în 1998.
Familia de protocoale Paxos include un spectru de compromisuri între numărul de procesoare, numărul de întârzieri ale mesajelor înainte de a afla valoarea convenită, nivelul de activitate al participanților individuali, numărul de mesaje trimise și tipurile de eșecuri. Deși niciun protocol de consens determinist tolerant la defecțiuni nu poate garanta progresul într-o rețea asincronă (un rezultat dovedit într-o lucrare de Fischer , Lynch și Paterson ), Paxos garantează siguranța (consistența), iar condițiile care ar putea să-l împiedice să facă progrese sunt dificil de realizat. a provoca.
Paxos este de obicei utilizat acolo unde durabilitatea este necesară (de exemplu, pentru a reproduce un fișier sau o bază de date), în care cantitatea de stare durabilă ar putea fi mare. Protocolul încearcă să facă progrese chiar și în perioadele în care un număr limitat de replici nu răspund. Există, de asemenea, un mecanism pentru a renunța la o replică nereușită definitiv sau pentru a adăuga o nouă replică.
Istorie
Subiectul precede protocolul. În 1988, Lynch , Dwork și Stockmeyer au demonstrat solvabilitatea consensului într-o familie largă de sisteme „parțial sincrone”. Paxos are asemănări puternice cu un protocol utilizat pentru acord în „replicarea vizualizată”, publicat pentru prima dată de Oki și Liskov în 1988, în contextul tranzacțiilor distribuite. În pofida acestei lucrări anterioare, Paxos a oferit un formalism deosebit de elegant și a inclus una dintre cele mai vechi dovezi de siguranță pentru un protocol consens distribuit tolerant la defecțiuni.
Mașinile de stat reconfigurabile au legături strânse cu munca anterioară privind protocoalele fiabile de grup multicast care susțin apartenența la grup dinamic, de exemplu munca Birman din 1985 și 1987 privind protocolul gbcast practic sincron . Cu toate acestea, gbcast este neobișnuit în susținerea durabilității și în soluționarea eșecurilor de partiționare. Cele mai multe protocoale multicast fiabile nu au aceste proprietăți, care sunt necesare pentru implementările modelului de replicare a mașinii de stat. Acest punct este elaborat într-o lucrare de Lamport , Malkhi și Zhou.
Protocoalele Paxos sunt membre ale unei clase teoretice de soluții la o problemă formalizată ca acord uniform cu eșecurile de avarie. Limitele inferioare pentru această problemă au fost dovedite de Keidar și Shraer. Derecho, o bibliotecă software C ++ pentru replicarea mașinii de stat la scară cloud, oferă un protocol Paxos care a fost integrat cu abonament practic sincron autogestionat. Acest protocol se potrivește cu limitele de optimitate Keidar și Shraer și se mapează eficient la hardware-ul modern al centrului de date DMA (RDMA) la distanță (dar folosește TCP dacă RDMA nu este disponibil).
Ipoteze
Pentru a simplifica prezentarea Paxos, următoarele presupuneri și definiții sunt explicite. Tehnicile de extindere a aplicabilității sunt cunoscute în literatura de specialitate și nu sunt tratate în acest articol.
Procesoare
- Procesoarele funcționează la o viteză arbitrară.
- Procesoarele pot întâmpina eșecuri.
- Procesoarele cu stocare stabilă pot re-adera la protocol după eșecuri (urmând un model de eșec de recuperare a erorilor).
- Procesoarele nu intră în coliziune, nu mint sau nu încearcă altfel să subvertizeze protocolul. (Adică, eșecurile bizantine nu apar. Consultați Paxos bizantin pentru o soluție care tolerează eșecurile care apar din comportamentul arbitrar / rău intenționat al proceselor.)
Reţea
- Procesoarele pot trimite mesaje către orice alt procesor.
- Mesajele sunt trimise asincron și pot fi livrate în mod arbitrar.
- Mesajele pot fi pierdute, reordonate sau duplicate.
- Mesajele sunt livrate fără corupție. (Adică, eșecurile bizantine nu apar. Consultați Paxos bizantin pentru o soluție care tolerează mesajele corupte care apar din comportamentul arbitrar / rău intenționat al canalelor de mesagerie.)
Număr de procesoare
În general, un algoritm consens poate face progrese folosind procesoare, în ciuda eșecului simultan al oricăror procesoare: cu alte cuvinte, numărul de procese non-defecte trebuie să fie strict mai mare decât numărul de procese defecte. Cu toate acestea, utilizând reconfigurarea, poate fi utilizat un protocol care supraviețuiește oricărui număr de eșecuri totale atâta timp cât nu mai mult de F eșuează simultan. Pentru protocoalele Paxos, aceste reconfigurări pot fi tratate ca configurații separate .
Roluri
Paxos descrie acțiunile procesorilor prin rolurile lor în protocol: client, acceptor, propunător, cursant și lider. În implementările tipice, un singur procesor poate juca unul sau mai multe roluri în același timp. Acest lucru nu afectează corectitudinea protocolului - este obișnuit să se unească rolurile pentru a îmbunătăți latența și / sau numărul de mesaje din protocol.
- Client
- Clientul trimite o cerere către sistemul distribuit și așteaptă un răspuns . De exemplu, o cerere de scriere pe un fișier într-un server de fișiere distribuit.
- Acceptor (alegători)
- Acceptorii acționează ca „memoria” tolerantă la erori a protocolului. Acceptanții sunt colectați în grupuri numite cvorumuri. Orice mesaj trimis către un acceptor trebuie trimis către un cvorum de acceptori. Orice mesaj primit de la un acceptor este ignorat, cu excepția cazului în care se primește o copie de la fiecare acceptor dintr-un cvorum.
- Propunător
- Un Propunător pledează pentru o cerere a clientului, încercând să-i convingă pe Acceptori să fie de acord și acționează ca un coordonator pentru a avansa protocolul atunci când apar conflicte.
- Învățător
- Elevii acționează ca factor de replicare pentru protocol. Odată ce o cerere a Clientului a fost agreată de Acceptori, Elevul poate lua măsuri (de exemplu: execută cererea și trimite un răspuns clientului). Pentru a îmbunătăți disponibilitatea procesării, pot fi adăugați cursanți suplimentari.
- Lider
- Paxos necesită un propunător distins (numit lider) pentru a face progrese. Multe procese pot crede că sunt lideri, dar protocolul garantează progresul doar dacă unul dintre ei este ales în cele din urmă. Dacă două procese cred că sunt lideri, pot bloca protocolul propunând continuu actualizări conflictuale. Cu toate acestea, proprietățile de siguranță sunt încă păstrate în acest caz.
Cvorumuri
Cvorumurile exprimă proprietățile de siguranță (sau consistență) ale Paxos, asigurându-se că cel puțin un procesor supraviețuitor păstrează cunoștințele despre rezultate.
Cvorumurile sunt definite ca subseturi ale setului de acceptori, astfel încât oricare două subseturi (adică oricare două cvorumuri) să împartă cel puțin un membru. De obicei, un cvorum este majoritatea acceptorilor participanți. De exemplu, având în vedere setul de acceptori {A, B, C, D}, un cvorum majoritar ar fi trei acceptori: {A, B, C}, {A, C, D}, {A, B, D} , {B, C, D}. Mai general, ponderile pozitive arbitrare pot fi atribuite acceptorilor; în acest caz, un cvorum poate fi definit ca orice subset de acceptori cu greutatea sumară mai mare de jumătate din greutatea totală a tuturor acceptorilor.
Numărul propunerii și valoarea convenită
Fiecare încercare de a defini o valoare convenită v se realizează cu propuneri care pot sau nu să fie acceptate de acceptori. Fiecare propunere este numerotată în mod unic pentru un anumit Propunător. Deci, de exemplu, fiecare propunere poate avea forma (n, v) , unde n este identificatorul unic al propunerii și v este valoarea propusă efectivă. Valoarea corespunzătoare unei propuneri numerotate poate fi calculată ca parte a rulării protocolului Paxos, dar nu trebuie să fie.
Proprietăți de siguranță și viață
Pentru a garanta siguranța (numită și "consistență"), Paxos definește trei proprietăți și se asigură că primele două sunt întotdeauna păstrate, indiferent de tiparul de defecțiuni:
- Valabilitate (sau non-trivialitate )
- Doar valorile propuse pot fi alese și învățate.
- Acord (sau consecvență sau siguranță )
- Niciun cursant distinct nu poate învăța valori diferite (sau nu poate exista mai mult de o valoare decisă)
- Încetare (sau vioiciune)
- Dacă s-a propus valoarea C, atunci în cele din urmă cursantul L va învăța o anumită valoare (dacă procesoare suficiente rămân neafectate).
Rețineți că Paxos nu este garantat să înceteze și, prin urmare, nu are proprietatea de viață. Acest lucru este susținut de rezultatul imposibilității Fischer Lynch Paterson (FLP), care afirmă că un protocol de consistență poate avea doar două de siguranță , viață și toleranță la erori . Întrucât punctul Paxos este să asigure toleranța la erori și să garanteze siguranța, nu poate garanta, de asemenea, viața.
Implementare tipică
În majoritatea implementărilor Paxos, fiecare proces participant acționează în trei roluri; Propunător, acceptant și cursant. Acest lucru reduce semnificativ complexitatea mesajului, fără a sacrifica corectitudinea:
În Paxos, clienții trimit comenzi către un lider. În timpul funcționării normale, liderul primește comanda unui client, îi atribuie un nou număr de comandă i, iar apoi începe instanța a algoritmului consens prin trimiterea de mesaje către un set de procese acceptor.
Prin îmbinarea rolurilor, protocolul „se prăbușește” într-o implementare eficientă a stilului client-master-replică, tipic comunității bazei de date. Avantajul protocoalelor Paxos (inclusiv implementările cu roluri combinate) este garanția proprietăților sale de siguranță .
Fluxul de mesaje al unei implementări tipice este acoperit în secțiunea Multi-Paxos .
Paxos de bază
Acest protocol este cel mai de bază din familia Paxos. Fiecare „instanță” (sau „execuție”) a protocolului de bază Paxos decide asupra unei singure valori de ieșire. Protocolul se desfășoară pe mai multe runde. O rundă de succes are 2 faze: faza 1 (care este împărțită în părțile a și b ) și faza 2 (care este împărțită în părțile a și b ). Vezi mai jos descrierea fazelor. Amintiți-vă că presupunem un model asincron, deci un procesor poate fi într-o fază, în timp ce un alt procesor poate fi într-o altă fază.
Faza 1
Faza 1a: Pregătiți-vă
- Un Propunător creează un mesaj, pe care îl numim „Pregătiți”, identificat cu un număr n . Rețineți că n nu este valoarea care trebuie propusă și poate convenită, ci doar un număr care identifică în mod unic acest mesaj inițial de către propunător (care trebuie trimis acceptatorilor). Numărul n trebuie să fie mai mare decât orice număr utilizat în oricare dintre mesajele anterioare Pregătiți de acest propunător. Apoi, trimite mesajul Pregătiți care conține n către un cvorum de acceptori . Rețineți că mesajul Pregătiți conține doar numărul n (adică nu trebuie să conțină, de exemplu, valoarea propusă, adesea notată cu v ). Propunătorul decide cine se află în Cvorum. Un propunător nu ar trebui să inițieze Paxos dacă nu poate comunica cu cel puțin un cvorum de acceptori.
Faza 1b: Promisiune
- Oricare dintre acceptori așteaptă un mesaj Pregătiți de la oricare dintre Propunători . În cazul în care un Acceptor primește un mesaj Pregătiți, acceptorul trebuie să se uite la numărul de identificare n a primit doar Pregătiți mesajul. Există două cazuri.
- Dacă n este mai mare decât fiecare număr de propunere anterior primit, de la oricare dintre Propunători, de către Acceptant, atunci Acceptantul trebuie să returneze un mesaj, pe care îl numim „Promisiune”, către Propunător, pentru a ignora toate propunerile viitoare cu un număr mai mic decât n . Dacă acceptatorul a acceptat o propunere la un moment dat în trecut, aceasta trebuie să includă numărul propunerii anterioare, să zicem m , și valoarea acceptată corespunzătoare, să zicem w , în răspunsul său la propunător.
- În caz contrar (adică n este mai mic sau egal cu orice număr anterior de propunere primit de la orice Propunător de către Acceptant) Acceptatorul poate ignora propunerea primită. Nu trebuie să răspundă în acest caz pentru ca Paxos să funcționeze. Cu toate acestea, din motive de optimizare, trimiterea unui răspuns de respingere ( Nack ) i-ar spune Propunătorului că își poate opri încercarea de a crea consens cu propunerea n .
Faza 2
Faza 2a: Acceptați
- Dacă un propunător primește majoritatea promisiunilor de la un cvorum de acceptori, trebuie să stabilească o valoare v la propunerea sa. Dacă vreunul dintre Acceptanți a acceptat anterior vreo propunere, atunci își vor trimite valorile către Propunător, care acum trebuie să stabilească valoarea propunerii sale, v , la valoarea asociată cu cel mai mare număr de propunere raportat de Acceptori, să o numim z . Dacă niciunul dintre acceptori nu a acceptat o propunere până în acest moment, atunci Propunătorul poate alege valoarea pe care dorea să o propună inițial, să spunem x .
- Propunătorul trimite un mesaj de acceptare (n, v) către un cvorum de acceptori cu valoarea aleasă pentru propunerea sa, v și numărul propunerii n (care este același cu numărul conținut în mesajul Pregătire trimis anterior către Acceptori). Deci, mesajul Accept este (n, v = z) sau, în cazul în care niciunul dintre acceptori nu a acceptat anterior o valoare, (n, v = x) .
Acest mesaj de acceptare trebuie interpretat ca o „cerere”, ca în „Acceptați această propunere, vă rog!”.
Faza 2b: Acceptat
- În cazul în care un Acceptor primește un mesaj de Acceptare, (n, v) , de la un propunător, acesta trebuie să - l accepte , dacă și numai dacă aceasta a nu deja promis (in faza 1b a protocolului Paxos) să ia în considerare doar propunerile care au o mai mare identificator decât n .
- Dacă Acceptorul nu a promis deja (în Faza 1b) să ia în considerare doar propunerile care au un identificator mai mare de n , ar trebui să înregistreze valoarea v (a mesajului de acceptare tocmai primit ) ca valoare acceptată (a Protocolului) și să trimită un Mesaj acceptat către Propunător și fiecare cursant (care pot fi în mod tipic Propunătorii înșiși).
- Altfel, poate ignora mesajul sau cererea de acceptare.
Rețineți că un acceptor poate accepta mai multe propuneri. Acest lucru se poate întâmpla atunci când un alt Propunător, care nu știe despre noua valoare care se decide, începe o nouă rundă cu un număr de identificare mai mare n . În acest caz, acceptantul poate promite și accepta ulterior noua valoare propusă, chiar dacă a acceptat o alta mai devreme. Aceste propuneri pot avea chiar valori diferite în prezența anumitor eșecuri. Cu toate acestea, protocolul Paxos va garanta că Acceptorii vor conveni în cele din urmă asupra unei singure valori.
Când rundele eșuează
- Rundele eșuează atunci când mai mulți Propunători trimit mesaje de pregătire conflictuale sau când Propunătorul nu primește un Cvorum de răspunsuri ( Promisiune sau Acceptat ). În aceste cazuri, trebuie începută o altă rundă cu un număr mai mare de propuneri.
Paxos poate fi folosit pentru a selecta un lider
Observați că un Propunător din Paxos ar putea propune „Eu sunt liderul” (sau, de exemplu, „Propunătorul X este liderul”). Datorită acordului și garanțiilor de validitate ale Paxos, dacă sunt acceptate de un cvorum, atunci Propunătorul este acum cunoscut ca fiind liderul tuturor celorlalte noduri. Acest lucru satisface nevoile alegerii liderului, deoarece există un singur nod care crede că este liderul și un singur nod cunoscut a fi lider în orice moment.
Reprezentarea grafică a fluxului de mesaje în Paxos de bază
Următoarele diagrame reprezintă mai multe cazuri / situații de aplicare a protocolului Basic Paxos. Unele cazuri arată modul în care protocolul Basic Paxos face față eșecului anumitor componente (redundante) ale sistemului distribuit.
Rețineți că valorile returnate în mesajul Promisiunea sunt „nule” prima dată când se face o propunere (deoarece niciun acceptor nu a acceptat o valoare înainte în această rundă).
Paxos de bază fără eșecuri
În diagrama de mai jos, există 1 client, 1 propunător, 3 acceptori (adică dimensiunea cvorumului este 3) și 2 cursanți (reprezentați prin cele 2 linii verticale). Această diagramă reprezintă cazul unei prime runde, care are succes (adică niciun proces din rețea nu eșuează).
Client Proposer Acceptor Learner
| | | | | | |
X-------->| | | | | | Request
| X--------->|->|->| | | Prepare(1)
| |<---------X--X--X | | Promise(1,{Va,Vb,Vc})
| X--------->|->|->| | | Accept!(1,V)
| |<---------X--X--X------>|->| Accepted(1,V)
|<---------------------------------X--X Response
| | | | | | |
Aici, V este ultimul dintre (Va, Vb, Vc).
Cazuri de eroare în Paxos de bază
Cele mai simple cazuri de eroare sunt eșecul unui acceptor (când un cvorum de acceptori rămâne în viață) și eșecul unui cursant redundant. În aceste cazuri, protocolul nu necesită „recuperare” (adică încă reușește): nu sunt necesare runde sau mesaje suplimentare, așa cum se arată mai jos (în următoarele două diagrame / cazuri).
Paxos de bază atunci când un acceptor eșuează
În următoarea diagramă, unul dintre acceptorii din cvorum eșuează, astfel încât dimensiunea cvorumului devine 2. În acest caz, protocolul Basic Paxos încă reușește.
Client Proposer Acceptor Learner
| | | | | | |
X-------->| | | | | | Request
| X--------->|->|->| | | Prepare(1)
| | | | ! | | !! FAIL !!
| |<---------X--X | | Promise(1,{Va, Vb, null})
| X--------->|->| | | Accept!(1,V)
| |<---------X--X--------->|->| Accepted(1,V)
|<---------------------------------X--X Response
| | | | | |
Paxos de bază atunci când un cursant redundant eșuează
În următorul caz, unul dintre cursanții (redundanți) eșuează, dar protocolul Basic Paxos reușește în continuare.
Client Proposer Acceptor Learner
| | | | | | |
X-------->| | | | | | Request
| X--------->|->|->| | | Prepare(1)
| |<---------X--X--X | | Promise(1,{Va,Vb,Vc})
| X--------->|->|->| | | Accept!(1,V)
| |<---------X--X--X------>|->| Accepted(1,V)
| | | | | | ! !! FAIL !!
|<---------------------------------X Response
| | | | | |
Paxos de bază atunci când un propunător eșuează
În acest caz, un Propunător eșuează după ce a propus o valoare, dar înainte de a se ajunge la acord. Mai exact, nu reușește în mijlocul mesajului Accept, deci doar un Acceptor al Cvorumului primește valoarea. Între timp, este ales un nou lider (un propunător) (dar acest lucru nu este prezentat în detaliu). Rețineți că există 2 runde în acest caz (rundele se desfășoară vertical, de sus în jos).
Client Proposer Acceptor Learner
| | | | | | |
X----->| | | | | | Request
| X------------>|->|->| | | Prepare(1)
| |<------------X--X--X | | Promise(1,{Va, Vb, Vc})
| | | | | | |
| | | | | | | !! Leader fails during broadcast !!
| X------------>| | | | | Accept!(1,V)
| ! | | | | |
| | | | | | | !! NEW LEADER !!
| X--------->|->|->| | | Prepare(2)
| |<---------X--X--X | | Promise(2,{V, null, null})
| X--------->|->|->| | | Accept!(2,V)
| |<---------X--X--X------>|->| Accepted(2,V)
|<---------------------------------X--X Response
| | | | | | |
Paxos de bază atunci când mai mulți Propozitori intră în conflict
Cel mai complex caz este atunci când mai mulți Propunători se cred lideri. De exemplu, actualul lider poate eșua și mai târziu se poate recupera, dar ceilalți Propunători au reselectat deja un nou lider. Liderul recuperat nu a aflat încă acest lucru și încearcă să înceapă o rundă în conflict cu actualul lider. În diagrama de mai jos, sunt afișate 4 runde nereușite, dar ar putea fi mai multe (așa cum este sugerat în partea de jos a diagramei).
Client Proposer Acceptor Learner
| | | | | | |
X----->| | | | | | Request
| X------------>|->|->| | | Prepare(1)
| |<------------X--X--X | | Promise(1,{null,null,null})
| ! | | | | | !! LEADER FAILS
| | | | | | | !! NEW LEADER (knows last number was 1)
| X--------->|->|->| | | Prepare(2)
| |<---------X--X--X | | Promise(2,{null,null,null})
| | | | | | | | !! OLD LEADER recovers
| | | | | | | | !! OLD LEADER tries 2, denied
| X------------>|->|->| | | Prepare(2)
| |<------------X--X--X | | Nack(2)
| | | | | | | | !! OLD LEADER tries 3
| X------------>|->|->| | | Prepare(3)
| |<------------X--X--X | | Promise(3,{null,null,null})
| | | | | | | | !! NEW LEADER proposes, denied
| | X--------->|->|->| | | Accept!(2,Va)
| | |<---------X--X--X | | Nack(3)
| | | | | | | | !! NEW LEADER tries 4
| | X--------->|->|->| | | Prepare(4)
| | |<---------X--X--X | | Promise(4,{null,null,null})
| | | | | | | | !! OLD LEADER proposes, denied
| X------------>|->|->| | | Accept!(3,Vb)
| |<------------X--X--X | | Nack(4)
| | | | | | | | ... and so on ...
Multi-Paxos
O implementare tipică a Paxos necesită un flux continuu de valori convenite care acționează ca comenzi către o mașină de stare distribuită. Dacă fiecare comandă este rezultatul unei singure instanțe a protocolului Basic Paxos , ar rezulta o cantitate semnificativă de cheltuieli generale.
Dacă liderul este relativ stabil, faza 1 devine inutilă. Astfel, este posibil să omiteți faza 1 pentru instanțele viitoare ale protocolului cu același lider.
Pentru a realiza acest lucru, numărul rundei I este inclus împreună cu fiecare valoare care este incrementată în fiecare rundă de același lider. Multi-Paxos reduce întârzierea mesajului fără eșec (propunerea de învățare) de la 4 întârzieri la 2 întârzieri.
Reprezentarea grafică a fluxului de mesaje în Multi-Paxos
Multi-Paxos fără eșecuri
În următoarea diagramă, este afișată doar o singură instanță (sau „execuție”) a protocolului de bază Paxos, cu un Leader inițial (un Propunător). Rețineți că un Multi-Paxos constă din mai multe instanțe ale protocolului de bază Paxos.
Client Proposer Acceptor Learner
| | | | | | | --- First Request ---
X-------->| | | | | | Request
| X--------->|->|->| | | Prepare(N)
| |<---------X--X--X | | Promise(N,I,{Va,Vb,Vc})
| X--------->|->|->| | | Accept!(N,I,V)
| |<---------X--X--X------>|->| Accepted(N,I,V)
|<---------------------------------X--X Response
| | | | | | |
unde V = ultimul dintre (Va, Vb, Vc).
Multi-Paxos când faza 1 poate fi omisă
În acest caz, instanțele ulterioare ale protocolului de bază Paxos (reprezentat de I + 1 ) utilizează același lider, deci faza 1 (a acestor instanțe ulterioare ale protocolului de bază Paxos), care constă din subfazele Pregătiți și promiteți, este omis. Rețineți că liderul trebuie să fie stabil, adică nu trebuie să se blocheze sau să se schimbe.
Client Proposer Acceptor Learner | | | | | | | --- Following Requests --- X-------->| | | | | | Request | X--------->|->|->| | | Accept!(N,I+1,W) | |<---------X--X--X------>|->| Accepted(N,I+1,W) |<---------------------------------X--X Response | | | | | | |
Multi-Paxos când rolurile sunt prăbușite
O desfășurare comună a Multi-Paxos constă în prăbușirea rolului Propunătorilor, Acceptanților și Cursanților la „Servere”. Deci, în final, există doar „Clienți” și „Servere”.
Următoarea diagramă reprezintă prima „instanță” a unui protocol de bază Paxos, când rolurile Propunătorului, Acceptorului și Învățătorului sunt prăbușite într-un singur rol, numit „Server”.
Client Servers
| | | | --- First Request ---
X-------->| | | Request
| X->|->| Prepare(N)
| |<-X--X Promise(N, I, {Va, Vb})
| X->|->| Accept!(N, I, Vn)
| X<>X<>X Accepted(N, I)
|<--------X | | Response
| | | |
Multi-Paxos atunci când rolurile sunt prăbușite și liderul este stabil
În instanțele ulterioare ale protocolului Paxos de bază, cu același lider ca în instanțele anterioare ale protocolului Paxos de bază, faza 1 poate fi omisă.
Client Servers X-------->| | | Request | X->|->| Accept!(N,I+1,W) | X<>X<>X Accepted(N,I+1) |<--------X | | Response | | | |
Optimizări
Se pot efectua o serie de optimizări pentru a reduce numărul de mesaje schimbate, pentru a îmbunătăți performanța protocolului etc. Câteva dintre aceste optimizări sunt raportate mai jos.
- „Putem salva mesaje cu prețul unei întârzieri suplimentare a mesajului, având un singur cursant distins care îi informează pe ceilalți cursanți atunci când află că a fost aleasă o valoare. Acceptatorii trimit apoi mesaje acceptate numai cursantului distins. În majoritatea aplicațiilor, rolurile de lider și învățat distins sunt îndeplinite de același procesor.
- „Un lider își poate trimite mesajele Pregătiți și Acceptați! Doar către un cvorum de acceptori. Atâta timp cât toți acceptorii din acel cvorum funcționează și pot comunica cu liderul și cursanții, nu este nevoie ca acești acceptori care nu se află în cvorum să facă acest lucru. orice.
- „Acceptanților nu le pasă ce valoare este aleasă. Ei răspund pur și simplu la mesajele Pregătiți și acceptați! Pentru a se asigura că, în ciuda eșecurilor, se poate alege doar o singură valoare. Cu toate acestea, dacă un acceptor află ce valoare a fost aleasă, poate stoca valoarea stocării stabile și șterge orice alte informații pe care le-a salvat acolo. Dacă acceptantul primește ulterior un mesaj Pregătiți sau Acceptați!
- „ În loc de a trimite valoarea v, liderul poate trimite un hash de v la unele acceptori în sale Accept! Mesaje. Un cursant va învăța că v este ales dacă primește acceptate mesaje , fie pentru v sau codul hash dintr - un cvorum de acceptori, și cel puțin unul dintre aceste mesaje conține v mai degrabă decât hash-ul său. Cu toate acestea, un lider ar putea primi mesaje Promise care îi spun hash-ul unei valori v pe care trebuie să îl folosească în acțiunea sa de fază 2a fără a-i spune valoarea reală a lui v. se întâmplă, liderul nu își poate executa acțiunea Phase2a până când nu comunică cu un proces care știe v. "
- „Un propunător își poate trimite propunerea doar liderului, mai degrabă decât tuturor coordonatorilor. Cu toate acestea, acest lucru necesită ca rezultatul algoritmului de selecție a liderilor să fie difuzat către propunători, ceea ce ar putea fi costisitor. Deci, ar fi mai bine să lăsați Proponentul trimite propunerea tuturor coordonatorilor (în acest caz, numai coordonatorii înșiși trebuie să știe cine este liderul).
- „În loc ca fiecare acceptor să trimită mesaje acceptate către fiecare cursant, acceptatorii își pot trimite mesajele acceptate către lider, iar liderul poate informa cursanții când a fost aleasă o valoare. Cu toate acestea, acest lucru adaugă o întârziere suplimentară a mesajelor.
- "În cele din urmă, observați că faza 1 nu este necesară pentru runda 1. Liderul rundei 1 poate începe runda prin trimiterea unui mesaj Accept! Cu orice valoare propusă."
Paxos ieftin
Paxos ieftin extinde Paxos de bază pentru a tolera eșecurile F cu procesoarele principale F + 1 și procesoarele auxiliare F prin reconfigurarea dinamică după fiecare eșec.
Această reducere a cerințelor procesorului vine în detrimentul vietii; dacă prea multe procesoare principale eșuează într-un timp scurt, sistemul trebuie să se oprească până când procesoarele auxiliare pot reconfigura sistemul. În perioade stabile, procesoarele auxiliare nu iau parte la protocol.
„Cu doar două procesoare p și q, un procesor nu poate distinge eșecul celuilalt procesor de eșecul mediului de comunicație. Este necesar un al treilea procesor. Cu toate acestea, cel de-al treilea procesor nu trebuie să participe la alegerea secvenței de comenzi. acționați numai în cazul în care p sau q eșuează, după care nu face nimic în timp ce fie p, fie q continuă să funcționeze sistemul singur. Prin urmare, al treilea procesor poate fi unul mic / lent / ieftin sau un procesor dedicat în principal altor sarcini . "
Flux de mesaje: Multi-Paxos ieftin
Un exemplu care implică trei acceptori principali, un acceptor auxiliar și dimensiunea cvorumului de trei, care arată eșecul unui procesor principal și reconfigurarea ulterioară:
{ Acceptors }
Proposer Main Aux Learner
| | | | | | -- Phase 2 --
X----------->|->|->| | | Accept!(N,I,V)
| | | ! | | --- FAIL! ---
|<-----------X--X--------------->| Accepted(N,I,V)
| | | | | -- Failure detected (only 2 accepted) --
X----------->|->|------->| | Accept!(N,I,V) (re-transmit, include Aux)
|<-----------X--X--------X------>| Accepted(N,I,V)
| | | | | -- Reconfigure : Quorum = 2 --
X----------->|->| | | Accept!(N,I+1,W) (Aux not participating)
|<-----------X--X--------------->| Accepted(N,I+1,W)
| | | | |
Paxos rapid
Fast Paxos generalizează Paxos de bază pentru a reduce întârzierile de la un mesaj la altul. În Basic Paxos, întârzierea mesajului de la solicitarea clientului la învățare este de 3 întârzieri de mesaj. Fast Paxos permite 2 întârzieri de mesaje, dar necesită ca (1) sistemul să fie format din acceptori 3f + 1 pentru a tolera până la f erori (în loc de 2f + 1 clasic) și (2) Clientul să-și trimită cererea către destinații multiple .
Intuitiv, dacă liderul nu are nicio valoare de propus, atunci un client ar putea trimite un Accept! mesaj direct către acceptori. Acceptatorii ar răspunde ca în Paxos de bază, trimitând mesaje acceptate liderului și fiecărui cursant care realizează două întârzieri de mesaj de la client la cursant.
Dacă liderul detectează o coliziune, acesta rezolvă coliziunea trimițând Accept! mesaje pentru o nouă rundă care sunt acceptate ca de obicei. Această tehnică de recuperare coordonată necesită patru întârzieri de mesaj de la client la cursant.
Optimizarea finală are loc atunci când liderul specifică o tehnică de recuperare în avans, permițând acceptorilor să efectueze singuri recuperarea coliziunii. Astfel, recuperarea necoordonată a coliziunilor poate apărea în trei întârzieri ale mesajelor (și doar două întârzieri ale mesajelor dacă toți cursanții sunt și acceptori).
Flux de mesaje: Paxos rapid, fără conflict
Client Leader Acceptor Learner | | | | | | | | | X--------->|->|->|->| | | Any(N,I,Recovery) | | | | | | | | X------------------->|->|->|->| | | Accept!(N,I,W) | |<---------X--X--X--X------>|->| Accepted(N,I,W) |<------------------------------------X--X Response(W) | | | | | | | |
Flux de mesaje: Paxos rapid, propuneri contradictorii
Propuneri conflictuale cu recuperare coordonată. Notă: protocolul nu specifică modul de gestionare a solicitării clientului abandonat.
Client Leader Acceptor Learner | | | | | | | | | | | | | | | | | | | | | | | | | | | !! Concurrent conflicting proposals | | | | | | | | | !! received in different order | | | | | | | | | !! by the Acceptors | X--------------?|-?|-?|-?| | | Accept!(N,I,V) X-----------------?|-?|-?|-?| | | Accept!(N,I,W) | | | | | | | | | | | | | | | | | | !! Acceptors disagree on value | | |<-------X--X->|->|----->|->| Accepted(N,I,V) | | |<-------|<-|<-X--X----->|->| Accepted(N,I,W) | | | | | | | | | | | | | | | | | | !! Detect collision & recover | | X------->|->|->|->| | | Accept!(N+1,I,W) | | |<-------X--X--X--X----->|->| Accepted(N+1,I,W) |<---------------------------------X--X Response(W) | | | | | | | | |
Propuneri conflictuale cu recuperare necoordonată.
Client Leader Acceptor Learner | | | | | | | | | | | X------->|->|->|->| | | Any(N,I,Recovery) | | | | | | | | | | | | | | | | | | !! Concurrent conflicting proposals | | | | | | | | | !! received in different order | | | | | | | | | !! by the Acceptors | X--------------?|-?|-?|-?| | | Accept!(N,I,V) X-----------------?|-?|-?|-?| | | Accept!(N,I,W) | | | | | | | | | | | | | | | | | | !! Acceptors disagree on value | | |<-------X--X->|->|----->|->| Accepted(N,I,V) | | |<-------|<-|<-X--X----->|->| Accepted(N,I,W) | | | | | | | | | | | | | | | | | | !! Detect collision & recover | | |<-------X--X--X--X----->|->| Accepted(N+1,I,W) |<---------------------------------X--X Response(W) | | | | | | | | |
Flux de mesaje: Paxos rapid cu recuperare necoordonată, roluri restrânse
(roluri fuzionate de acceptor / cursant)
Client Servers | | | | | | | | X->|->|->| Any(N,I,Recovery) | | | | | | | | | | | | !! Concurrent conflicting proposals | | | | | | !! received in different order | | | | | | !! by the Servers | X--------?|-?|-?|-?| Accept!(N,I,V) X-----------?|-?|-?|-?| Accept!(N,I,W) | | | | | | | | | | | | !! Servers disagree on value | | X<>X->|->| Accepted(N,I,V) | | |<-|<-X<>X Accepted(N,I,W) | | | | | | | | | | | | !! Detect collision & recover | | X<>X<>X<>X Accepted(N+1,I,W) |<-----------X--X--X--X Response(W) | | | | | |
Paxos generalizat
Consensul generalizat explorează relația dintre operațiunile mașinii de stare replicate și protocolul de consens care o implementează. Descoperirea principală implică optimizări ale Paxos atunci când propunerile conflictuale ar putea fi aplicate în orice ordine. adică, atunci când operațiile propuse sunt operații comutative pentru mașina de stat. În astfel de cazuri, operațiunile conflictuale pot fi acceptate atât, evitând întârzierile necesare pentru rezolvarea conflictelor și propunând din nou operațiunile respinse.
Acest concept este generalizat în continuare în secvențe în continuă creștere de operații comutative, dintre care unele sunt cunoscute ca fiind stabile (și astfel pot fi executate). Protocolul urmărește aceste secvențe, asigurându-se că toate operațiunile propuse ale unei secvențe sunt stabilizate înainte de a permite oricărei operațiuni care nu fac naveta cu ele să devină stabile.
Exemplu
Pentru a ilustra Paxos generalizat, exemplul de mai jos arată un flux de mesaje între doi clienți care execută concomitent și o mașină de stare replicată care implementează operații de citire / scriere pe două registre distincte A și B.
| Citeste o) | Scrie o) | Citiți (B) | Scrie (B) | |
|---|---|---|---|---|
| Citeste o) | ||||
| Scrie o) | ||||
| Citiți (B) |
|
|||
| Scrie (B) |
|
Rețineți că
în acest tabel se indică operațiuni care nu sunt comutative.
O posibilă succesiune de operații:
<1:Read(A), 2:Read(B), 3:Write(B), 4:Read(B), 5:Read(A), 6:Write(A)>
Deoarece face 5:Read(A)naveta cu ambele 3:Write(B)și 4:Read(B), o posibilă permutare echivalentă cu ordinea anterioară este următoarea:
<1:Read(A), 2:Read(B), 5:Read(A), 3:Write(B), 4:Read(B), 6:Write(A)>
În practică, o navetă are loc numai atunci când operațiile sunt propuse simultan.
Flux de mesaje: Paxos generalizat (exemplu)
Răspunsurile nu sunt afișate. Notă: abrevierile mesajelor diferă de fluxurile de mesaje anterioare din cauza specificității protocolului, consultați pentru o discuție completă.
Client Leader Acceptor Learner | | | | | | | | !! New Leader Begins Round | | X----->|->|->| | | Prepare(N) | | |<-----X- X- X | | Promise(N,null) | | X----->|->|->| | | Phase2Start(N,null) | | | | | | | | | | | | | | | | !! Concurrent commuting proposals | X------- ?|-----?|-?|-?| | | Propose(ReadA) X-----------?|-----?|-?|-?| | | Propose(ReadB) | | X------X-------------->|->| Accepted(N,<ReadA,ReadB>) | | |<--------X--X-------->|->| Accepted(N,<ReadB,ReadA>) | | | | | | | | | | | | | | | | !! No Conflict, both accepted | | | | | | | | Stable = <ReadA, ReadB> | | | | | | | | | | | | | | | | !! Concurrent conflicting proposals X-----------?|-----?|-?|-?| | | Propose(<WriteB,ReadA>) | X--------?|-----?|-?|-?| | | Propose(ReadB) | | | | | | | | | | X------X-------------->|->| Accepted(N,<WriteB,ReadA> . <ReadB>) | | |<--------X--X-------->|->| Accepted(N,<ReadB> . <WriteB,ReadA>) | | | | | | | | | | | | | | | | !! Conflict detected, leader chooses | | | | | | | | commutative order: | | | | | | | | V = <ReadA, WriteB, ReadB> | | | | | | | | | | X----->|->|->| | | Phase2Start(N+1,V) | | |<-----X- X- X-------->|->| Accepted(N+1,V) | | | | | | | | Stable = <ReadA, ReadB> . | | | | | | | | <ReadA, WriteB, ReadB> | | | | | | | | | | | | | | | | !! More conflicting proposals X-----------?|-----?|-?|-?| | | Propose(WriteA) | X--------?|-----?|-?|-?| | | Propose(ReadA) | | | | | | | | | | X------X-------------->|->| Accepted(N+1,<WriteA> . <ReadA>) | | |<--------X- X-------->|->| Accepted(N+1,<ReadA> . <WriteA>) | | | | | | | | | | | | | | | | !! Leader chooses order: | | | | | | | | W = <WriteA, ReadA> | | | | | | | | | | X----->|->|->| | | Phase2Start(N+2,W) | | |<-----X- X- X-------->|->| Accepted(N+2,W) | | | | | | | | Stable = <ReadA, ReadB> . | | | | | | | | <ReadA, WriteB, ReadB> . | | | | | | | | <WriteA, ReadA> | | | | | | | |
Performanţă
Fluxul de mesaje de mai sus ne arată că Paxos generalizat poate utiliza semantica operațională pentru a evita coliziunile atunci când ordonarea spontană a rețelei eșuează. Acest lucru permite protocolului să fie în practică mai rapid decât Fast Paxos. Cu toate acestea, atunci când are loc o coliziune, Paxos generalizat are nevoie de două călătorii suplimentare pentru a-și reveni. Această situație este ilustrată cu operațiile WriteB și ReadB în schema de mai sus.
În cazul general, astfel de călătorii dus-întors sunt inevitabile și provin din faptul că mai multe comenzi pot fi acceptate în timpul unei runde. Acest lucru face ca protocolul să fie mai scump decât Paxos atunci când conflictele sunt frecvente. Sperăm că două posibile îmbunătățiri ale Paxos generalizate sunt posibile pentru a îmbunătăți timpul de recuperare.
- În primul rând, dacă coordonatorul face parte din fiecare cvorum de acceptori (runda N se spune centrată ), atunci pentru a recupera la runda N + 1 dintr-o coliziune la runda N, coordonatorul omite faza 1 și propune la faza 2 secvența pe care a acceptat-o ultima în timpul rundei N. Aceasta reduce costul recuperării la o singură călătorie dus-întors.
- În al doilea rând, dacă ambele runde N și N + 1 folosesc un cvorum unic și identic centrat, atunci când un acceptor detectează o coliziune la runda N, propune spontan la runda N + 1 o secvență care sufixă ambele (i) secvența acceptată la runda N de coordonatorul și (ii) cel mai mare prefix neconflictant pe care l-a acceptat în runda N. De exemplu, dacă coordonatorul și acceptatorul au acceptat respectiv în runda N <WriteB, ReadB> și <ReadB, ReadA>, acceptatorul va accepta spontan < WriteB, ReadB, ReadA> la runda N + 1. Cu această variantă, costul recuperării este o întârziere a mesajului unic, care este evident optimă. Observați aici că utilizarea unui cvorum unic la o rundă nu dăunează vietii. Acest lucru provine din faptul că orice proces din acest cvorum este un cvorum citit pentru faza de pregătire a următoarelor runde.
Paxos bizantin
Paxos poate fi, de asemenea, extins pentru a sprijini eșecurile arbitrare ale participanților, inclusiv minciuna, fabricarea mesajelor, coluziunea cu alți participanți, neparticiparea selectivă etc. Aceste tipuri de eșecuri se numesc eșecuri bizantine , după soluția popularizată de Lamport.
Paxos bizantin introdus de Castro și Liskov adaugă un mesaj suplimentar (Verify) care acționează pentru a distribui cunoștințele și a verifica acțiunile celorlalți procesoare:
Flux de mesaje: Multi-Paxos bizantin, starea de echilibru
Client Proposer Acceptor Learner | | | | | | | X-------->| | | | | | Request | X--------->|->|->| | | Accept!(N,I,V) | | X<>X<>X | | Verify(N,I,V) - BROADCAST | |<---------X--X--X------>|->| Accepted(N,V) |<---------------------------------X--X Response(V) | | | | | | |
Paxos bizantin rapid introdus de Martin și Alvisi elimină această întârziere suplimentară, deoarece clientul trimite comenzi direct către acceptori.
Rețineți că mesajul acceptat în Fast Byzantine Paxos este trimis tuturor acceptanților și tuturor cursanților, în timp ce Fast Paxos trimite mesaje acceptate numai cursanților):
Flux de mesaje: Multi-Paxos bizantin rapid, starea de echilibru
Client Acceptor Learner | | | | | | X----->|->|->| | | Accept!(N,I,V) | X<>X<>X------>|->| Accepted(N,I,V) - BROADCAST |<-------------------X--X Response(V) | | | | | |
Scenariul de eșec este același pentru ambele protocoale; Fiecare cursant așteaptă să primească F + 1 mesaje identice de la diferiți acceptori. Dacă acest lucru nu se întâmplă, Acceptorii înșiși vor fi, de asemenea, conștienți de acest lucru (deoarece și-au schimbat reciproc mesajele în runda de difuzare), iar Acceptorii corecți vor retransmite valoarea convenită:
Flux de mesaje: Multi-Paxos bizantin rapid, eșec
Client Acceptor Learner
| | | ! | | !! One Acceptor is faulty
X----->|->|->! | | Accept!(N,I,V)
| X<>X<>X------>|->| Accepted(N,I,{V,W}) - BROADCAST
| | | ! | | !! Learners receive 2 different commands
| | | ! | | !! Correct Acceptors notice error and choose
| X<>X<>X------>|->| Accepted(N,I,V) - BROADCAST
|<-------------------X--X Response(V)
| | | ! | |
Adaptarea Paxos pentru rețelele RDMA
Odată cu apariția unor rețele de centre de date fiabile de mare viteză, care acceptă DMA la distanță ( RDMA ), a existat un interes substanțial în optimizarea Paxos pentru a beneficia de descărcarea hardware, în care placa de interfață de rețea și routerele de rețea oferă fiabilitate și control al congestiei stratului de rețea, eliberând CPU gazdă pentru alte sarcini. Biblioteca Derecho C ++ Paxos este o implementare open-source Paxos care explorează această opțiune.
Derecho oferă atât un Paxos clasic, cu durabilitatea datelor pe secvențe complete de oprire / repornire, cât și Paxos vertical (atomic multicast), pentru replicarea în memorie și sincronizarea stării-mașină. Protocoalele Paxos utilizate de Derecho trebuiau adaptate pentru a maximiza fluxul de date asincron și pentru a elimina alte surse de întârziere pe calea critică a liderului. Astfel, Derecho poate susține rata de date RDMA bidirecțională completă. În schimb, deși protocoalele tradiționale Paxos pot fi migrate către o rețea RDMA prin simpla mapare a operațiunilor de trimitere a mesajelor către operațiuni RDMA native, acest lucru lasă întârzieri dus-întors pe calea critică. În rețelele RDMA de mare viteză, chiar și întârzierile mici pot fi suficient de mari pentru a preveni utilizarea întregii lățimi de bandă potențiale.
Utilizarea producției Paxos
- Google folosește algoritmul Paxos în serviciul lor de blocare distribuită Chubby pentru a menține replicile coerente în caz de eșec. Chubby este folosit de Bigtable, care este acum în producție în Google Analytics și alte produse.
- Google Spanner și Megastore utilizează algoritmul Paxos intern.
- Serviciul de replicare OpenReplica utilizează Paxos pentru a menține replici pentru un sistem de acces deschis care permite utilizatorilor să creeze obiecte tolerante la erori. Oferă performanțe ridicate prin runde concurente și flexibilitate prin schimbări dinamice de membru.
- IBM se presupune că folosește algoritmul Paxos în produsul său IBM SAN Volume Controller pentru a implementa o mașină virtuală de uz general tolerant la defecțiuni utilizată pentru a rula componentele de configurare și control ale serviciilor de virtualizare a stocării oferite de cluster. ( Lucrare de cercetare originală MIT și IBM )
- Microsoft folosește Paxos în serviciul de gestionare a clusterului Autopilot de la Bing și în Windows Server Failover Clustering.
- WANdisco a implementat Paxos în cadrul tehnologiei DConE de replicare activă-activă.
- XtreemFS folosește un algoritm de negociere a închirierii bazat pe Paxos pentru o replicare tolerantă la erori și consecventă a datelor și metadatelor fișierelor.
- Heroku folosește Doozerd, care implementează Paxos pentru depozitul său constant de date distribuite.
- Ceph folosește Paxos ca parte a proceselor de monitorizare pentru a conveni care sunt OSD-urile și în cluster.
- Baza de date SQL distribuită Clustrix folosește Paxos pentru rezoluția tranzacției distribuite .
- Baza de date cu grafice Neo4j HA implementează Paxos, înlocuind Apache ZooKeeper de la v1.9
- Baza de date Apache Cassandra NoSQL utilizează numai funcția Paxos pentru tranzacții ușoare
- Amazon Elastic Container Services folosește Paxos pentru a menține o viziune consecventă a stării clusterului
Vezi si
Referințe
linkuri externe
- Pagina principală a lui Leslie Lamport
- Paxos Made Simple
- Paxos făcut moderat complex
- Revizuirea algoritmului Paxos
- Angajamentul Paxos
- Hârtie albă Google: Chubby Distributed Lock Service
- Carte albă Google: Bigtable Un sistem de stocare distribuit pentru date structurate
- Studiul algoritmilor Paxos (2007)
- OpenReplica Open Replication Service
- FTFile: Biblioteca de fișiere tolerante la erori
- Biblioteca Isis2 (primitivul SafeSend este o implementare gratuită open source a Paxos)
- Mencius - Paxos rotativ circular pentru sisteme geo-distribuite
- WANdisco - Soluții de replicare activă-activă pentru Hadoop, Subversion și GIT
- libpaxos, o colecție de implementări open source ale algoritmului Paxos
- libpaxos-cpp, o implementare C ++ a algoritmului consens distribuit paxos
- JBP - Paxos bizantin Java
- erlpaxos, Paxos de Erlang
- paxos - Implementare directă paxos în Python și Java
- Manhattan Paxos (mpaxos), Paxos în C, acceptând mai multe grupuri de paxos și tranzacții eficiente între ele.
- Clustering cu Neo4j
- HT-Paxos
- PaxosStore, implementarea paxos în WeChat
- LWT în Cassandra
- Google TechTalks: Algoritmul Paxos