Strona głównaArtykułyDwa fazowe zatwierdzenie: Jak bazy danych rozproszone osiągnąją zgody na zatwierdzenie lub anulowanie wspólnie

Dwa fazowe zatwierdzenie: Jak bazy danych rozproszone osiągnąją zgody na zatwierdzenie lub anulowanie wspólnie

Pomyśl o przelew bankowy, który dotyka dwóch oddzielnych baz danych: jedna odlicza z twojego konta checking, a druga dodaje do twojego konta oszczędności. Co się stanie, jeśli pierwsze aktualizacja powiedzie się, ale druga nie powiedzie się po pół drogi ze względu na awarię sieci? Dwa fazowe zatwierdzenie (2PC) jest klasycznym protokołem używanym przez systemy rozproszone do odpowiedzi na to pytanie, wymuszając, aby każdy uczestniczący węzeł zgadzał się w jednym tempie: albo wszyscy zatwierdzają, albo wszyscy anulują, bez pozwolenia na stan przejściowy. Funkcjonuje poprzez podział decyzji na fazę głosowania i fazę decyzyjną, koordynowaną przez pojedyncze wężeł, które zbiera głosy przed wydanie końcowego rozstrzygnięcia. Protokół jest elegancki i szeroko używany, ale nosi znane słabe miejsce: jeśli koordynator zniknie dokładnie w nadmiarowo nieodpowiednim momencie, uczestnicy mogą być zamarznięci, nie będą mogąc dalej postępować samodzielnie. Zrozumienie 2PC jest pierwszym krokiem w kierunku zrozumienia dlaczego współczesne systemy coraz częściej szukają algorytmów zgody jak Paxos i Raft.

mysimulator teamZaktualizowano — czerwiec 2026≈ 8 min czytania▶ Otwórz symulację

Problem atomiczności rozproszonej

Transakcja w bazie danych pojedynczego punktu końcowego jest prosta w zakresie atomiczności: silnik przechowywania albo zapisuje wszystkie zmiany na dysku, albo żadnej. W przypadku awarii podczas zapisu, zmiany są automatycznie cofnięte przy ponownym uruchomieniu. Transakcje rozproszone są trudniejsze, ponieważ praca jest rozłożona po wielu niezależnych maszynach, każda z własnym dyskiem lokalnym, własnym zegarem i własną szansą na awarię lub utratę połączenia sieciowego w każdym momencie. Jeśli transakcja aktualizuje dane na trzech oddzielnych węzłach bazy danych, potrzebne są one wszystkie do sukcesu razem lub wszystkie do niepowodzenia atomiczność między maszynami, nawet jeśli żadna z maszyn nie może zobaczyć, co robi inna w czasie rzeczywistym. Bez koordynacji, częściowe awarie (węzeł A komituje się, a węzeł B awariuje przed tym, aby mógł to zrobić) pozostawiają system w stanie niespójnym: pieniądze odjęte z jednego konta, ale nigdy nie wpisane na drugie, zamówienie oznaczone jako wysłane przez jedną usługę, ale nigdy nie wpisane jako zapłacone przez usługę rozliczeniową. Jest to jądro wyzwania, które problem dwoistego zatwierdzenia (2PC) został zaprojektowany, aby rozwiązać: konwersja zestawu niezależnych, niewielkich decyzji lokalnych w jedną wiarygodną, udostępnioną, wszystko lub nic decyzję. Protokół wprowadza dwa role, które pozwalają na to: koordynator, który steruje procesem, oraz jedno lub więcej uczestników, którzy przechowują rzeczywiste dane i wykonują rzeczywistą pracę transakcyjną.

Faza 1: Przygotowanie i Głosowanie

