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?
źródło
Odpowiedzi:
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:
Począwszy od MySQL 5.5, przy użyciu replikacji półsynchronicznej , teraz replikacja będzie działać w następujący sposób:
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
Krok 2) Uruchom ponownie MySQL
Krok 3) Uruchom te polecenia w kliencie MySQL
Krok 4) Odkomentuj trzy opcje rpm_semi_sync po opcji plugin-dir
Krok 5) Uruchom ponownie MySQL
Wszystko zrobione !!! Teraz skonfiguruj replikację MySQL jak zwykle.
źródło
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:
Klient wysyła do master zapytanie SQL (na przykład wstaw) za pomocą transakcji
Master wykonuje transakcję. W przypadku powodzenia zapis jest zapisywany na dysku, ale transakcja nie została jeszcze zatwierdzona.
Master zapisuje zdarzenie wstawiania w głównym dzienniku binarnym Jeśli master nie mógł zapisać go w dzienniku binarnym, transakcja została wycofana.
Klient otrzymuje odpowiedź od wzorca (sukces lub wycofanie).
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.
Wątek we / wy slave odbiera zdarzenie i zapisuje je na końcu pliku dziennika przekazywania.
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:
Klient wysyła do master zapytanie SQL (na przykład wstaw) za pomocą transakcji.
Master wykonuje transakcję. W przypadku powodzenia zapis jest zapisywany na dysku, ale transakcja nie zostaje zatwierdzona.
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.
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.
Wątek we / wy slave odbiera zdarzenie i zapisuje je na końcu pliku dziennika przekazywania.
Slave potwierdza Master zapisu zdarzenia w pliku dziennika przekazywania.
Master zatwierdza transakcję wstawienia.
Klient otrzymuje odpowiedź od mistrza (sukces).
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
źródło
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.
źródło