Czy na replikację MySQL ma wpływ połączenie o wysokim opóźnieniu?


11

Mamy waniliową konfigurację MySQL master i slave, które znajdują się w różnych centrach danych, oraz inną slave w tym samym centrum danych, co master.

Przepustowość między centrum danych jest dość wysoka (w przeprowadzonych przez nas testach sieciowych możemy osiągnąć 15 MB / sekundę), ale istnieje opóźnienie, około 28 ms. W żadnym wypadku nie jest wysoki, ale jest znacznie większy niż opóźnienie poniżej sekundy w tym samym centrum danych.

Czasami występują poważne opóźnienia (2000 sekund i więcej) po usunięciu slave, podczas gdy lokalny slave jest aktualny. Patrząc na opóźnione zdalne slave, wątek SQL zwykle spędza czas na oczekiwaniu na aktualizację dziennika przekazywania przez wątek IO. Mistrz pokazuje jednocześnie „czekanie na sieć” lub coś w tym rodzaju.

Oznacza to, że jest to sieć, ale w tym momencie nadal mamy wolne pasmo.

Moje pytanie brzmi : czy opóźnienie między centrami danych może wpływać na wydajność replikacji? Czy wątek slave io przesyła strumieniowo zdarzenia, dopóki master przestanie je wysyłać, czy może w jakiś sposób łączy master między zdarzeniami?


2000 sekund? Czyli 33-minutowe opóźnienie?
Richard

Tak ... To idzie w górę i w dół w ciągu dnia.
shlomoid

2
+1, ponieważ uwielbiam tego rodzaju pytania na tej stronie. Powiedz innym, aby przyszli na tę stronę z pytaniami o tym charakterze !!!
RolandoMySQLDBA,

Odpowiedzi:


7

Bezpośrednia odpowiedź na twoje pytanie brzmi: tak, ale zależy to od wersji MySQL, którą używasz. Przed MySQL 5.5 replikacja działała w następujący sposób:

  • Master Wykonuje SQL
  • Master zapisuje zdarzenie SQL w swoich dziennikach binarnych
  • Slave czyta zdarzenie SQL z Master Binary Logs
  • Slave zapisuje zdarzenie SQL w dziennikach przekaźników za pośrednictwem wątku we / wy
  • Slave czyta następne zdarzenie SQL z dziennika przekazywania przez wątek SQL
  • Slave wykonuje SQL
  • Slave uznaje mistrza pełnego wykonania zdarzenia SQL

Począwszy od MySQL 5.5, przy użyciu replikacji półsynchronicznej , teraz replikacja będzie działać w następujący sposób:

  • Master Wykonuje SQL
  • Master zapisuje zdarzenie SQL w swoich dziennikach binarnych
  • Slave czyta zdarzenie SQL z Master Binary Logs
  • Slave potwierdza Master odbioru zdarzenia SQL
  • Slave zapisuje zdarzenie SQL w dziennikach przekaźników za pośrednictwem wątku we / wy
  • Slave czyta następne zdarzenie SQL z dziennika przekazywania przez wątek SQL
  • Slave wykonuje SQL
  • Slave uznaje mistrza pełnego wykonania zdarzenia SQL

Ten nowy paradygmat pozwoli Slave na bliższą synchronizację z jego Mistrzem.

Niezależnie od tego, opóźnienia w sieci mogą utrudnić replikację Semisync MySQL do tego stopnia, że ​​powraca ona do replikacji asynchronicznej w starym stylu. Dlaczego ? Jeśli nastąpi przekroczenie limitu czasu bez potwierdzenia transakcji przez urządzenie podrzędne, urządzenie nadrzędne powraca do replikacji asynchronicznej. Gdy co najmniej jedno półsynchroniczne urządzenie podrzędne łapie, master wraca do półsynchronicznej replikacji.

AKTUALIZACJA 2011-08-08 14:22 EDT

Konfiguracja półsynchronicznej replikacji MySQL 5.5 jest prosta

Krok 1) Dodaj te cztery (4) linie do /etc/my.cnf

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
#rpl_semi_sync_master_enabled
#rpl_semi_sync_master_timeout=5000
#rpl_semi_sync_slave_enabled

Krok 2) Uruchom ponownie MySQL

service mysql restart

Krok 3) Uruchom te polecenia w kliencie MySQL

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave  SONAME 'semisync_slave.so';

Krok 4) Odkomentuj trzy opcje rpm_semi_sync po opcji plugin-dir

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
rpl_semi_sync_master_enabled
rpl_semi_sync_master_timeout=5000
rpl_semi_sync_slave_enabled

Krok 5) Uruchom ponownie MySQL

service mysql restart

