Jak zbadać wyciek pamięci za pomocą Apache i PHP?

16

Prowadzimy ciężką stronę internetową Drupal, która wykonuje modelowanie finansowe. Wydaje się, że mamy do czynienia z pewnym wyciekiem pamięci, biorąc pod uwagę fakt, że z czasem pamięć używana przez apache rośnie, a liczba procesów apache pozostaje stabilna:

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Wiemy, że problem z pamięcią pochodzi z Apache / PHP, ponieważ za każdym razem, gdy wydajemy, /etc/init.d/httpd reloadzużycie pamięci spada (patrz powyższy zrzut ekranu i poniżej wyjścia CLI):

Przed httpd przeładuj

$ za darmo
             Łącznie wykorzystane wolne buforowane bufory współdzielone
Mem: 49447692 45926468 3521224 0 191100 22609728
- / + bufory / pamięć podręczna: 23125640 26322052
Zamiana: 2097144 536552 1560592

Po httpd przeładuj

$ za darmo
             Łącznie wykorzystane wolne buforowane bufory współdzielone
Mem: 49447692 28905752 20541940 0 191360 22598428
- / + bufory / pamięć podręczna: 6115964 43331728
Zamiana: 2097144 536552 1560592

Każdemu wątkowi Apache przypisany jest PHP o memory_limitwielkości 512 MB, co wyjaśnia, że ​​wysokie zużycie pamięci zmniejsza niską liczbę żądań, oraz max_execution_time120 sekund, które powinny zakończyć wątki, których wykonanie trwa dłużej, a zatem powinny zapobiec ciągłemu wzrostowi wykorzystania pamięci. widzenie.

P: Jak możemy zbadać, co powoduje wyciek pamięci?

Idealnie szukam kroków rozwiązywania problemów, które mogę wykonać w systemie bez przeszkadzania zespołowi programistów.

Dodatkowe informacje:

OS: RHEL 5.6
PHP: 5.3
Drupal: 6.x
MySQL: 5.6

Do Twojej wiadomości jesteśmy świadomi problemu wymiany, który badamy osobno i nie ma nic wspólnego z wyciekiem pamięci, który zaobserwowaliśmy przed rozpoczęciem wymiany.

Max
źródło
Ostatnim razem, gdy natrafiłem na poważny problem z użyciem pamięci w LAMP + Drupal, miałem wtedy używaną bibliotekę PHP z pamięcią podręczną. Po tym, jak go zabrałem, zużycie pamięci spadło bardzo gwałtownie. Tylko zgadnij. Może nieco później odpowiedzieć na pytanie.
Janne Pikkarainen,
@JannePikkarainen: korzystamy z memcachedbiblioteki PHP . Na podstawie strony administratora memcache memcache.phpwidzimy tylko, że przydzieliliśmy 5GBpamięć memcache, z której 3.3GBsię korzysta. Byłoby wspaniale, gdybyś mógł nam pomóc tutaj dalej.
Max
Tak, memcachedsam demon prawdopodobnie jest w porządku. Jest to biblioteka memcache PHP, która może, ale nie musi, przeciekać pamięć (i tym samym zwiększać wykorzystanie pamięci przez Apache). Mój problem pojawił się około 1-2 lata temu, więc potem wszystko mogło zostać naprawione. W każdym razie, jeśli memcached nie jest dla Ciebie obowiązkowy, spróbuj go na chwilę wyłączyć i sprawdź, czy użycie pamięci Apache nadal rośnie.
Janne Pikkarainen
Jaki jest rzeczywisty problem? Czy wydajność jest niska? Mówisz nam o symptomach, nie wyjaśniając, jaki problem powinniśmy pomóc ci rozwiązać. (A o czym jest ten problem z zamianą? Czy tak bardzo zmieniasz to, że wpływa to na wydajność?)
David Schwartz
@DavidSchwartz: problem polega na tym, że jeśli nie uruchomimy się ponownie httpd, użycie pamięci będzie rosło, a pudełko ostatecznie ulegnie awarii z niektórymi komunikatami o braku jądra pamięci. Wydajności są dobre (dopóki zużycie pamięci nie zbliża się do limitu pamięci). Zignoruj ​​problem z zamianą.
Maks.

