Uruchamianie crona w Ubuntu do czyszczenia pamięci dla sesji PHP zajmuje 25 minut, dlaczego?


13

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:

Wykres wykorzystania 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:

Czas IO

I operacje dyskowe:

Operacje na dysku

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? lsKatalogu sesji /var/lib/php5trwa 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 rmbędzie cholernie szybszy niż wydajność, którą widzę). Usunę użycie utrwalacza i zobaczę, co się stanie.


Ile ruchu generuje Twoja witryna, aby wygenerować tyle sesji?
Michael Hampton

Odpowiedzi:


9

Usunięcie fuserpowinno pomóc. To zadanie uruchamia fuserpolecenie (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 fuserrozwiąże problemu.


Wygląda na to, że błąd w utrwalaczu polegał na tym, że wcześniejsza wersja rozwidliła się, ale po zakończeniu nigdy nie została wykorzystana, pozostawiając tysiące fuserprocesó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.
thenickdude

To kolejny błąd. Masz prosty problem z uruchomieniem tysięcy fuserprocesów, z których wszystkie muszą przeszukać całość w /proc/poszukiwaniu otwartych plików.
Tometzky

9

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 fuserlub rmlub odkurzacz.

W tym miejscu polecam przyjrzeć się alternatywnym sposobom przechowywania sesji:

  • Jedną z opcji jest przechowywanie sesji wmemcached . To błyskawiczne, ale jeśli serwer ulegnie awarii lub zostanie ponownie uruchomiony, wszystkie sesje zostaną utracone i wszyscy zostaną wylogowani.
  • Możesz także przechowywać sesje w bazie danych. Byłoby to nieco wolniejsze niż memcached, ale baza danych byłaby trwała, a stare sesje można było wyczyścić za pomocą prostego zapytania SQL. Aby to zaimplementować, musisz napisać niestandardowy moduł obsługi sesji .

Memcached jest z pewnością opcją, chociaż musiałaby być oddzielną pulą od naszej głównej instancji memcached, w przeciwnym razie sesje byłyby losowo eksmitowane z naszego nacisku na pamięć podręczną. Nie jestem jednak przekonany, że usunięcie 14 000 plików powinno zająć 25 minut. To dla mnie brzmi zbyt wolno. Zaczekam kilka godzin i zobaczę, jak wygląda wykonanie prostej rm.
thenickdude

Nie wiedząc więcej o swojej ogólnej architekturze, waham się polecić jedną z drugiej.
Michael Hampton

Możesz połączyć serwery Memcached w celu uzyskania nadmiarowości, ustawiając memcache.session_redundancy = 2. Zobacz serverfault.com/questions/164350/… . Redis to dobra opcja, jeśli obawiasz się o trwałość i znacznie szybciej niż w bazach danych SQL.
jfountain

4

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 fuserzadania cron. Oto wykresy wydajności po powrocie do zadania cron Natty / Oneiric, które rmzamiast fuserprzycinać stare sesje, używa przełączania o 2:30.

użycie procesora

Upływający czas we / wy

Operacje na dysku

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:

09 *     * * *     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) -print0 \
   | xargs -n 200 -r -0 rm

-print0 | xargs ...nie jest konieczne - możesz po prostu -deletetam wyjść . Ale będzie działać w obie strony z porównywalną prędkością.
Tometzky

1

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.


0

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.