Ubuntu hat einen Cron-Job eingerichtet, der alte PHP-Sessions sucht und löscht:
# 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
Mein Problem ist, dass dieser Prozess sehr lange dauert, mit viel Festplatten-IO. Hier ist mein CPU-Nutzungsdiagramm:
Die Bereinigung wird durch die blaugrünen Spitzen dargestellt. Zu Beginn des Zeitraums wurden die Bereinigungsaufträge von PHP standardmäßig zu 09 und 39 Minuten geplant. Um 15:00 Uhr habe ich die 39-minütige Zeit von cron entfernt, sodass ein Reinigungsjob, der doppelt so groß ist, halb so häufig ausgeführt wird (Sie können sehen, dass die Spitzen doppelt so breit und halb so häufig werden).
Hier sind die entsprechenden Grafiken für die E / A-Zeit:
Und Plattenoperationen:
Auf dem Höhepunkt, an dem etwa 14.000 Sitzungen aktiv waren, wird die Bereinigung 25 Minuten lang ausgeführt, wobei anscheinend 100% eines Kerns der CPU und anscheinend 100% der Festplatten-E / A für den gesamten Zeitraum verwendet werden. Warum ist es so ressourcenintensiv? Ein ls
Teil des Sitzungsverzeichnisses /var/lib/php5
benötigt nur einen Bruchteil einer Sekunde. Warum dauert es dann ganze 25 Minuten, um alte Sitzungen zu kürzen? Kann ich irgendetwas tun, um dies zu beschleunigen?
Das Dateisystem für dieses Gerät ist derzeit ext4 und läuft unter Ubuntu Precise 12.04 64-Bit.
EDIT: Ich vermute, dass die Last auf den ungewöhnlichen Prozess "Fixiereinheit" zurückzuführen ist (da ich erwarte, dass ein einfacher rm
ein verdammter Anblick schneller ist als die Leistung, die ich sehe). Ich werde die Fixiereinheit entfernen und sehen, was passiert.
quelle
Antworten:
Das Entfernen von
fuser
sollte helfen. Dieser Job führtfuser
für jede gefundene Sitzungsdatei einen Befehl aus (prüfen Sie, ob eine Datei geöffnet ist) , was auf einem ausgelasteten System mit 14.000 Sitzungen leicht mehrere Minuten dauern kann. Dies war ein Debian-Fehler (Ubuntu basiert auf Debian).Anstelle von memcached können Sie auch versuchen, tmpfs (ein Dateisystem im Speicher) für Sitzungsdateien zu verwenden. Wie in memcached würde dies Sitzungen beim Neustart ungültig machen (dies kann umgangen werden, indem dieses Verzeichnis irgendwo im Shutdown-Skript gesichert und im Start-Skript wiederhergestellt wird), ist jedoch viel einfacher einzurichten. Aber es hilft nicht bei
fuser
Problemen.quelle
fuser
Prozessen in einem Zombie-Status Speicher verbrauchten, was zu einem Serverabsturz führte. Ich denke, das wurde bereits in der von mir verwendeten Version von psmisc behoben.fuser
Prozessen zu starten , die alle das Ganze/proc/
nach offenen Dateien durchsuchen müssen .Herzlichen Glückwunsch zu einer beliebten Website, die die ganze Zeit auf einer virtuellen Maschine ausgeführt werden kann.
Wenn Sie wirklich in zwei Millionen Seitenzugriffen pro Tag ziehen, dann werden Sie eine ganze Reihe von PHP - Sessions im Dateisystem stapeln, und sie werden eine lange Zeit in Anspruch nehmen , egal zu löschen , ob Sie verwenden
fuser
oderrm
oder Staubsauger.An dieser Stelle empfehle ich Ihnen, nach alternativen Möglichkeiten zum Speichern Ihrer Sitzungen zu suchen:
memcached
. Dies ist blitzschnell, aber wenn der Server abstürzt oder neu startet, gehen alle Ihre Sitzungen verloren und alle werden abgemeldet.quelle
rm
ist.Die von den Benutzern hier vorgeschlagenen Speicheroptionen für Memcached-Sitzungen und für Datenbanksitzungen sind daher eine gute Wahl, um die Leistung zu steigern, und haben jeweils ihre eigenen Vor- und Nachteile.
Beim Testen der Leistung stellte ich jedoch fest, dass die enormen Leistungskosten für diese Sitzungswartung fast ausschließlich auf die Anforderungen
fuser
im Cron-Job zurückzuführen sind. Hier sind die Leistungsdiagramme nach dem Zurücksetzen auf den Natty / Oneiric-Cron-Job, der verwendetrm
wirdfuser
, um alte Sitzungen zu kürzen. Die Umschaltung erfolgt um 2:30 Uhr.Sie können sehen, dass der durch die Bereinigung von Ubuntu-PHP-Sitzungen verursachte periodische Leistungsabfall fast vollständig beseitigt ist. Die im Diagramm "Datenträgervorgänge" gezeigten Spitzen sind jetzt viel kleiner und ungefähr so dünn, wie dieses Diagramm möglicherweise messen kann. Dies zeigt eine kleine, kurze Störung, bei der die Serverleistung zuvor 25 Minuten lang erheblich beeinträchtigt wurde. Die zusätzliche CPU-Auslastung entfällt vollständig. Dies ist jetzt ein IO-gebundener Job.
(Ein nicht verwandter E / A-Auftrag wird um 05:00 Uhr und ein CPU-Auftrag um 7:40 Uhr ausgeführt. Beide verursachen ihre eigenen Spitzen in diesen Diagrammen.)
Der geänderte Cron-Job, den ich jetzt ausführe, ist:
quelle
-print0 | xargs ...
ist nicht nötig - man könnte einfach dort abreisen-delete
. Aber es wird in beide Richtungen mit vergleichbarer Geschwindigkeit funktionieren.Ich bin auf diesen Beitrag gestoßen, als ich über Sitzungen recherchiert habe. Die akzeptierte Antwort ist zwar sehr gut (und der Fixier-Aufruf wurde für einige Zeit aus dem gc-Skript entfernt), aber ich denke, es lohnt sich, ein paar andere Überlegungen zu beachten, falls jemand anderes auf ein ähnliches Problem stößt.
In dem beschriebenen Szenario verwendete das OP ext4. Verzeichnisse in ext4 speichern Dateidaten in einem Htree-Datenbankformat - was bedeutet, dass das Speichern vieler Dateien in einem einzigen Verzeichnis nur geringfügige Auswirkungen hat, verglichen mit der Verteilung auf mehrere Verzeichnisse. Dies gilt nicht für alle Dateisysteme. Der Standard-Handler in PHP erlaubt es Ihnen, mehrere Unterverzeichnisse für Sitzungsdateien zu verwenden (beachten Sie jedoch, dass Sie überprüfen sollten, ob der Steuerungsprozess in diese Verzeichnisse rekursiert - der obige Cron-Job nicht).
Ein Großteil der Betriebskosten (nach dem Entfernen des Anrufs an die Fixiereinheit) entsteht durch das Betrachten von Dateien, die noch nicht veraltet sind. Die Verwendung (zum Beispiel) einer einzigen Ebene von Unterverzeichnissen und 16 Cron-Jobs, die in jedem Unterverzeichnis (0 /, 1 /, ... d /, e /, f /) suchen, glätten die auftretenden Belastungsstöße.
Die Verwendung eines benutzerdefinierten Session-Handlers mit einem schnelleren Substrat wird helfen - es gibt jedoch eine große Auswahl (Memcache, Redis, MySQL-Handler-Socket ...), wobei der Qualitätsbereich der im Internet veröffentlichten Sockets, den Sie auswählen, vom genauen Wert abhängt Anforderungen in Bezug auf Ihre Anwendung, Infrastruktur und Kenntnisse, nicht zu vergessen, dass es häufig Unterschiede im Umgang mit Semantik (insbesondere Sperren) im Vergleich zum Standard-Handler gibt.
quelle
Bei dieser Art von Datenverkehr sollten Sie keine Sitzungen auf ein Dis setzen. Sie sollten so etwas wie Memcache verwenden. Alles was Sie tun müssen, ist PHP einzurichten und es ist keine Codeänderung erforderlich. Siehe zum Beispiel
http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/
Der Grund, warum es so lange dauert, ist die riesige Menge an Dateien, die sortiert werden müssen, um zu sehen, welche gelöscht werden können. Memcache kann diese aufgrund der in Ihrem Code festgelegten Sitzungsdauer automatisch ablaufen lassen.
quelle