...

Zrozumienie spójności replikacji bazy danych i Split-Brain w klastrach MySQL

Pokazuję, jak Spójność replikacji w konfiguracjach MySQL i dlaczego nawet drobne błędy sieciowe mogą wywołać rozdwojenie jaźni. Wyjaśniam w praktyczny sposób, jak replikacja, modele spójności i mechanizmy kworum współpracują ze sobą i jak mogę szybko opanować scenariusze błędów.

Punkty centralne

Najpierw podsumuję najważniejsze wytyczne, abyś mógł prawidłowo ustawić priorytety i Ryzyko ocenia. Każda decyzja dotycząca topologii wpływa na spójność, opóźnienia i odzyskiwalność, więc należy ją świadomie ocenić i udokumentować. Kworum, wytyczne zapisu i reguły przełączania awaryjnego zapobiegają sporom o aktywny węzeł i utrzymują obciążenie pisaniem czysty kanał.

  • Cele w zakresie spójności jasno zdefiniować (RPO/RTO, odczyt po zapisie)
  • Topologia wybrać odpowiedni (replika podstawowa, multi-master, klaster)
  • Kworum bezpieczne (większość, trzecia lokalizacja, urządzenie)
  • Przełączanie awaryjne Ścisła kontrola (tylko do odczytu, VIP/DNS, orkiestracja)
  • Monitoring Rozszerzenie (opóźnienie, latencja, kondycja, alarmy)

Te kamienie węgielne dają mi stabilny kompas do podejmowania decyzji i zapobiegają akcjonizmowi w przypadku niepowodzenia. W ten sposób zachowuję spójność i utrzymuję Dostępność pod kontrolą.

Jak działa replikacja MySQL

Replikuję operacje zapisu z Podstawowe do jednej lub więcej replik w celu amortyzacji awarii i dystrybucji dostępu do odczytu. Topologie primary-replica łączą zapisy centralnie, podczas gdy repliki są odpowiedzialne za odczyty, kopie zapasowe i analizy. Multi-master dystrybuuje zapisy do kilku węzłów, ale wymaga ścisłych reguł konfliktu. Klastry z poziomem koordynacji łączą poziom danych i kworum, co oznacza, że węzeł pozostaje aktywny tylko przy większości. Więcej informacji na temat poszczególnych wariantów można znaleźć na stronie Typy replikacji MySQL dobry przegląd, którego używam jako punktu wyjścia. Ostatecznie liczy się to, że zapisy są jasno zarządzane i że świadomie kontroluję ścieżki odczytu, aby spójność nie pozostała w tyle. Skalowanie cierpi.

Poziomy izolacji i projektowanie transakcji

Zawsze planuję replikację razem z Projekt transakcji. MySQL domyślnie używa REPEATABLE READ: Jest to solidne dla OLTP, ale generuje szybszy odczyt dla długich transakcji. Lag, ponieważ przechowywanych jest wiele starych wersji. W przypadku obciążeń z wieloma selektywnymi aktualizacjami czasami używam READ COMMITTED, aby zmniejszyć blokady i efekty uboczne. Upewniam się, że zmiany wsadowe są małe, ograniczony w czasie transakcji zamiast wykonywania minutowych „mega-commitów“. Dzięki temu dzienniki binarne są kompaktowe, wątki SQL repliki nie blokują się, a Opóźnienie replikacji buduje się wolniej. Unikam również funkcji niedeterministycznych w formie instrukcji (np. NOW() bez ustalania), jeśli nie chcę używać Oparte na rzędach replikować - w przeciwnym razie ryzykuję rozbieżności.

Modele spójności wyjaśnione w jasny sposób

