Zoptymalizuj apache / php / mysql działający na VPS pod kątem dużego obciążenia

17

Pytanie o optymalizację serwera apache / mysql na VPS z 512m pamięci RAM. Pod normalnym obciążeniem wszystko działa szybko, bez opóźnień połączenia. Jednak gdy otrzymujemy dni o dużym natężeniu ruchu (ponad 50 000 odwiedzin), strona indeksuje się i odzyskiwanie zawartości z apache zajmuje ponad 30 sekund.

Strona działa na Expression Engine (CMS) (w PHP) i postępowałem zgodnie z ich przewodnikiem optymalizacji obciążenia. Poszukałem go i śledziłem kilku z apaszem przy odrobinie szczęścia, docierając tam, gdzie jest teraz, ale muszę mieć stały czas reakcji.

Zakładam, że różni się to od pytania „zoptymalizuj pod kątem małej pamięci” tutaj, ponieważ mam wystarczającą ilość pamięci RAM (do tego, co próbuję zrobić), po prostu muszę sprawić, aby serwer nie dusił się pod dużym obciążeniem.

Jakieś rekomendacje?

Papugi
źródło
1
Po prostu kontynuacja - zmiana na Lighttpd i już różnica jest niesamowita, znacznie lepiej radząc sobie z ładunkiem. Jestem pewien, że pojawią się kolejne optymalizacje, ale to bardzo pomogło. I użyłem eakceleratora, który wybrałem w stosunku do APC, ponieważ został o to poproszony.
Papugi

Odpowiedzi:

18

W przypadku PHP istnieją 2 ważne rzeczy, które zwiększą pojemność:

  1. Advanced PHP Caching (APC), jak wspomniano. Tego używamy w Yahoo !. Istnieją inne podobne projekty, ale ten jest dzieckiem Rasmusa.
  2. FastCGI zamiast mod_php. Trwa debata na ten temat, ponieważ mod_php jest zwykle najszybszy. Zakładam jednak, że masz jeden serwer Apache dostarczający zarówno dynamiczną zawartość PHP, jak i zasoby statyczne (JS, CSS, flash, obrazy, pliki PDF itp.). Żądania dotyczące tych zasobów statycznych nie muszą zajmować tak dużo pamięci, ale ponieważ PHP jest modułem, znajduje się w każdym wątku Apache.

W przypadku Apache:

  1. Użyj MPM pracownika
  2. Włącz KeepAlive

Możesz także posunąć się do rozważenia przejścia z Apache na Lighttpd lub Nginx . Uwielbiam Apache. Używam głupca z wielu jego zaawansowanych funkcji. Akceptuję jego koszty ogólne, ponieważ potrzebuję tego, co oferuje. W przypadku zwykłego stosu LAMP jest to więcej niż potrzeba i marnowanie zasobów.

W przypadku MySQL:

  1. Twoje wysiłki związane z optymalizacją zwrócą się 10-krotnie, gdy wydasz je na analizę i poprawianie zapytań, zamiast ulepszania wartości my.cnf. Nie twierdzę, że poprawne buforowanie, połączenia itp. Nie są ważne ... ale dla większości ludzi jest to tylko 9% problemu.
  2. Podczas kontroli jakości włącz ogólny dziennik zapytań na pomostowym / dev mysqld, aby przechwycić wszystkie wysłane zapytania. (NIE rób tego na produkcyjnym serwerze mysql!)
  3. Użyj EXPLAIN do analizy zapytań. Zwłaszcza jeśli używasz frameworka z ORM (abstrakcji DB i powstrzymuje Cię przed pisaniem własnego SQL), będziesz musiał wyczyścić zbędne JOIN, SELECT bez klauzuli WHERE, ORDER BYs, które wywołują „using fileort”, i zapytania które nie używają indeksów.
  4. Jeśli używasz MySQL 5.1, skorzystaj z profilera zapytań .

Inne narzędzia warte rozważenia to mk-visual-wyjaśnianie

Przywołałem 10 świetnych referencji. Te rzeczy powinny cię nucić. Daj nam znać, jak to się potoczy.

Bruno Bronosky
źródło
6

