Split-brain w klastrze HA - jak do niego nie dopuścić
Udostępnij na:
Spis treści
PostgreSQL
Split-brain w klastrze HA - jak do niego nie dopuścić
W skrócie
W klastrze wysokiej dostępności po awarii sieci nagle działają dwa serwery primary naraz, każdy przyjmuje zapisy i dane się rozjeżdżają.
To split-brain: gdy węzły przestają się widzieć, a nie ma jednego arbitra decydującego, kto jest primary, standby promuje się do primary, mimo że stary primary wciąż żyje.
Zapobiegaj przez menedżera klastra z rozproszonym magazynem stanu i mechanizmem odcinania starego primary (fencing), a nie przez ręczne promocje - i nigdy nie promuj standby "na wszelki wypadek".
Split-brain to najgroźniejsza awaria w klastrze HA PostgreSQL: dwa węzły uznają się za primary i oba przyjmują zapisy, przez co dane rozchodzą się nieodwracalnie. Rozwiązania takie jak Patroni istnieją właśnie po to, żeby do tego nie dopuścić. Pokażemy, skąd bierze się split-brain i jak go systemowo wyeliminować.
Jak to wygląda w praktyce
Po incydencie sieciowym albo nieudanym failoverze aplikacja zgłasza dziwne niespójności: rekord zapisany przez jednego użytkownika znika u drugiego, klucze się dublują, salda się nie zgadzają. Przy bliższym spojrzeniu okazuje się, że dwa serwery, które miały tworzyć parę primary-standby, oba odpowiadają jako zapisywalne primary. Każdy przyjął część ruchu i ma teraz własną, rozbieżną wersję danych. Nie da się ich prosto połączyć, bo obie strony mają zmiany, których nie ma druga. To sytuacja, w której zwykłe wznowienie replikacji już nie pomoże - trzeba wybrać jedną wersję prawdy i pogodzić się z utratą części zapisów z drugiej. Dlatego split-brain leczy się przez zapobieganie, nie przez naprawę po fakcie.
Dlaczego tak się dzieje
Klaster HA ma dwie kluczowe potrzeby: musi wykryć, że primary padł, i musi zapewnić, że w danym momencie primary jest dokładnie jeden. Split-brain pojawia się, gdy te dwie rzeczy się rozjeżdżają. Najczęstsza przyczyna to podział sieci: węzły przestają się widzieć, więc standby wnioskuje, że primary padł, i sam się promuje - podczas gdy stary primary wcale nie padł, tylko stracił łączność, i dalej obsługuje klientów po swojej stronie. Bez wspólnego, rozstrzygającego źródła prawdy każdy węzeł podejmuje decyzję lokalnie i obie decyzje mogą być sprzeczne. Do tego dochodzą ręczne promocje wykonywane w panice ("promujmy standby, bo primary nie odpowiada"), gdy stary primary za chwilę wraca do życia. Rozwiązaniem jest oddanie decyzji jednemu mechanizmowi opartemu na kworum (większości głosów w rozproszonym magazynie stanu) oraz twarde odcięcie starego primary przed promocją nowego.
Jak to rozwiązać krok po kroku
Nie zarządzaj failoverem ręcznie. Wdróż menedżera klastra dla PostgreSQL (np. Patroni), który przejmuje decyzję o tym, kto jest primary, zamiast administratora działającego pod presją.
Postaw rozproszony magazyn stanu z kworum (np. etcd) i uruchom go na nieparzystej liczbie węzłów, żeby po podziale sieci tylko jedna strona miała większość i prawo utrzymać primary.
Skonfiguruj dzierżawę roli lidera (leader lease): primary musi cyklicznie odnawiać swój status w magazynie stanu, a gdy straci większość, sam się degraduje, zamiast obsługiwać zapisy w izolacji.
Włącz odcinanie starego primary (fencing lub STONITH), tak aby przed promocją standby stary węzeł został pewnie zatrzymany lub odcięty od klientów. To fizycznie uniemożliwia dwa primary naraz.
Skieruj ruch aplikacji przez jeden punkt wejścia świadomy roli węzłów (np. warstwa proxy prowadzona przez menedżera klastra), żeby klienci zawsze trafiali do aktualnego primary, a nie do zdegradowanego węzła.
Przetestuj scenariusze awarii w środowisku nieprodukcyjnym: odetnij sieć między węzłami, ubij primary, zasymuluj powrót starego lidera i sprawdź, że klaster zawsze zbiega do jednego primary.
Ustaw monitoring i alarmy na liczbę węzłów w roli primary oraz na utratę kworum, żeby każde odchylenie od "dokładnie jeden primary" natychmiast rzucało się w oczy.
Jak sprawdzić, że zadziałało
Najpewniejszy dowód to kontrolowany test awaryjny na środowisku testowym: rozłącz sieć między węzłami i potwierdź, że tylko strona z kworum utrzymuje primary, a odcięta strona degraduje się do standby lub zatrzymuje. Po każdym failoverze sprawdź, że w całym klastrze dokładnie jeden węzeł zwraca false z pg_is_in_recovery(), a wszystkie pozostałe zwracają true. Zajrzyj do stanu menedżera klastra (dla Patroni jego widok stanu członków), żeby zobaczyć jednego lidera i resztę jako repliki. Zweryfikuj też, że ruch aplikacji trafia wyłącznie do bieżącego primary. Jeśli po symulowanym podziale sieci nigdy nie pojawiają się dwa primary, ochrona przed split-brain działa.
To sytuacja, w której dwa węzły jednocześnie uznają się za primary i oba przyjmują zapisy, przez co dane rozchodzą się na dwie rozbieżne wersje. Najczęściej powstaje po podziale sieci: węzły przestają się widzieć, standby wnioskuje, że primary padł, i sam się promuje, podczas gdy stary primary wciąż żyje i obsługuje klientów po swojej stronie. Efektu nie da się prosto naprawić, bo obie strony mają zmiany, których nie ma druga, więc split-brain leczy się przez zapobieganie.
Dlaczego ręczny failover grozi split-brain?
Bo decyzja o promocji zapada lokalnie, pod presją i bez pewności, że stary primary naprawdę padł. Administrator, który promuje standby, gdy primary tylko chwilowo nie odpowiada (na przykład z powodu problemu sieciowego), tworzy drugi primary w momencie, gdy stary za chwilę wraca do życia. Bez wspólnego arbitra i bez odcięcia starego węzła oba serwery przyjmują zapisy naraz. Dlatego failoverem powinien sterować menedżer klastra oparty na kworum, a nie człowiek działający ad hoc.
Jak kworum zapobiega split-brain?
Kworum to wymóg większości głosów w rozproszonym magazynie stanu, na przykład etcd, uruchomionym na nieparzystej liczbie węzłów. Gdy sieć się dzieli, tylko jedna strona ma większość i tylko ona może utrzymać albo wybrać primary; strona mniejszościowa sama się degraduje i nie obsługuje zapisów w izolacji. Do tego dochodzi dzierżawa roli lidera: primary musi cyklicznie odnawiać status w magazynie, a gdy straci większość, degraduje się samoczynnie. Dzięki temu w danym momencie primary jest dokładnie jeden.
Do czego służy fencing w kontekście split-brain?
Fencing (nazywany też STONITH) to mechanizm pewnego odcięcia starego primary przed promocją nowego. Zanim menedżer klastra awansuje standby, stary węzeł zostaje zatrzymany albo odcięty od klientów, co fizycznie uniemożliwia istnienie dwóch primary naraz. Bez fencingu nawet klaster z kworum ryzykuje, że odizolowany stary primary wciąż przyjmuje zapisy od klientów, którzy do niego docierają. Dlatego pełna ochrona przed split-brain łączy kworum z fencingiem i jednym punktem wejścia ruchu świadomym ról węzłów.
Komentarze (0)
Brak komentarzy...