Rozróżniam między silny Spójność, ewentualna spójność i odczyt po zapisie. Silna spójność wymaga zatwierdzenia przez kilka węzłów, zanim klient otrzyma komunikat o powodzeniu. Ostateczna spójność akceptuje krótkoterminowe różnice, dopóki repliki nie nadrobią zaległości. Read-after-write zapewnia, że piszący użytkownik natychmiast odczyta swoją zmianę, nawet jeśli inni nadal widzą stare dane. W krytycznych procesach biznesowych polegam na silnej spójności lub spójności odczytu po zapisie, podczas gdy do raportowania używam ostatecznej spójności. Taki kompromis pozwala kontrolować opóźnienia, a jednocześnie chroni dane. Integralność danych.

Typy replikacji i opóźnienia

Używam replikacji asynchronicznej, gdy potrzebuję maksymalnego opóźnienia zapisu i pewnego RPO zaakceptować. Procesy półsynchroniczne zmniejszają ryzyko utraty danych, ale kosztują czas na zatwierdzenie. Procesy synchroniczne silnie zapewniają spójność, ale są wrażliwe na opóźnienia sieciowe i utratę pakietów. Wraz ze wzrostem odległości między węzłami wzrasta czas podróży w obie strony, co znacznie spowalnia synchroniczne zatwierdzenia. Jeśli wystąpi opóźnienie, aktywnie sprawdzam Opóźnienie replikacji w MySQL, zoptymalizować wzorce pisania i rozdzielać żądania czytania w ukierunkowany sposób. Pozwala mi to zachować równowagę między tempem i wydajnością. Bezpieczeństwo.

Tryb Zaangażowane zachowanie Opóźnienie RPO Typowe zastosowanie Ryzyko rozdwojenia jaźni
Asynchroniczny Główny potwierdzony natychmiast Niski Wyższy Wysoka przepustowość, raportowanie odczytów Średni (dla przełączania awaryjnego bez wskazówek)
Półsynchroniczny Co najmniej jedna replika została potwierdzona Średni Niższy Krytyczne transakcje z buforem opóźnień Niższy (możliwe lepsze prowadzenie)
Synchroniczny/klaster Większość oszczędza na stałe Wyższy Bardzo niski Klastry z wymaganiami dotyczącymi kworum Niski (z czystym kworum)

Format Binlog, identyfikatory GTID i bezpieczeństwo kolizji

Konsekwentnie polegam na GTID (gtid_mode=ON, enforce_gtid_consistency=ON), aby przełączanie awaryjne działało bez zagadek związanych z pozycją. Obsługuję kanały replikacji z auto_position=1, aby repliki sortowały się po przełączeniu. Dla binloga preferuję Oparte na rzędach (binlog_format=ROW), ponieważ jest deterministyczny i pozwala uniknąć konfliktów z funkcjami lub niedeterminizmem. Używam mixed/statement tylko wybiórczo.

Zapewniam bezpieczeństwo podczas kolizji dzięki sync_binlog=1 oraz innodb_flush_log_at_trx_commit=1 jeśli RPO ma być praktycznie zerowe. W przypadku większej wrażliwości na opóźnienia wybieram kompromisy, ale wyraźnie je dokumentuję. Aby upewnić się, że repliki wyczyszczą się w przypadku awarii, aktywuję relay_log_recovery i odejść log_replica_updates (dawniej log_slave_updates), aby kaskady pozostały stabilne. Dla przepustowości Replikacja równoległa: replica_parallel_workers (np. 8-32) plus binlog_transaction_dependency_tracking=WRITESET optymalizuje układ bez naruszania wierszy.

Rozszczepienie mózgu: przyczyny i objawy

Rozszczepienie mózgu występuje, gdy związek dzieli się na kilka części w tym samym czasie pisać. Problem często wywołuje partycja sieciowa lub wadliwe połączenie międzysieciowe. Wadliwe skrypty przełączania awaryjnego lub niejasne reguły kworum pogarszają sytuację. Istnieją również dwie prawdy zapisu, które nie widzą się nawzajem. Bezpośrednim skutkiem są kolizje automatycznych przyrostów, sprzeczne aktualizacje i utracone usunięcia. Im dłużej taka sytuacja będzie się utrzymywać, tym trudniejsze będą kolejne operacje. Połączenie.

