Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

Po awarii primary aplikacja nie widzi nowego mastera - VIP i HAProxy

W skrócie

  • Po awarii serwera głównego klaster wybrał nowy węzeł, ale aplikacja dalej próbuje łączyć się do starego adresu i nie działa.
  • Aplikacja ma na sztywno wpisany adres primary, więc failover na poziomie bazy nie przekierowuje jej automatycznie na nowy węzeł.
  • Potrzebna jest warstwa kierująca ruch, czyli pływający adres VIP albo proxy w rodzaju HAProxy, które zawsze wskazuje na aktualnego mastera.

Automatyczny failover to dopiero połowa sukcesu. Baza może poprawnie wypromować nowy węzeł, a mimo to aplikacja pozostanie odcięta, bo wciąż puka do maszyny, która padła. Wyjaśnimy, dlaczego tak się dzieje i jak zbudować warstwę dostępową, dzięki której klient zawsze trafi na aktualny serwer główny.

Jak to wygląda w praktyce

Serwer główny pada, a klaster HA (na przykład zarządzany przez Patroni) w kilkanaście sekund promuje jeden z serwerów zapasowych na nowy primary. Z punktu widzenia bazy wszystko zadziałało: nowy węzeł przyjmuje zapisy. Tymczasem aplikacja rzuca błędami połączenia, bo w jej konfiguracji figuruje adres IP starej maszyny. Ktoś musi ręcznie zmienić connection string i zrestartować aplikację, przez co realny przestój trwa nie kilkanaście sekund, lecz tyle, ile zajmie interwencja człowieka. Cel wysokiej dostępności zostaje zaprzepaszczony.

Dlaczego tak się dzieje

Failover odbywa się wewnątrz klastra bazy. Mechanizm HA wie, który węzeł jest teraz główny, ale nie ma żadnej mocy nad tym, dokąd łączy się aplikacja. Klient używa adresu, który mu podano, i jeśli jest to konkretny adres jednego serwera, po jego awarii po prostu nie ma z kim rozmawiać. Brakuje pośrednika, który wiedziałby o zmianie roli i kierował ruch we właściwe miejsce.

Rozwiązuje to warstwa dostępowa. Pierwsze podejście to pływający adres VIP: jeden wirtualny adres IP, który w danej chwili jest przypisany do węzła pełniącego rolę głównego i przy failoverze wędruje na nowy węzeł. Drugie podejście to proxy, najczęściej HAProxy, do którego łączy się aplikacja i które rozdziela połączenia na aktualnego mastera. HAProxy rozpoznaje, który węzeł jest główny, odpytując go zdrowotnym sprawdzeniem - w klastrach Patroni służy do tego wbudowany REST API, którego endpoint zwraca inny kod HTTP dla lidera i dla repliki.

Jak to rozwiązać krok po kroku

  1. Ustal jeden stabilny punkt wejścia dla aplikacji i wpisz go do connection stringa raz na zawsze. Może to być adres VIP albo adres HAProxy - aplikacja nigdy nie powinna znać adresów pojedynczych węzłów.
  2. Jeśli wybierasz HAProxy, skonfiguruj dwa frontendy: jeden na zapisy kierowany do lidera i opcjonalnie drugi na odczyty rozkładany na repliki. Rozdzielenie ruchu odczytowego i zapisowego pozwala odciążyć głównego.
  3. W sekcji backend zapisowego ustaw sprawdzenie zdrowia oparte na endpoincie lidera klastra, na przykład zapytanie HTTP do REST API Patroni na ścieżkę /primary. Węzeł, który nie jest liderem, zwróci kod inny niż 200 i HAProxy go pominie.
  4. Dobierz krótkie interwały sprawdzeń zdrowia, żeby proxy szybko zauważyło zmianę lidera. Zbyt długie odstępy wydłużają czas, przez który ruch trafia w próżnię po failoverze.
  5. Alternatywnie zbuduj rozwiązanie na VIP i menedżerze, który przy zmianie roli przenosi adres na nowego lidera. To mniej ruchomych części, ale wymaga, żeby wszystkie węzły były w jednej podsieci warstwy drugiej.
  6. Przetestuj przełączenie ręcznie, wywołując kontrolowany failover, zanim zaufasz mechanizmowi w produkcji. Obserwuj, po ilu sekundach aplikacja odzyskuje połączenie bez ingerencji człowieka.