Odpowiedzi:

11

Wiemy, że problem pamięci pochodzi z Apache / PHP, ponieważ za każdym razem, gdy wydajemy plik /etc/init.d/httpd, przeładowanie pamięci spada

Nie - to tylko oznacza, że ​​jest to związane z ruchem w sieci. Wspomniałeś, że uruchamiasz mysql na urządzeniu - prawdopodobnie zarządzającym danymi dla serwera - może być tutaj równie sprawcą. Podobnie jak inne usługi, z których korzysta twoja strona internetowa, o których nie wspomniałeś.

Każdy wątek apache ma przypisany limit pamięci 512 MB, co wyjaśnia

Nie, nie ma. Zgłaszasz średnio 7 i maksymalnie 25 zajętych serwerów - ale twój wykres pamięci pokazuje deltę około 25 Gb.

Naprawdę powinieneś zacząć od podstawowego strojenia HTTP - wydaje się, że masz stałe 256 httpds, ale twoje szczytowe użycie wynosi 25 - to jest po prostu głupie.

i max_execution_time 120 sekund, co powinno zakończyć wątki, których wykonanie trwa dłużej

Nie - tylko jeśli wątek wykonania znajduje się w interpreterie PHP - nie jeśli PHP jest zablokowane.

który wykonuje modelowanie finansowe

(westchnienie)

Byłoby pomocne, gdybyś podał szczegółowe informacje na temat konfiguracji Apache, wątków lub preforków, jakiej wersji, w jaki sposób wywoływane jest PHP (moduł, cgi, fastcgi), czy używasz trwałych połączeń, czy używasz procedur przechowywanych.

Sugeruję, aby zacząć od przeniesienia mysql na oddzielną maszynę i przestać używać trwałych połączeń (jeśli obecnie ich używasz). Ustaw limit pamięci znacznie niższy i zastąp to na podstawie skryptu. Upewnij się, że masz zainstalowany i skonfigurowany kolektor odniesienia do śmieci.

symcbean
źródło
2

Prawdopodobnie już rozwiązałeś swój problem. Tymczasowo, aby serwer nie zamieniał się / nie powodował przeładowania, co godzinę uruchamiam z crona następujące polecenie:

#!/bin/sh 
sync; echo 3 > /proc/sys/vm/drop_caches

Nie twierdzę, że jest to rozwiązanie, tylko sposób na utrzymanie działania i zminimalizowanie downtimw podczas badania faktycznej przyczyny wycieku pamięci.

Więcej informacji można znaleźć tutaj.

http://www.tecmint.com/clear-ram-memory-cache-buffer-and-swap-space-on-linux/

Patrick
źródło
1

Najwyraźniej tak działa PHP - a jeśli robisz długie pętle, w których przydzielasz obiekty i kto wie, czy przekazujesz je również przez referencję, więc jedynym sposobem na poradzenie sobie z tym jest po N żądaniach dla każdego procesu PHP zatrzymać to. Jeśli używasz PHP jako CGI, każde żądanie powoduje jego odrodzenie - więc nie ma wycieku pamięci, a spadek wydajności może nie być tak duży. Możesz także uruchomić fast-cgi, gdzie np. Każde 1000 żądań proces php-fcgi zostaje zabity, a jego pamięć zwolniona - ponownie nie ma wycieku pamięci. Jeśli uruchamiasz PHP jako moduł mod_php, możesz spróbować ustawić maxrequests w httpd.conf, aby sprawdzić, czy to pomoże. Spróbowałbym skonfigurować np. 10 - jeśli to zadziała, spadek wydajności nie będzie wysoki, ale nie powinno być przecieków pamięci,

Andrew Smith
źródło
-1

Sprawdź pamięć w globalnym pliku php.ini. nie po prostu dekalre valure jak 1 G itp. Gorąco polecam, aby lokalny plik php.ini został uwzględniony na tym koncie, aby nie wpływał na cały serwer. Polecam ustawienie globalnego limitu php.ini na około 64 mln, ponieważ zwykle wystarcza to na większości kont

sprawdź też ustawienia apache

Nikhil Babu
źródło