Scenariusze ryzyka specyficzne dla MySQL

Największe niebezpieczeństwa widzę w asynchronicznych konfiguracjach master-master bez ścisłej Wskazówki. Jeśli obie strony są zapisywalne, a sieć migocze, narzędzia z łatwością promują oba do kluczy podstawowych. Bez automatycznego zwiększania offsetów, klucze podstawowe natychmiast się zderzają. Jeśli nie ma logiki VIP lub przełącznika DNS, klienci zapisują do dwóch węzłów równolegle. Nawet klastry z wadliwym kworum pozwalają obu stronom kontynuować zapis. Te konstelacje rozbijają spójność szybciej niż zespół może się zorientować, dlatego zalecam jasne Runbooki gotowy.

Strategie zapewniające spójność

Definiuję jasną zasadę pisowni: jedna podstawowa, wszystkie inne ściśle tylko do odczytu. Do przełączania używam VIP lub krótkiego DNS TTL, aby zapisy trafiały tylko do aktywnego węzła. W projektach wielomasterowych ograniczam pokoje danych według klientów, regionów lub przestrzeni kluczy. Używam również automatycznego zwiększania offsetów, idempotencji i pól wersji. Po stronie aplikacji utrzymuję odczyt po zapisie z lepkością sesji lub ukierunkowanymi odczytami podstawowymi. Monitorowanie sprawdza opóźnienia, opóźnienia i kondycję, podczas gdy alarmy zapewniają wczesne ostrzeganie. W ten sposób wspieram spójność na kilku Poziomy jednocześnie.

Odczyt po zapisie w praktyce

Zabezpieczam odczyt po zapisie, przenosząc sesje zapisu do Podstawowe pin. Alternatywnie, pozostawiam odczyty na replikach tylko wtedy, gdy ich gtid_executed zawiera zapis użytkownika. W praktyce używam tokenów (np. GTID transakcji), które sprawdza ścieżka odczytu. Jeśli brakuje potwierdzenia, odczyt przechodzi bezpośrednio do wersji podstawowej lub czeka krótko, aż replika nadrobi zaległości. W przypadku interfejsów API używam nagłówków odpowiedzi z „wymagany odczyt po zapisie“, dzięki czemu frontendy mogą świadomie decydować o tym, czy świeży Wymuszaj dane lub żyj z możliwie spójnymi odczytami.

Zarządzanie lagami i projektowanie zapytań

Tworzę lagi głównie poprzez Dyscyplina zapytań z: Długie SELECTy mają limity czasowe i odpowiednie indeksy, hotspoty są rozbijane za pomocą shardingu lub kluczy alternatywnych. Duże aktualizacje/usunięcia wykonuję partiami z przerwami, aby nie zalewać binloga. Planuję przebudowy (np. ALTER TABLE) tak, aby były oparte na oknach i, jeśli to możliwe, online, aby nie blokować wątków replikacji. Na poziomie aplikacji ograniczam równoległe zapisy za pomocą ograniczania szybkości i wygładzam szczyty ruchu za pomocą kolejek. Niewielka tabela heartbeat pomaga mi mierzyć opóźnienia z dokładnością do sekundy. Limity alertów realistycznie.

Kworum, połączenia międzysystemowe i przełączanie awaryjne

Zaprojektowałem Quorum w taki sposób, że tylko część z Większość może napisać. Trzecia lokalizacja lub urządzenie kworum skutecznie rozwiązuje podziały dwukierunkowe. Nadmiarowe połączenia międzysieciowe zmniejszają ryzyko powstawania odizolowanych wysp. Przed każdym przełączeniem awaryjnym sprawdzam, czy poprzedni serwer podstawowy rzeczywiście zniknął lub został wyraźnie odcięty. Narzędzia do orkiestracji mogą promować tylko z wyraźnymi blokadami i kontrolami. Repliki pozostają chronione przed przypadkowymi zapisami za pomocą read_only=ON i super_read_only=ON, dopóki nie zaznaczę wyraźnie zwolnienie.