Wszystko zrobione !!! Teraz skonfiguruj replikację MySQL jak zwykle.


Nie jestem pewien ostatniego etapu replikacji asynchronicznej - nie sądzę, aby mistrz wiedział, jak daleko zaszedł każdy niewolnik. O ile mi wiadomo, mogą poprosić o dowolną część dziennika binarnego, czy mają jakieś referencje?
shlomoid

Ponadto używamy domyślnej replikacji asynchronicznej w MySQL, a nie typu asynchronicznego - który należy włączyć celowo, instalując wtyczki i podobne. Próbuję zrozumieć, czy zdarzenia są przesyłane do sieci slave w stylu net-cat z pozycji początkowej w dzienniku, czy istnieje wymiana tam iz powrotem między panem i niewolnikiem dla każdego zdarzenia, które może cierpieć z powodu takiego opóźnienia.
shlomoid

Z całą pewnością gorąco polecam używanie MySQL 5.5, aby skorzystać z tej nowej formy replikacji MySQL, a także ulepszeń InnoDB.
RolandoMySQLDBA,

1
Tak, oczywiście używamy MySQL 5.5, ale nie jest to domyślny typ replikacji. Musisz przejść całą procedurę konfiguracji, zainstalować wtyczki i tym podobne, aby działało to w sposób częściowo synchroniczny.
shlomoid

2

Naprawdę podoba mi się, jak Rolando opisał sekwencję operacji wykonywanych przez replikację. Myślę jednak, że byłoby bardziej jasne, gdybyśmy dodali inny komponent - klient.

W przypadku klienta sekwencja operacji replikacji asynchronicznej może wyglądać następująco:

  1. Klient wysyła do master zapytanie SQL (na przykład wstaw) za pomocą transakcji

  2. Master wykonuje transakcję. W przypadku powodzenia zapis jest zapisywany na dysku, ale transakcja nie została jeszcze zatwierdzona.

  3. Master zapisuje zdarzenie wstawiania w głównym dzienniku binarnym Jeśli master nie mógł zapisać go w dzienniku binarnym, transakcja została wycofana.

  4. Klient otrzymuje odpowiedź od wzorca (sukces lub wycofanie).

  5. W przypadku powodzenia transakcji wątek zrzutu na urządzeniu głównym odczytuje zdarzenie z dziennika binarnego i wysyła go do podrzędnego wątku we / wy.

  6. Wątek we / wy slave odbiera zdarzenie i zapisuje je na końcu pliku dziennika przekazywania.

  7. Gdy zdarzenie przejdzie do dziennika przekazywania, wątek SQL slave wykonuje
    zdarzenie, aby zastosować zmiany w bazie danych na slave.

W tym scenariuszu master nie dba o slave, a klient wie tylko, że coś jest nie tak z slave, ręcznie wykonując polecenie „SHOW SLAVE STATUS”.

W przypadku replikacji synchronicznej sekwencja operacji może wyglądać następująco:

  1. Klient wysyła do master zapytanie SQL (na przykład wstaw) za pomocą transakcji.

  2. Master wykonuje transakcję. W przypadku powodzenia zapis jest zapisywany na dysku, ale transakcja nie zostaje zatwierdzona.

  3. Master zapisuje zdarzenie wstawiania w głównym dzienniku binarnym Jeśli master nie może zapisać go w dzienniku binarnym, transakcja jest wycofywana, a klient odbiera odpowiedź tylko w przypadku wycofania.

  4. Z powodu powodzenia transakcji na module głównym wątek zrzutu na module głównym odczytuje zdarzenie z dziennika binarnego i wysyła go do wątku podrzędnego we / wy.

  5. Wątek we / wy slave odbiera zdarzenie i zapisuje je na końcu pliku dziennika przekazywania.

  6. Slave potwierdza Master zapisu zdarzenia w pliku dziennika przekazywania.

  7. Master zatwierdza transakcję wstawienia.

  8. Klient otrzymuje odpowiedź od mistrza (sukces).

  9. Gdy zdarzenie trafi do dziennika przekazywania, wątek slave SQL wykonuje
    zdarzenie. Master i klient nie wiedzą, czy wykonanie zakończyło się powodzeniem, czy nie.

Półsynchroniczna replikacja rozwiązała jeden ważny przypadek, gdy Slave lub sieć zmarły, a Master kontynuował. Następnie master umiera i chcesz zrestartować stary slave jako nowy master tylko dlatego, że naprawiłeś ten węzeł.

Więc uruchomiłeś ten węzeł jako nowy master, naprawiłeś stary master i teraz chcesz go używać jako slave. Ten węzeł nadal ma dane, ale jeśli nowy slave zacznie od miejsca, w którym zaczął nowy master, będą istnieć zduplikowane rekordy.

