Serwery w chmurze Amazon AWS (cz.1)
Przeanalizujemy dość ciekawy, moim zdaniem, projekt, który mam okazję realizować a którego celem jest przygotowanie infrastruktury pod 1 godzinne wydarzenie internetowe z przewidywalnym maksymalnym ruchem 50,000 użytkowników jednocześnie. Tak, tak, to nie są żarty, nasz serwer musi poradzić sobie właśnie z takim ruchem.
Mimo otwartego budżetu i obecności na rynku wielu rozwiązań zarówno hardware’owych jak i dedykowanych usług obsługujących wydarzenia online o dużym ruchu postanowiłem skorzystać z dobrodziejstw chmury Amazon AWS i spróbować własnej konfiguracji. Wcześniej jednak z czystej ciekawości wykonałem test wydajnościowy Apach’a za pomocą narzędzi SIEGE i AB przy 100 jednoczesnych połączeniach do jednego adresu URL na standardowym serwerze produkcyjnym – wynik był przygnębiający, 40 jednoczesnych połączeń to górny limit wytrzymałości serwera www (sprzęt 2GHz, 4GB ram, 32bit). Testowana aplikacja to framework PHP opisany w kilku postach wcześniej w bardzo prostej postaci, wykorzystujący 2 zapytania SQL na potrzeby testowe. Dokładnie ten sam framework wykorzystany będzie do testów w chmurze Amazona.
A zatem do wstępnych obliczeń. 50,000 użytkowników jednocześnie wygeneruje 500,000 requestów do webserwera w ciągu sekundy (50,000 x 10 requestów na jedną stronę zakładając wyłączony cache przeglądarki) i 100,000 zapytań SQL (zakładając brak cachu i optymalizacji MySQL)
Pierwszą decyzje, którą podjąłem to skorzystanie z CDN w chmurze Amazona i wykupienie usługi S3 na którą wgramy wszystkie statyczne pliki (CSS, JS etc). Ten krok spowodował, że teraz jedno zapytanie do webserwera to dokładnie 1 request, a nie 10. A zatem najważniejsze pytanie: Ile webserwerów potrzebujemy aby zapewnić 50,000 odwołań na sekundę – zabieramy sie do testów…
Konfiguracja testowa:
1 x serwer AWS EC2 64GB ram, 8 core 64bit Linux
1 x AWS S3 CDN Irlandia
Testy wykonujemy za pomocą SIEGE i AB odpytując webserwer zapytaniami, startujemy od 100 jednocześnie zwiększając ilość co 200 aż do momentu pojawienia się błędów. Tym sposobem określam maksymalną wydajność webserwera na 2200 request/s ale sporadycznie pojawiają się błędy socketów w narzędziach testujących. Okazuje się, że sam fakt testowania wykorzystuje maksymalną ilość plików otwartych jednocześnie przez użytkownika (każdy otwarty socket to również otwarty plik), szybka zmiana i po ustawieniu limitów z 1000 na 20000 w limits.conf kontynuujemy testy.
Tym razem wyniki są dużo lepsze, pierwsze błędy pojawiają się przy około 2900-3000 request/s i zwracane śa przez Apache’a jako „connection reset by peer (104)” – uzywam prefork MPM ze względu na stabilność pracy z modułowym PHP 5.3.2 – zmiany w konfiguracji nie pomagają.
W kilku dyskusjach na temat wydajności samego Apache’a polecano konfigurację PHP jako FastCGI i MPM worker lub MPM event ale nie zdecydowałem się na te zmiany ze względy na obserwowaną niestabilność Apache’a w takiej konfiguracji. Używanie MPM worker i FastCGI dostarcza naturalnego load balancingu pomiędzy procesami Apache’a i na pewno warto przetestować tą opcję w przyszłości, póki co moje doświadczenia z FreeBSD, PHP FastCGI i memory leaks podpowiedziały mi żeby odstawić ten scenariusz na później…
Na chwilę obecną serwer MySQL jest uruchomiony na lokalnej maszynie i na pewno dokłada się do wysycenia zasobów, przeniesienie go na osobny serwer, instancję EC2 jako master-db to kolejny krok. Testy pokazują, że na chwilę obecną będę potrzebował ok 25 najsilniejszych instancji EC2 aby zapewnić obsługę 50,000 requestów na sekundę, nie wspominając o jakimś dedykowanym rozwiązaniu dla serwera DB.
Kolejne wyniki testów i zmiany w konfiguracji w kolejnym artykule.
Jeszcze jeden szczegół oparty na pierwszych testach, koszt infrastruktury w chmurze Amazona oscyluje w okolicach 1200-1400$ za 24 godziny, najtańsza oferta , którą do tej pory otrzymałem za instalacje i udostępnienie takiej struktury to 18tyś zł…
Data: sie 6, 2010