Orkiestracja, ogrodzenia i bezpieczne promocje

Używam orkiestracji wyłącznie jako StrażnikPromocja jest dozwolona tylko wtedy, gdy stary tryb podstawowy jest aktywnie ogrodzony (np. wycofany VIP), super_read_only=ON, spójny status repliki). Moje zasady obejmują:

  • Wyraźne wybory lidera z kontrolą większości i „no-dual-primary“ blokada
  • Promocja tylko jeśli server_uuid jednoznaczne, tylko do odczytu zestaw i kanały replikacji są czyste
  • Przełącznik DNS/VIP tylko po sprawdzeniu kondycji i opóźnień, nie wcześniej
  • Ścieżka wycofania: W razie wątpliwości system woli pozostać na swoim miejscu. krótki tylko do odczytu, zamiast pisać ryzykowne

Ważne: tylko do odczytu nie chroni przed zapisami od użytkowników SUPER - dlatego zawsze używam super_read_only. Izoluję również konta administratorów, aby żaden „przypadkowy“ zapis nie trafił na replikę w przypadku stresu.

Runbooki na wypadek sytuacji awaryjnych

Jeśli dojdzie do rozszczepienia mózgu, działam natychmiast i blokuję oba aktywne węzły zapisu dla nowych węzłów zapisu. Transakcje. Tworzę świeże kopie zapasowe lub migawki obu witryn przed podłączeniem czegokolwiek. Następnie zatrzymuję każdą replikację, aby stany danych nie mieszały się dalej. Następnie przeprowadzam analizę: które tabele zostały naruszone, które okresy, które działania użytkowników? Dzienniki audytu, znaczniki czasu i wersje pokazują mi historię. Definiuję „źródło prawdy“, selektywnie wprowadzam zmiany i ponownie konfiguruję replikację. Na koniec dokonuję walidacji za pomocą kontroli integralności i ścisłej siatki. Monitoring.

Porównywanie i uzdrawianie tabel danych

Do porównania używam sum kontrolnych, znaczników czasu i Pola wersji, aby niezawodnie rozpoznać rozbieżne linie. Tam, gdzie to możliwe, rekonstruuję sekwencję z dzienników zapisu lub dzienników binarnych. W przypadku konfliktów podejmuję decyzję zgodnie z jasnymi zasadami, takimi jak wygrana ostatniego zapisującego lub logika domeny na atrybut. Silnie rozbieżne obszary zastępuję przywracaniem ze spójnej migawki, aby uniknąć efektów ubocznych. W pełni dokumentuję każdy import, aby późniejsze audyty mogły prześledzić ścieżkę. Po uzdrowieniu wymuszam całkowitą ponowną inicjalizację replik, tak aby wszystkie węzły miały identyczne parametry. Punkty początkowe mają.

Kopie zapasowe, PITR i ponowne wysiewanie

Łączę kompletne fizyczny Kopie zapasowe z binlogami do odzyskiwania w czasie rzeczywistym (PITR). Kopie zapasowe są uruchamiane na replice w celu ochrony podstawowej i są regularnie odczytywane na podstawie testów. W celu szybkiego ponownego wysiewu używam klonów/fizycznej wysyłki, jeśli jest dostępna, a następnie uruchamiam replikację z automatycznym pozycjonowaniem GTID. Opieram swoje zasady przechowywania na zgodności i celach RPO; zachowuję binlogi tak długo, jak wymaga tego mój maksymalny horyzont PITR. Bardzo ważne jest, aby kopie zapasowe Spójność (płukanie InnoDB, prawidłowe okno startowe binlog), w przeciwnym razie przywracanie i replikacja nie będą działać.

Testy, ćwiczenia i SLO