Przenieś pliki sesji PHP do tmpfs , użyj APC (lub innego) i usuń wszystkie niepotrzebne moduły PHP. Usuń wszystkie moduły Apache, których nie potrzebujesz / których używasz.

Aby utworzyć tmpfs (katalog w pamięci RAM!)

mkdir /tmpfs; chmod 777 /tmpfs
mount -t tmpfs -o size=256M tmpfs /tmpfs

W / etc / fstab dodaj poniższy wiersz, aby utworzyć go przy ponownym uruchomieniu!

tmpfs     /tmpfs    tmpfs   size=256m,mode=0777    0       0

W /etc/apache2/php.ini dostosuj, aby przechowywać sesje w pamięci RAM (tmpfs)!

session.save_handler = files
session.save_path = "/tmpfs"

Uwaga: Z plikami PHP ORAZ plikami sesji w pamięci RAM ledwo dotykasz dysku!

Używaj expires_module w apache, aby przeglądarki mogły buforować większość rzeczy.

ExpiresActive On
ExpiresDefault "access plus 90 days"
ExpiresByType image/gif "access plus 90 days"
ExpiresByType image/ico "access plus 90 days"
ExpiresByType image/png "access plus 90 days"
ExpiresByType image/jpeg "access plus 90 days"
ExpiresByType image/x-icon "access plus 90 days"
ExpiresByType text/css "Access plus 90 days"
ExpiresByType text/html "Access plus 90 days"
ExpiresByType application/x-shockwave-flash "Access plus 90 days"
ExpiresByType application/x-javascript "Access plus 90 days"

Nie używaj plików .htaccess ! Zamiast tego koduj je na stałe w pliku konfiguracyjnym vhost! Drastycznie wyeliminuje / ograniczy kontrole dysku dla wszystkich żądań HTTP ... naprawdę się sumuje.

Options FollowSymLinks 
AllowOverride None

Przykład pliku .htaccess zastosowanego w pliku vhost.conf ...

<Directory /home/user/www/site.com/secure>
    Order Allow,Deny
    Deny from All
</Directory>
Nulled
źródło
5

Przychodzi mi na myśl kilka rzeczy.

Pamięć podręczna kodów operacyjnych jest zawsze dobrym pomysłem. Wolę http://eaccelerator.net/ niż APC. Jeśli po drodze nie rozwijałeś się z APC, próba dodania go jest prawie zawsze bolesna. Eaccelerator, choć nie jest tak fantazyjny, po prostu wydaje się działać.

Odwrotny serwer proxy jest również dobrym pomysłem, ale musisz obserwować użycie pamięci RAM. Uważam, że Apache 2.2 z mpm-worker sam zajmuje dość dużo pamięci RAM. W twoim przypadku poleciłbym coś lżejszego jak Nginx i uruchom Apache z PHP jako FASTCGI lub po prostu zostaw to zgodnie z procesem. Pomysł korzystania z Varnish, Squid, Nginx itp. Polega na tym, aby serwery obsługiwały zawartość statyczną, zajmowały się połączeniami użytkowników i przekazywały tylko żądania PHP do Apache, który traktujesz jak serwer aplikacji.

Jeśli używasz dość nowej wersji Mysql 5.1, takiej jak co najmniej 5.1.24, masz teraz dostęp do wolniejszych dzienników poniżej drugiej sekundy. Chciałbym zacząć long_query_time od 1 lub 2, a następnie obniżyć go do 0,5, gdy opanujesz naprawdę długie. Istnieje również wiele ogólnych informacji o tuningu w sieci dla Mysql, ale nie masz pamięci RAM, aby zrobić wiele. Czy zwiększyłeś którekolwiek z ustawień od domyślnych? Większość domyślnych plików my.cnf jest skonfigurowanych do korzystania z około 64 MB pamięci RAM. Przynajmniej zwiększyłem key_buffer z 16 MB do 64 MB.

Dodatkowo używasz tabel Myisam lub Innodb? Jeśli trzymasz sesję w DB, będziesz chciał zmienić tabelę sesji na Innodb (lub zamiast tego zrobić ciasteczko) zamiast pozostawić tabelę Mysiam, która blokuje na poziomie tabeli, a nie na poziomie wiersza. Zasadniczo każda tabela, która zawiera więcej niż 20% zapisu do 80% odczytów, jest kandydatem do przejścia na Innodb. Pamiętaj, że musisz zrównoważyć ilość pamięci RAM między tabelami Myisam i tabelami Innodb, ponieważ bufory dla każdej są konfigurowane osobno.