Jeśli okres oczekiwania jest nieskończony, pozycja dziennika binarnego głównego zawsze będzie zsynchronizowana z pozycją dziennika przekaźnika podrzędnego, zakładając, że wszystkie zapytania na urządzeniu podrzędnym zakończyły się powodzeniem. Jak realistyczne jest to założenie?

Myślę, że to jest bardzo realistyczne. Jednym z najczęstszych przypadków niepowodzenia zapytania podrzędnego jest „zduplikowany rekord”. Gdzie zduplikowany rekord dotarł do niewolnika, jeśli master go nie miał? Przyszedł z niewłaściwej pozycji podanej niewolnikowi, aby rozpocząć replikację. Początkowa pozycja replikacji obejmowała rekord, który został już zreplikowany. W przypadku replikacji półsynchronicznej taka sytuacja się nie stanie.

Jacob Nikom


1

Kwalifikator : Nie jestem użytkownikiem MySQL, więc głównie są to moje badania w Internecie.

Jak zapewne wiesz, największym ograniczeniem replikacji MySQL jest to, że jest ona jednowątkowa. Tak więc, gdy wątek jest zajęty wysyłaniem danych do wewnętrznego urządzenia podrzędnego, nie będzie w stanie wysłać danych do zdalnego urządzenia podrzędnego. To jest tutaj .


Per tutaj :

Jedyną rzeczą, którą musisz zrobić, to skrócić czas transakcji. Dzięki temu wątek replikacji ma możliwość nadrobienia zaległości w bazie danych. Chcesz, aby Twoje transakcje były jak najkrótsze.

Jednym ze sposobów na to jest cięcie zapytań; ogranicz wiersze zmienione przez UPDATE lub DELETE za pomocą klauzul WHERE. Jeśli utkniesz w pętli, możesz iterować listę, rozpoczynając i zatwierdzając transakcję za każdym razem. (UPDATE / DELETE pierwszy trzecią, drugą trzecią, a następnie ostateczną trzecią każdy we własnym transakcji.) Osobiście zdecydowanie odradzam ten sposób, ponieważ otworzyć się na możliwość danymi w tabeli zmieniającym między transakcjami. Istnieje jednak możliwość poprawy tej wydajności, jeśli masz pewność, że nikt inny nie będzie bałaganu w tabeli (i nigdy nie będzie) .

Inną możliwością jest nie replikowanie tych długo działających transakcji, a raczej uruchomienie ich zarówno na urządzeniu głównym (które replikuje się na lokalnym urządzeniu podrzędnym), a następnie osobne uruchomienie na zdalnym urządzeniu podrzędnym. Spowodowałoby to zwolnienie wątku replikacji, aby nie ugrzęzł do znaku ponad 30 minut.


Per tutaj :

Ostatnią możliwością byłoby dostrojenie rozmiaru buforów TCP. Celem jest zmniejszenie liczby komunikacji między panem a niewolnikiem. Może to pomóc zmniejszyć opóźnienie.

Osobiście spróbowałbym tego, jeśli wszystko inne zawiedzie. Podejrzewam, że problem jest bardziej spowodowany przez system jednowątkowej replikacji, a nie opóźnienie sieciowe. Sieci zwykle kończyłyby się na długo przed upływem 30 minut. (30 minut?!)


Delicious JHammerb's Zakładki ma kilka linków do replikacji mysql, które możesz chcieć również sprawdzić.

Mam nadzieję że to pomogło.


1
Otrzymujesz +1 za wzmiankę o tym, jak replikacja MySQL jest jednowątkowa, ale muszę zakwalifikować twoje oświadczenie w następujący sposób: Replikacja MySQL jest dwuwątkowa przy użyciu wątku I / O do pobierania zdarzeń SQL od Master do Slave oraz wątku SQL do przetwarzania zdarzenia SQL lokalnie w Slave. Jednak transmisja zdarzeń SQL jest jednowątkowa, co jest kontekstowo prawidłowe dla tego pytania.
RolandoMySQLDBA,

2
BTW Proszę nie używać LIMIT z instrukcjami UPDATE i DELETE, ponieważ kolejność wierszy aktualizowanych lub usuwanych może nie być taka sama w Slave jak w Master. Jeśli faktem jest, komunikaty ostrzegawcze na ten temat pojawiają się w dzienniku błędów w rodzaju „Komunikat nie BinLog-Safe”.
RolandoMySQLDBA

O, dobra uwaga na temat nieużywania LIMITU z UPDATE i DELETE. Zmodyfikuję swoją odpowiedź, aby ją usunąć.
Richard
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.