Ubuntu ma skonfigurowane zadanie cron, które wyszukuje i usuwa stare sesje PHP:
# Look for and purge old sessions every 30 minutes
09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] \
&& [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 \
-maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) ! -execdir \
fuser -s {} 2> /dev/null \; -delete
Mój problem polega na tym, że proces ten trwa bardzo długo, z dużą ilością operacji we / wy dysku. Oto wykres wykorzystania mojego procesora:
Przebieg czyszczenia jest reprezentowany przez kolce turkusowe. Na początku tego okresu zadania czyszczenia PHP były zaplanowane domyślnie 09 i 39 minut. O 15:00 usunąłem 39-minutowy czas z crona, więc zadanie czyszczenia dwa razy większe przebiega w połowie tak często (widać, że szczyty robią się dwa razy szersze, a połowa tak częste).
Oto odpowiednie wykresy dla czasu IO:
I operacje dyskowe:
W szczycie, w którym było aktywnych około 14 000 sesji, czyszczenie może trwać przez pełne 25 minut, najwyraźniej wykorzystując 100% jednego rdzenia procesora i co najwyżej 100% IO dysku przez cały okres. Dlaczego zajmuje tak dużo zasobów? ls
Katalogu sesji /var/lib/php5
trwa zaledwie ułamek sekundy. Dlaczego więc przycinanie starych sesji zajmuje całe 25 minut? Czy mogę coś zrobić, aby to przyspieszyć?
System plików dla tego urządzenia to obecnie ext4, działający na Ubuntu Precise 12.04 64-bit.
EDYCJA: Podejrzewam, że obciążenie jest spowodowane niezwykłym procesem „utrwalacza” (ponieważ spodziewam się, że prosty rm
będzie cholernie szybszy niż wydajność, którą widzę). Usunę użycie utrwalacza i zobaczę, co się stanie.
źródło
Odpowiedzi:
Usunięcie
fuser
powinno pomóc. To zadanie uruchamiafuser
polecenie (sprawdź, czy plik jest aktualnie otwarty) dla każdego znalezionego pliku sesji , co może zająć kilka minut w zajętym systemie z 14k sesjami. To był błąd Debiana (Ubuntu jest oparty na Debianie).Zamiast memcached możesz także spróbować użyć tmpfs (system plików w pamięci) dla plików sesji. Podobnie jak Memcached, spowoduje to unieważnienie sesji przy ponownym uruchomieniu komputera (można to obejść, wykonując kopię zapasową tego katalogu gdzieś w skrypcie zamykania i przywracając w skrypcie uruchamiania), ale będzie znacznie łatwiejsze do skonfigurowania. Ale to nie
fuser
rozwiąże problemu.źródło
fuser
procesów w stanie zombie zajmującym pamięć, co prowadzi do awarii serwera. Myślę, że zostało to już naprawione w używanej wersji psmisc.fuser
procesów, z których wszystkie muszą przeszukać całość w/proc/
poszukiwaniu otwartych plików.Gratulujemy posiadania popularnej strony internetowej i zarządzania nią przez cały ten czas na maszynie wirtualnej.
Jeśli naprawdę ciągnie w dwóch milionów odsłon dziennie, a potem idziesz do układania się wiele sesji PHP w systemie plików, a oni będą trwać długo, aby usunąć bez względu na to, czy używasz
fuser
lubrm
lub odkurzacz.W tym miejscu polecam przyjrzeć się alternatywnym sposobom przechowywania sesji:
memcached
. To błyskawiczne, ale jeśli serwer ulegnie awarii lub zostanie ponownie uruchomiony, wszystkie sesje zostaną utracone i wszyscy zostaną wylogowani.źródło
rm
.Tak więc sugerowane przez użytkowników opcje przechowywania sesji Memcached i bazy danych są dobrym wyborem, aby zwiększyć wydajność, z których każda ma swoje zalety i wady.
Ale dzięki testom wydajności odkryłem, że ogromne koszty wydajności związane z utrzymaniem tej sesji są prawie całkowicie związane z wezwaniem do
fuser
zadania cron. Oto wykresy wydajności po powrocie do zadania cron Natty / Oneiric, którerm
zamiastfuser
przycinać stare sesje, używa przełączania o 2:30.Widać, że okresowe obniżenie wydajności spowodowane czyszczeniem sesji PHP przez Ubuntu jest prawie całkowicie usunięte. Skoki pokazane na wykresie Operacje dyskowe są teraz znacznie mniejsze i mniej więcej tak chude, jak ten wykres może zmierzyć, pokazując małe, krótkie zakłócenia, w których wcześniej wydajność serwera była znacznie obniżona przez 25 minut. Dodatkowe zużycie procesora zostało całkowicie wyeliminowane, jest to teraz zadanie związane z operacjami we / wy.
(niepowiązane zadanie we / wy działa o 05:00, a zadanie procesora o 7:40, które powodują własne skoki na tych wykresach)
Zmodyfikowane zadanie crona, które teraz uruchamiam, to:
źródło
-print0 | xargs ...
nie jest konieczne - możesz po prostu-delete
tam wyjść . Ale będzie działać w obie strony z porównywalną prędkością.Zetknąłem się z tym postem podczas badań nad sesjami. Chociaż zaakceptowana odpowiedź jest bardzo dobra (a wywołanie utrwalacza zostało na jakiś czas usunięte ze skryptu gc), myślę, że warto zwrócić uwagę na kilka innych rozważań, jeśli ktokolwiek napotka podobny problem.
W opisanym scenariuszu PO korzystał z ext4. Katalogi w ext4 przechowują dane plików w formacie bazy danych htree - co oznacza, że utrzymywanie dużej liczby plików w jednym katalogu w niewielkim stopniu wpływa na ich dystrybucję w wielu katalogach. Nie dotyczy to wszystkich systemów plików. Domyślny moduł obsługi w PHP pozwala na użycie wielu podkatalogów dla plików sesji (należy jednak pamiętać, że powinieneś sprawdzić, czy proces kontrolny rekursuje w tych katalogach - powyższe zadanie cron nie).
Wiele kosztów operacji (po usunięciu wywołania utrwalacza) powstaje w wyniku przeglądania plików, które nie są jeszcze przestarzałe. Użycie (na przykład) jednego poziomu podkatalogów i 16 zadań cron w każdym podkatalogu (0 /, 1 /, ... d /, e /, f /) wygładzi powstałe obciążenia.
Użycie niestandardowego modułu obsługi sesji z szybszym podłożem pomoże - ale jest wiele do wyboru (memcache, redis, gniazdo modułu obsługi mysql ...), pomijając zakres jakości tych publikowanych w Internecie, który wybierzesz zależy od dokładnego wymagania dotyczące aplikacji, infrastruktury i umiejętności, nie zapominając, że często występują różnice w obsłudze semantyki (zwłaszcza blokowania) w porównaniu z domyślnym modułem obsługi.
źródło
Przy tego rodzaju ruchu nie powinieneś stawiać sesji na dysk. Powinieneś używać czegoś takiego jak memcache. Wszystko, co musisz zrobić, to skonfigurować php i nie będzie potrzeby zmiany kodu. Zobacz na przykład
http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/
Powodem, dla którego zajmuje to tak dużo czasu, jest ogromna liczba plików, które musi posortować, aby zobaczyć, które można usunąć. Pamięć podręczna może automatycznie wygasać, biorąc pod uwagę długość sesji ustawioną w kodzie.
źródło