Jak sprawdzić, że zadziałało

Wykonaj kontrolowany failover i mierz, ile trwa przerwa widziana przez aplikację - przy dobrze ustawionym HAProxy powinno to być kilka sekund, bez żadnej ręcznej zmiany konfiguracji. Do którego węzła faktycznie trafiasz, sprawdzisz, łącząc się przez punkt wejścia i wykonując SELECT pg_is_in_recovery(); - odpowiedź f potwierdza, że proxy albo VIP wskazuje na serwer główny, a nie na replikę. W statystykach HAProxy (strona stanu albo gniazdo administracyjne) upewnij się, że jako aktywny w backendzie zapisowym widnieje dokładnie jeden węzeł. Powtórz test po ponownym uruchomieniu starego węzła: musi wrócić jako replika, a ruch zapisowy pozostać na nowym liderze - to dowód, że warstwa dostępowa poprawnie śledzi rolę i nie rozjeżdża się z klastrem.

Wróć do listy: 100 najczęstszych pytań i problemów z PostgreSQL

Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL

Sprawdź szkolenie: Administracja, replikacja i tuning baz danych PostgreSQL

To szkolenie może być dofinansowane z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Szkolenie Zaawansowana administracja PostgreSQL - HA, DR, monitoring, skalowanie

Sprawdź szkolenie: Zaawansowana administracja PostgreSQL (HA, DR, monitoring, skalowanie)

To szkolenie może być dofinansowane z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Najczęściej zadawane pytania

Dlaczego po failoverze aplikacja nie łączy się z nowym serwerem głównym?
Bo failover odbywa się wewnątrz klastra bazy i zmienia jedynie to, który węzeł jest głównym. Nie ma wpływu na to, dokąd łączy się aplikacja. Jeśli klient ma w konfiguracji na sztywno adres starego serwera, po jego awarii po prostu nie ma z kim rozmawiać. Brakuje warstwy, która kierowałaby ruch na aktualnego mastera.
Jak sprawić, żeby aplikacja zawsze trafiała na aktualny serwer główny?
Postaw między aplikacją a bazą warstwę dostępową i wpisz do connection stringa jeden stały punkt wejścia. Dwa typowe rozwiązania to pływający adres VIP, który przy failoverze wędruje na nowego lidera, albo proxy takie jak HAProxy, które rozpoznaje aktualnego mastera i kieruje do niego połączenia. Aplikacja nigdy nie powinna znać adresów pojedynczych węzłów.
Jak HAProxy rozpoznaje, który węzeł PostgreSQL jest aktualnie liderem?
Przez sprawdzenie zdrowia oparte na endpoincie klastra. W klastrach zarządzanych przez Patroni HAProxy odpytuje wbudowane REST API, którego ścieżka dla lidera, na przykład /primary, zwraca kod HTTP 200, a dla repliki kod inny niż 200. Dzięki temu HAProxy kieruje ruch zapisowy wyłącznie do węzła, który jest teraz główny.
Jak sprawdzić, że po failoverze trafiam na serwer główny, a nie na replikę?
Połącz się przez stały punkt wejścia i wykonaj SELECT pg_is_in_recovery(). Odpowiedź f oznacza serwer główny, a t replikę. Warto też zajrzeć w statystyki HAProxy i upewnić się, że w backendzie zapisowym jako aktywny widnieje dokładnie jeden węzeł. Całość najlepiej przetestować kontrolowanym failoverem przed wdrożeniem na produkcji.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...