Pierwsza faza 2PC to runda głosowania. Koordynator wysyła żądanie prepare do każdego uczestnika, podstawowo pytając: czy możesz gwarantować sukces transakcji, jeśli powiem ci, że ma być zatwierdzona później? Każdy uczestnik potem wykonuje rzeczywistą pracę transakcji lokalnie, stosując zmiany w sposób, który nadal mógłby być cofnięty, a krytycznie, zapisuje wynik do trwałości na dysku przed odpowiedzią. Ta etapowa trwałość ma niezwykle duże znaczenie: gdy uczestnik zapisze prepare jako takie w swoim dzienniku, robi on skomunikowane obietnice, że może zatwierdzić transakcję nawet jeśli się zatrzyma i ponownie uruchomi w międzyczasie, ponieważ odtworzy log i przypomni sobie swoją obietnicę. Każdy uczestnik następnie odpowiada głosem: tak/gotowy oznaczając, że wykonał pracę, zakłócił niezbędne zasoby i jest gotowy do zatwierdzenia, lub nie/anulować, jeśli coś poszło nie tak, np. naruszenie ograniczeń, konflikt blokowania lub lokalny błąd, co uniemożliwi kontynuację transakcji. Koordynator zbiera wszystkie głosy przed dalszym postępem. Ta faza przekształca niepewne przyszłe działanie w pewną, zapisaną obietnicę, co sprawia, że druga faza jest zaufana.

Faza 2: Ostateczne Zatwierdzenie lub Anulowanie

Po tym, jak koordynator odebrał odpowiedzi od wszystkich uczestników, podaje ostateczny wyrok korzystając z prostej reguły jednogłośnej. Jeśli wszystkie uczestnicy głosowały za, koordynator zapisuje swoją decyzję w trwałem dzienniku i wysyła komendę zatwierdzenia do każdego uczestnika, którzy kończą transakcję, cofają swoje bloki i czynią zmiany trwało widoczne. Jeśli choć jedna osoba głosowała przeciwko, koordynator wysyła komendę anulowania do wszystkich uczestników, a każdy cofa lokalne zmiany, które tentatywnie zastosował podczas fazy 1, jakoby transakcja nigdy się nie stała. Ta reguła jednogłośnej głosowania jest to, co dostarcza atrybutu atomiczności: nie ma ścieżki w protokołu, w której niektóre uczestnicy zatwierdzają, podczas gdy inni anulują, ponieważ decyzja koordynatora jest rozgłoszona do wszystkich i każdy uczestnik jest zobowiązany do jej przestrzegania. Uczestnicy potwierdzają ostateczną komendę, a dopiero wtedy koordynator uznaje transakcję za całkowicie zakończoną. Ze стороны zewnętrznego, cała rozproszone transakcja zachowuje się jak jedna operacja atomowa, nawet jeśli dotknęła wielu niezależnych maszyn, które nigdy nie koordynowały się bezpośrednio ze sobą.

Problem blokady: Krytyczne słabe miejsce

Dwa-fazowy zatwierdzenie gwarantuje wiarygodnie atomowość, ale ma znane strukturalne słabości nazywane problemem blokady. Rozważmy taki scenariusz: trzy uczestniki głosują za podczas pierwszej fazie, pisanie tej obietnicy stabilnie do swoich dzienników i zablokowanie swoich zasobów. Koordynator otrzymuje wszystkie trzy głosy za, a jest gotowy wysłać wiadomość zatwierdzającą, ale przed tym, niż mógłby wysłać coś, krzyczy, być może ze względu na awarię sprzętu lub podział sieci. Teraz każdy uczestnik jest w niejednoznacznym stanie. Każdy obiecał, że może zatwierdzić, więc nie może uniwersalnie anulować, ponieważ koordynator mógł już zdecydować się na zatwierdzenie i powiedzieć innemu uczestnikowi. Ale również nie może uniwersalnie zatwierdzić, ponieważ koordynator może być ostatecznie gotowy wysłać anulowanie. Jedyna bezpieczna opcja to utrzymywanie swoich zasobów zablokowanych, blokując każdą inną transakcję potrzebującą tych samych zasobów, i czekanie na recykloację koordynatora i jego rozstrzygnięcie. Jeśli koordynator pozostaje w stanie awarii przez długie czas, te zasoby pozostają blokowane całą całością, potencjalnie zamrożone dużymi części systemu. To jedno punkt fałszywe, gdzie los wielu uczestników całkowicie zależy od recykloacji jednego koordynatora, jest głównym krytykiem wskazanym na dwa-fazowe zatwierdzenie.

Motywacja trójfazowego zatwierdzenia i protokołów zgody

