Optymalizacja aplikacji społecznościowej na Facebook i Grono w praktyce

Jak sprawić, aby aplikacja społecznościowa na Facebooku czy Gronie odwiedzana prawie milion razy miesięcznie działała bez problemów? Dowiesz się o tym z tego postu. Przedstawiam w nim techniki, które pozwoliły mi uzyskać taką wydajność na przykładzie aplikacji Quizzy.

Aplikacja Quizzy to 4 najpopularniejsza aplikacja online dostępna na stronie internetowej Grono.net. Grono.net (15) to pierszy polski serwis społecznościowy z 1,5 milionem real userów według najnowszego Megapanelu i jedyny polski konkurent Facebooka (14), który pozwala pisać aplikacje niezależnym programistom. Optymalizacja aplikacji społecznościowej nie różni się od tego na który serwis będziesz ją pisał.

Najlepszy sposób na optymalizację kodu programu

Aplikacja ma 71 200 użytkowników, dziennie 8 000 unikalnych użytkowników. Od zeszłego miesiąca kiedy wystartowała miała 880 000 odsłon. Dla porównania: to więcej niż miał Kominek w 2007 roku i 2,3 razy więcej niż ma Antyweb.

Dlaczego istnieje problem wydajności?

Problem wydajności aplikacji był spowodowany tym, że nie wszystkie polecenia były wykonywane na czas. Jeżeli założymy, że 400 osób używa jednocześnie aplikacji. Dla uproszczenia można przyjąć, że każda z nich wysyła w tym samym momencie prośbę do serwera o wyświetlenie strony aplikacji. Dopuszczalny w ekstremalnym wypadku czas czekania przez użytkownika na odpowiedź to powiedzmy 3 sekundy. 400 jednoczesnych requestów do serwera www musi być wykonanych w tym czasie. Oznacza to, że średnio request musi być zrealizowany w 3 / 400 sekundy czyli 8 milisekund.

Aplikację musiałem przedtem 2 czy 3 razy wycofać, ponieważ nie wytrzymywała obciążenia. Ale nie skończę tego tekstu na chwaleniu się, że udało mi się zoptymalizować serwer i aplikację pod takie obciążenie. Zamiast tego podzielę się z Wami konkretnymi optymalizacjami jakie zrobiłem, abyście mogli też je zastosować.

Czytaj podobne  Pokolenie informatyczne

Optymalizacja sprzętu

Aplikacja początkowo miała do dyspozycji całego VPS-a w postaci OpenVZ z 512 MB RAM-u i 30% procesora 800Mhz. Po pierwszej próbie kiedy serwer padł w peaku o 17.00 postanowiłem zapewnić większą moc i dałem aplikacji trochę na wyrost 100% procesora 2,6 Ghz i 2 GB RAM. Jednak samo wzmocnienie sprzętu jest niczym gdy aplikacja jest nieoptymalna. Dlatego nie poprzestałem na tym.

Optymalizacja bazy danych

Po pierwsze polecenie TOP (trywialne, ale od czegoś trzeba zacząć) pokazało, że proces mysqld zarzyna serwer. Okazało się, że zapytania które wykonywałem do bazy danych były ekstremalnie nieoptymalne. Do znalezienia ich przydał się slow query log. Listuje on najmniej wydajne zapytania do pliku tekstowego. Do optymalizacji przydało się polecenie explain. Główne optymalizacje polegały na odpowiednim stworzeniu indeksów w odpowiedzi na wyniki polecenia explain, które wskazało takie rzeźnickie praktyki jak „using filesort”.

Optymalizacja warstwy danych

Oprócz tego pozostała optymalizacja zapytań, ale tutaj roboty dużo nie było: przede wszystkim grupowanie po kolumnie występującej w tabeli użytej w left joinie okazało się bardzo nieoptymalne (1000 ms zmniejszone do 85 ms). Lepiej używać odpowiedniej kolumny w tabeli głównej.

Druga sprawa to filtrowanie danych określonej listy użytkowników. Wygląda na to, że lepiej listę użytkowników z API Grona umieścić w tabeli tymczasowej zamiast używać listy w zapytaniu w części select * from where in (1,2,3).

Optymalizacja dostępu do danych i wyników pośrednich

Obojętnie jak bardzo zoptymalizujemy bazę danych to nie wystarczy przy tej skali. Potrzebny jest zawsze kesz. W celu przechowywania wygenerowanych raz danych użyłem Memcached. Jest to system keszowania używany i polecany twórcom aplikacji przez Facebooka. Na pierwszym poziomie użyłem go do keszowania wyników zapytań SQL a na drugim do keszowania fragmentów i całych podstron które generowałem. Odciążyło to bazę danych na tyle, aby nie ubijała serwera. Teraz na przykład ściana Quizzów wyświetla się w 1,2 ms i używając 1 zapytania SQL. Zresztą nie jest ono też potrzebne – czas ten spadłby wtedy do ułamków milisekundy.