I wreszcie kolejne 512 MB pamięci RAM przejdzie długą drogę w konfiguracji, a nawet kolejne 512 MB VPS do uruchomienia MySQL, jeśli jest to tańsze lub w przybliżeniu taka sama cena. Skłoniłbym się ku drugiej instancji, ponieważ podwoi to dostępne we / wy dysku. Jednym z problemów z serwerami VPS jest to, że Twoje IO nie jest chronione przed innymi osobami na tym samym serwerze fizycznym.

Hmmm mój post jest trochę rozproszony, ale daje ci wiele miejsc do obejrzenia. Powodzenia.

kashani
źródło
2
  • Użyj pamięci podręcznej opcode dla php, takich jak apc.
  • Użyj akceleratora http, takiego jak kałamarnica lub lakier.
wittwerch
źródło
1

W sytuacji niskiego poziomu pamięci (512 Mb jest niski, w przypadku serwera o dużym natężeniu ruchu) warto rozważyć wybór serwera WWW i silnika DB.

Lighttp jest po wyjęciu z pudełka lżejszy niż Apache zwykle można zrobić po wielu udoskonaleniach, a są nawet lżejsze opcje. Nie jest to oczywiście możliwe, jeśli istnieją funkcje Apache, od których zależy, które nie są obsługiwane na innych serwerach.

sqlite jest znacznie ciaśniejszy niż mySQL i szybszy również w wielu warunkach. Sprawdź, czy silnik, którego używasz, obsługuje to, a także czy daje szansę.

Inną opcją, łatwą opcją, jest uzyskanie większej ilości pamięci RAM w maszynie wirtualnej, jeśli możesz sobie na to pozwolić.

David Spillett
źródło
1

Poza świetnymi sugestiami, należy zauważyć, że wszystkie VPS nie są sobie równe. Z mojego doświadczenia wynika, że ​​PHP jest obciążone procesorem.

Benchmark Wordpress AB (ab-n 500-c 25 http://domain.com/index.php ) z nginx / apc / phpfpm / mysql (lokalny) na EC2 spowodował ~ 2 żądania / sekundę na poziomie podstawowym „2GB RAM / 1 Compute Unit Server ”.

Ten sam test porównawczy uruchomiony na tym samym dokładnym stosie (wdrożony przez skrypt w identycznym systemie operacyjnym) na 512 MB Rackspace Cloudserver zwraca ~ 80 req / sekundę. Więc 4x mniej pamięci RAM, 40x wydajność w tym podstawowym eksperymencie.

Oglądając górę podczas AB widzisz, że EC2 po prostu nie mógł poradzić sobie z współbieżnością i natychmiast uderzyłby w 100% obciążenie procesora i blokował się. Oglądając górę na 512 MB serwerze (zwirtualizowany czterordzeniowy procesor) podczas tego samego testu, rdzenie osiągnęłyby ~ 60% obciążenia i płynnie obsługiwałyby test.

VPS są niezwykle łatwe do uruchomienia i wyłączenia bez żadnych zobowiązań, testowanie infrastruktury, w której znajduje się VM / VPS, nie jest bolesne!

EDYCJA 1: Również mała instancja EC2 „High CPU” była w stanie dać ~ 10 / req sekundę, przy czym procesor nadal stanowił wąskie gardło. Doszedłem do wniosku, że poświęcasz wydajność dla stabilności / solidności z EC2, i oczywiście istnieje wiele przypadków użycia, które wymagają takiego środowiska.

iainlbc
źródło
rozważ także nginx (v.1 wydany dzisiaj). wordpress.com zamienił swoją konfigurację litespeed z nginx, więc jest to oczywiście sprawny serwer WWW.
iainlbc,
Nginx jest naprawdę imponujący. Chciałbym tylko, żeby mógł odczytać reguły mod_rewrite z plików .htaccess.
Martijn Heemels