Problem blokujący bezpośrednio motywował poszukiwanie bardziej odpornościowych alternatyw. Trójfazowe zatwierdzenie (3PC) było wcześniejszym próbą rozwiązania go poprzez wprowadzenie dodatkowej fazy przed-zatwierdzania, która dawała uczestnikom wystarczającą wspólną wiedzę, aby mogli bezpiecznie postępować nawet jeśli koordynator zniknie. Mimo to 3PC nadal ma problemy podczas rozdziałów sieciowych i nigdy nie uzyskał tak szerokiej adoptacji jak dwufazowe zatwierdzenie (2PC). Bardziej wpływowy ścieżka dalsza okazała się być algorytmy zgody, takie jak Paxos i Raft. Zamiast polegać na jednym koordynatorze, którego awaria może zatrzymać całą system, te protokoły replikują decyzję samej siebie pośród klastra węzłów i wymagają tylko większościu kwalifikacji do zgody, a nie zgody unanowej z każdego pojedynczego węzła. Jeśli awariuję nawet lider, pozostałe w większości mogą nadal wybierać nowego lidera i kontynuować postęp, ponieważ awaria żadnego pojedynczego urządzenia nie może blokować grupy na stałe. Ten przesuniecie od jednego niewytrzymującego koordynatora podpisującego decyzję do odpornonej kwalifikacji osiągającej zgody razem, stanowi podstawę, jak współczesne bazy danych rozproszone, usługi koordynacyjne, takie jak ZooKeeper i etcd, oraz systemy zgody rozproszonych osiągają zarówno atomiczność, jak i wysoką dostępność, bezpośrednio adresując słabość, której dwufazowe zatwierdzenie nigdy nie mogło całkowicie uniknąć.

Często zadawane pytania

Czym jest główna cel dwoistego potwierdzenia?

Głównym celem jest atomowość między wieloma niezależnymi węzłami w transakcji rozproszonej: zapewnienie, że każdy uczestnik albo potwierdzi transakcję razem z każdym innym uczestnikiem, albo abortuje ją razem, bez możliwości, że niektóre węzły potwierdzą, a inne nie.

Jakie jest różnice między koordynatorem a uczestnikiem?

Koordynator to pojedynczy węzeł, który steruje protokolem, wysyłając żądania przygotowania, zbierając głosy i rozpowszechnia końcowe decyzje o potwierdzeniu lub anulowaniu. Uczestnicy są węzłami, które rzeczywistym sposobem przechowują dane, wykonują pracę związane z transakcją lokalnie, głosują na to, czy mogą potwierdzić, a następnie podążają za końcową instrukcji koordynatora.

Dlaczego uczestnicy muszą zapisać swoje głosy do trwało przechowywalnego dziennika przed odpowiedzią?

Zapisanie głosu trwało oznacza, że jeśli uczestnik zatrzyma się po głosowaniu za potwierdzenie i ponownie uruchomi się, może odzyskać swoją obietnicę z dziennika i nadal ją przestrzegać, a nie zapomina o tym, że obiecał gotowość. Ta trwałość jest to, co sprawia, że głos za potwierdzenie staje się wiarygodną i poważną obietnicą.

Co dokładnie jest problemem blokującym w dwoistym potwierdzeniu?

Problem blokujący występuje, gdy koordynator zatrzymuje się po tym, jak uczestnicy głosują za potwierdzenie, ale przed wysłaniem końcowego decyzji o potwierdzeniu lub anulowaniu. Te uczestniki nie mogą bezpiecznie kontynuować w żadnym kierunku, więc muszą utrzymywać swoje zaszytki i czekać, potencjalnie na długi czas, aż koordynator odzyska się.

Jak Paxos i Raft unikają problemu blokującego, który występuje w dwoistym potwierdzeniu?

Paxos i Raft kopiują decyzje pośród klastra i wymagają tylko większościowej kworum do zgody zamiast jednogłośnego udziału koordynowanego przez pojedynczy niewytrzymujący węzeł. Jeśli węzeł lidera zatrzyma się, pozostająca większość może wyborzyć zastępcę i nadal rozwijać się, więc nie można zatrzymać całego systemu podczas zatrzymania koordynatora, jak to jest możliwe w klasycznym dwoistym potwierdzeniu.

Wypróbuj na żywo

Wszystko powyżej działa bezpośrednio w Twojej przeglądarce — otwórz Two-Phase Commit: How Distributed Databases Agree to Commit or Abort Together i zmieniaj parametry podczas działania. Nic nie jest instalowane ani przesyłane na serwer, cały model działa w jednej karcie.

▶ Otwórz symulację Two-Phase Commit: How Distributed Databases Agree to Commit or Abort Together

Co znalazłeś?

Dodaj kroki odtworzenia (opcjonalnie)