Nie boimy się wielkich liczb

Nie boimy się wielkich liczb

Jeden z wykonanych przez nas systemów dał prawdziwie dobre wyniki. Bez odpowiedniego oprogramowania i architektury serwerowej, którą również wdrażaliśmy raczej byłoby to nieosiągalne. W szczycie system przyjął ponad 10 000 unikalnych użytkowników na godzinę! Ale zacznijmy do początku…

Rozkład obciążenia

Spodziewaliśmy się dość sporego obciążenia po stronie klienckiej, gdzie pośród standardowych, prostych operacji na bazie danych system miał za zadanie przetwarzać również obrazki wrzucone przez użytkowników. Mieliśmy dane historyczne wykorzystania systemu i wiedzieliśmy, że w określonych sytuacjach baza danych również jest obciążona, jednak wąskim gardłem jest w pierwszej kolejności liczba użytkowników a następnie operacje użytkowników na obrazkach.
Postanowiliśmy rozdzielić architekturę serwerową przez wykorzystanie load balancera (tutaj rolę pełnił serwer nginx), a za nim stały kolejne 2 serwery www:

Taki układ bardzo sprawnie rozłożył obciążenie. Rozważaliśmy rozdzielenie samej obsługi przetwarzania obrazów użytkowników osobno jako tzw mikrousługi (wolimy jednak branżowo, po angielsku: microservices) jednak spodziewany ruch nie był aż tak duży aby opłacało się rozdzielać samą obsługę WWW od przetwarzania obrazów.
Do tego dochodzi jeszcze osobna maszyna przeznaczona na bazę danych, a w szczycie dwie bazy danych:

Całość działała w oparciu o chmurę made in Poland. Dlaczego chmurę? Podstawową zaletą chmury jest skalowalność, a branża klienta charakteryzuje się szybkimi wzrostami obciążenia. W miarę wzrostu obciążenia skalowaliśmy serwer w zależności od potrzeby.  Zwyczajnie, ekonomicznie uzasadnionym było wykorzystanie chmury nad dzierżawienie serwerów dedykowanych. A dlaczego nie Amazon? bo wolimy polskie usługi :-)

Po spięciu takiej infrastruktury uruchamiamy JMeter i odpalamy testowanie wydajności aplikacji, szukamy wąskich gardeł i weryfikujemy zachowanie systemu w zależności od różnych zmiennych.

System ma działać gdy serwerownia padnie

Ze względu na specyfikę branży klient oczekiwał nieprzerwanej dostępności systemu. Wymaganie było jasne: system ma działać nawet, gdy serwerownia padnie. Lekko dyskusyjne wymaganie bo do projektu wykorzystywaliśmy profesjonalnego i sprawdzonego dostawcę, no ale: klient płaci, klient wymaga. Czyli modyfikujemy system tak aby następowała replikacja na żywo (lub prawie na żywo) do drugiej, niezależnej serwerowni i w razie awarii przełączamy lokalizację.

Jak szybko przełączać miejsce wskazywania domeny pomiędzy różnymi serwerowniami? Cloudflare. O cudowności Cloudflare’a nikogo, kto tworzył popularniejszy w internecie system przekonywać nie trzeba. O ile główne zastosowania Cloudflare’a to wydajność i bezpieczeństwo to świetnie też się nadaje jako narzędzie do failover również w planie darmowym:

Po wdrożeniu drugiej serwerowni sytuacja wyglądała tak:

W drugiej serwerowni działały tylko bazy danych, które synchronizowały się z bazami z pierwszej serwerowni. W momencie awarii za pomocą API Cloudflare’a przełączamy w ciągu kilku minut system z jednej lokalizacji na drugą. Na szczęście nie sytuacja awarii serwerowni nie miała miejsca.

Kompletnie rzecz ujmując architektura prezentowała się tak:

Na poziomie bazy danych na diagramie jest pewnie uproszczenie jeśli chodzi o replikację, niemniej baza była replikowana na żywo do drugiej lokalizacji.

Wnioski

Klient był świadomy tego, że szansa na to aby chmura padła jest wyjątkowo mała, jednak chciał mieć system zreplikowany w dwóch lokalizacjach. W praktyce nie było potrzeby przełączania się pomiędzy lokalizacjami pozostaliśmy w Polsce – tak, druga lokalizacja chmury była zapewniona przez Amazona ;-) Efekt zastosowanej infrastruktury był taki, że w szczycie obciążenia wyżej opisana konfiguracja przyjęła ponad 10 tysięcy unikalnych użytkowników na godzinę i przepustowość 14GB danych na godzinę, a wszytko na kilkuletnim silniku w PHP5! Po drodze napotkaliśmy kilka problemów wymagających optymalizacji w kodzie PHP/SQL, po ich rozwiązaniu byliśmy w stanie przyjąć dwukrotnie wyższy ruch.
Czekamy na kolejne wyzwanie!