Definiuję jasno SLO (np. RPO ≤ 30 sekund, RTO ≤ 5 minut dla usług krytycznych) i regularnie sprawdzać je w ramach ćwiczeń. Scenariusze obejmują partycje sieciowe, awarie dysków, wadliwe połączenia i opóźnione repliki. Ćwiczę kroki „Fence - Promote - Switch Traffic - Validate“ i mierzę, jak szybko alerty i runbooki zaczynają działać. Specjalnie wstrzykuję również opóźnienia (szczyty ruchu, sztuczne opóźnienia), aby zobaczyć, jak reaguje routing, backpressure i mechanizmy odczytu po zapisie. Tylko to, co przećwiczymy, zadziała w sytuacji awaryjnej Niezawodny.

Skalowanie: Sharding, regiony i własność

Rozdzielam obowiązki związane z pisaniem między klientów, regiony lub Domeny, aby utrzymać małe obszary konfliktów. Regionalny sharding zmniejsza opóźnienia i pozwala na lokalne primary z jasnymi wskazówkami. Obsługuję globalne obciążenia odczytu z replik, podczas gdy ścieżki zapisu pozostają ściśle lokalne. Jeśli chcesz połączyć sharding, możesz znaleźć Sharding i replikacja dobry początek. Pozostaje to ważne: Reguły własności powinny znajdować się w kodzie, DDL i runbookach, a nie tylko w głowach ludzi. W ten sposób skalowanie pozostaje możliwe do zaplanowania, bez spójności przeciwko Prędkość do wymiany.

Funkcje chmury i wielu regionów

Aktywnie planuję ryzyko związane z opóźnieniami i partycjami w różnych regionach. Writes replikacja lokalna, międzyregionalna działa asynchronicznie z jasno określonym RPO. Przełączniki DNS lub VIP mają krótkie czasy TTL, ale tylko wtedy, gdy sprawdzane jest zdrowie i kworum. Unikam „przezroczystych“ globalnie rozproszonych zapisów bez twardych wskazówek - wyglądają na wygodne, ale tworzą konflikty, które są trudne do rozwiązania w przypadku awarii. W przypadku scenariuszy DR, utrzymuję w gotowości zimny lub ciepły region, regularnie ponownie zasiewam i testuję przełączanie awaryjne regionu jako pełne przełączanie awaryjne. Ćwiczenia biznesowe, nie tylko jako demo technologiczne.

Zgodność, bezpieczeństwo i możliwość audytu

Chronię kanały replikacji za pomocą TLS i ustawiam najmniejszy przywilej dla użytkowników replik. Przechowywanie binlogów i sum kontrolnych jest częścią funkcji audytu, podobnie jak identyfikowalne dzienniki zmian w potokach DDL. Szyfrowanie w spoczynku (przestrzeń tabel, kopie zapasowe) jest standardem; rotacja kluczy i kontrola dostępu są udokumentowane i przetestowane. Tożsamości serwerów (server_uuid, server_id) pozostają stabilne i jednoznaczne, dzięki czemu orkiestracja i GTID działają niezawodnie. Nic z tego nie jest celem samym w sobie: czyste ścieżki audytu przyspieszają Analizy przyczyn źródłowych i skrócić czas przestojów w sytuacjach awaryjnych.

Podsumowanie: Spójność przed szybkością

Nigdy nie planuję replikacji w odosobnieniu, ale zgodnie z jasnym Cele w zakresie spójności i przypadków biznesowych. Silne zasady dotyczące przywództwa, kworum i przełączania awaryjnego zapobiegają rozpadowi klastra przy pierwszym zakłóceniu. Monitorowanie, testy i ćwiczenia sprawiają, że mój zespół jest w stanie działać, gdy ma to znaczenie. Jeśli dojdzie do rozdwojenia jaźni, zatrzymuję zapisy, zapisuję stany, wybieram prawdę i konsekwentnie restartuję. W ten sposób replikacja MySQL pozostaje niezawodnie użyteczna, a spójność danych nie jest poświęcana na rzecz pragnienia Wydajność pada ofiarą.

Artykuły bieżące