Czytaj podobne  Nowe CodeGuru - nareszcie!

Warto też przed optymalizacją znaleźć najczęściej odświeżane strony aplikacji i je optymalizować, ponieważ optymalizacja działów rzadko odwiedzanych nie jest opłacalna.

Optymalizacja ustawień serwera WWW i bazy danych

Następnie wprowadziłem optymalizacje ustawień mysql i php. Najważniejszą optymalizacją było włączenie Fast CGI w postaci mod_fastcgi. Nie znam się na Linuxie i nie wiem czy to standard, ale na moim VPSie był serwer lighttpd ale z normalnym cgi, które nie ma według mnie racji bytu. Odkrycie, że problem wydajności leżał w interpretacji php wynikło z takiej próby: zrobiłem prosty plik php zliczający czas jego wykonania a obok drugi plik ale html. Czas wyświetlenia pustego php był o wiele większy niż html-a. W powyższym linku jest przykład sprawdzenia jakie moduły php masz włączone w konsoli. Do tego samego posłużyć może też phpinfo.

Niektóre poradniki wykazują też, że lepiej użyć lighttpd, ngx albo apache (niepotrzebne skreślić). Jednak różnice wydajności są tak znikome nawet przy tej skali jaką mają Quizzy, że mogą jedynie być przedmiotem dyskusji akademickiej.

Do szukania bugów i złodziei czasu w PHP przydatne jest Xdebug i wizualna nakładka Webgrind. Pozwalają one zdiagnozować które miejsce w kodzie trwa najdłużej i najczęściej będą to odwołania do bazy danych albo do API serwisu społecznościowego. Warto przy okazji pamiętać o keszowaniu tych drugich też.

Jeżeli mowa o wizualizacji to przydatny jest też plik memcached.php z PECL-owej wersji Memcached, który jednak działa na każdej innej wersji memcached i pokazuje użycie pamięci (nieduże) i inne ciekawe statystyki.

Akceleracja PHP

Podobny zresztą wizualizator ma APC, czyli pakiet do keszowania kodu pośredniego PHP (opcode). Optymalizacja kodu pośredniego daje najlepsze efekty, kiedy aplikacja webowa ma wiele skryptów, które używa. Do tej grupy zaliczają się wszystkie CMS-y jak Drupal gdzie wydajność PHP wzrasta 3 razy. W przypadku małych aplikacji webowych z małą ilością plików i kodu takich spektakularnych efektów się nie uzyska. Oprócz APC istnieje też eAccelerator, ionCube, MMCache, Xcache i Zend Optymizer. Niestety nie udało mi się dobrze zainstalować eAcceleratora i Xcache, Zend Optimizer sprawiał też problemy. APC zaskoczył od razu. Wszystkie wymienione akceleratory PHP działają na tej samej zasadzie co ujawnia się w tym, że różnice w ich wydajności również nie są istotne przy skali aplikacji jaką są Quizzy.

Czytaj podobne  Matura z informatyki 2009

Podsumowanie

Po wszystkich optymalizacjach aplikacja i serwer działają bez przerwy od miesiąca i 2 tygodni. Nie zanotowałem żadnych problemów. Podsumowując nisko wiszące owoce optymalizacji to: indeksy, optymalizacja zapytań, memcached i fast cgi. Okazało się, że do takiej skali jaką mają Quizzy nie potrzeba wdrażać wszystkich technik z tej przeszło 100 slajdowej prezentacji. Na szczęście wbrew radom niektórych osób nie musiałem też zmieniać języka programowania. Okazało się, że PHP potrafi sobie radzić całkiem nieźle przy tej skali. Obecnie mój serwer większą część dnia śpi, czasem zużywając max. 5% mocy procesora. Niedługo jednak ten nadmiar zostanie odpowiednio spożytkowany.

Przeczytaj też

Najlepsza książka do Pythona Nie wiesz, z jakiej książki/ebooka uczyć się programowania w języku Python? Postanowiłem zrobić zestawienie 10 książek z Heliona na ten temat, abyś mó...
Komplet 28 ebooków i kursów, aby zostać programist... Od jakiegoś czasu dostaję zapytania na temat tego jakie książki, kursy i ebooki polecam. W związku z tym postanowiłem przygotować dzisiaj zestaw, któr...
120 tapet programistycznych za darmo do pobrania Trochę mi się nudziło, więc przygotowałem zestaw 120 tapet dla programistów. Możesz go pobrać. Tapety są w rozdzielczości 1366x768. Podzielone ...
10 fiszek do nauki programowania w Pythonie Uczysz się programowania w Pythonie? Pobierz te 10 fiszek, które ułatwią Ci zapamiętanie funkcji wbudowanych* w Pythona! Programowanie potrafi ...
Napisano w Kolumna Tagi: , , , , , , , ,
One comment on “Optymalizacja aplikacji społecznościowej na Facebook i Grono w praktyce
  1. syllepsa pisze:

    Ciekawy wpis. Mimo, iż nie używam PHP.

Menu