[PHP] hohe sys-cpu-Last durch lstat(2)
Seit geraumer Zeit hat mich bereits der Zustand gestört, dass unsere PHP-Webserver eine extrem hohe System-CPU-Last aufweisen. Wenn die CPU 40% der Zeit mit der Abarbeitung der PHP-Scripte beschäftigt ist (usr%), dann steht die sys%-Anzeige ebenfalls bei 35-40%. Nach zahlreichen Vermutungen und einigen Spielereien mit oprofile und sysprof kam Ingo heute mit der Idee, einfach den PHP-Prozess per strace zu beobachten.
Heraus kam, dass der Großteil der Systemaufrufe aus lstat(2) besteht. Pro Request waren das gute 15.000 Aufrufe, die insgesamt 0,8 Sekunden gedauert haben (von ~5 Sekunden gesamt). Der Blog-Artikel von Nir Levy brachte mich dann auf die PHP-Konfigurationseinstellung realpath_cache_size, aber leider brachte auch das keine Linderung. PHP führte immernoch unzählige lstat-Aufrufe für immer die gleichen Verzeichnisse aus.
Letztendlich fand sich open_basedir als Schuldiger. Wenn open_basedir oder safe_mode in Verwendung sind, wird der realpath-cache komplett deaktiviert. Nachdem open_basedir aus der Konfiguration rausgeflogen war, sank die sys-cpu-Last von 40% auf angenehme 10% und es waren noch ganze 5 (!!!) lstat()-Aufrufe im trace.log vorhanden. Das heißt, wir müssen uns um weitere Webserver erstmal keine Gedanken machen. 😉
[…] die nächste gute Nachricht: Uwe und Ingo haben ein nerviges PHP-Performanceproblem eingrenzen und beheben können. Great job, […]