Normalerweise werden PHP-Skripte zur Laufzeit kompiliert. Das heißt, wenn jemand eine PHP-Seite wie WordPress aufruft, wird der PHP-Quelltext (die PHP-Datei) gelesen und vom PHP-Interpreter in sogenannten Bytecode (vorkompilierter Code) umgewandelt. Dieser Bytecode wird an eine virtuelle Maschine (die Zend Engine) übergeben, die daraus maschinenlesbaren Code erzeugt. Die Zend Engine stellt dabei eine einheitliche Laufzeitumgebung für verschiedene CPU-Architekturen und Betriebssysteme bereit.

Der Bytecode wird daraufhin verworfen und muss bei jedem Aufruf der Webseite neu generiert werden. Dies kostet Rechenzeit und verzögert den Aufruf der Webseite.

Durch die Nutzung von OPCache wird der Bytecode für die spätere Verwendung zwischengespeichert, so dass er nicht bei jedem Aufruf der Webseite neu erzeugt werden muss. Dies kann die Ladezeit von WordPress (oder anderen PHP-Projekten) spürbar beschleunigen.

Der Preis dafür ist, dass zum Zwischenspeichern des vorkompilierten Bytecodes RAM und/oder Festplattenspeicher benötigt wird. Außerdem werden (abhängig von der OPcache Knfiguration) Änderungen am PHP-Code unter Umständen nicht sofort sichtbar, da sich noch eine alte Version im Cache befindet.

OPcache aktivieren und konfigurieren

Um OPCache auf einem Ubuntu-Server zu nutzen, muss das Paket php7.2-opcache installiert werden. Anschließend kann der Cache über die php.ini aktiviert werden. Die php.ini befindet sich bei Ubuntu und der Verwendung von PHP als Apache-Modul unter /etc/php/7.2/apache2/php.ini. Bei Verwendung von PHP-FPM, beispielsweise mit NGINX, findet man die Konfigurationsdatei unter /etc/php/7.2/fpm/php.ini

In der php.ini scrollt man bis zum Abschnitt [opcache].

Um OPcache zu aktivieren muss die Zeile

;opcache.enable=0

abgeändert werden in

opcache.enable=1

Außerdem können und sollten weitere Einstellungen vorgenommen werden. In untenstehender Tabelle sind einige Option beschrieben, die ich für die wichtigsten halte.

OptionBedeutung
opcache.memory_consumption=256Die Menge an Speicherplatz die OPcache zur Verfügung steht, in Megabytes.
opcache.interned_strings_buffer=16Speicherplatz der für string interning zur Verfügung steht, ebenfalls in Megabytes.
opcache.max_accelerated_files=16229Die maximale Anzahl an Schlüsseln (und damit PHP-Skripte) die gespeichert werden können. Der Wert sollte größer als die Anzahl vorhandener Skripte sein. Der tatsächlich verwendete Wert wird aus einem festen Set aus Primzahlen gewählt (223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987). Es wird die Primzahl verwendet, die größer oder gleich dem gesetzten Wert ist. Gibt man beispielsweise als Wert 10000 an, werden tatsächlich 16229 Schlüssel gecached. Man kann also auch direkt eine der angegebenen Primzahlen als Wert setzen.
opcache.max_wasted_percentage=10Prozentsatz an verschwendetem Speicherplatz, der akzeptiert wird, becor der Cache komplett geleert wird. „Waste“ entsteht, wenn sich der Code ändert, während OPcache läuft. Der alte Cache-Eintrag wird dabei als „waste“ markiert.
opcache.validate_timestamps=1Legt fest, ob OPcache in regelmäßigen Abständen prüfen soll, ob sich der PHP-Code in einer Datei geändert hat. Wenn dies deaktiviert ist, muss nach jeder Änderung am Code (z.B. ein WordPress Update) ein Reset von OPcache durchgeführt werden, oder OPcache neu gestartet werden. Wer WordPress-Updates automatisch einspielen lässt, sollte die Option aktivieren. Wer die manuell macht, kann die Option deaktivieren und zusätzlich Rechenzeit sparen.
opcache.revalidate_freq=300Zeit in Sekunden, nach der überprüft wird ob sich der PHP-Code in einen Skript keändert hat. „0“ bedeutet, dass die Prüfung bei jedem Aufruf vorgenommen wird.
opcache.file_cache=/path/to/cacheOPcache kann Daten im Ram und/oder auf einem Datenträger speichern. Damit kann OPcache z.B. auch in Shared-Hosting Umgebungen genutzt werden. Auf dem eigenen Server hat die Nutzung dieser Option den Vorteil, dass bereits erzeugte Daten nach einem Neustart des Servers nicht verloren gehen. Das Verzeichnis muss vom PHP-Prozess beschrieben werden können.
opcache.file_cache_only=0Legt fest ob OPcache seine Daten nur auf dem Datenträger speichert (1) oder ob Daten im RAM und zusätzlich auf dem Datenträger gespeichert werden (0)

Wenn der Server von mehreren Benutzern verwendet wird, sind evtl. die Optionen opcache.validate_permission und opcache.validate_root von Bedeutung, die standardmäßig deaktiviert sind. Erstere prüft, ob der User überhaupt Leseberechtigung für das entsprechende Skript hat. Dies verhindert, dass zwischengespeicherte Daten an andere Benutzer geleaked werden. Zweitere verhindert Namenskollisionen bei verschiedenen chroot Umgebungen.

Damit Änderungen wirksam werden, muss Apache, bzw. PHP-FPM neu gestartet werden. Dabei wird außerdem der Cache geleert.

Überprüfen ob OPcache genutzt wird

Eine schöne Möglichkeit zum Steuern von OPcache und zum prüfen, ob OPcache überhaupt genutzt wird ist das Tool opcache-gui das auf Github zu finden ist. Es handelt sich dabei um ein PHP-Skript, das den verwendeten Speicherplatz, die Anzahl der zwischengespeicherten Skripte uvm. anzeigt. Da sich außerdem verschiedene Funktionen von OPcache steuern lassen, sollte man den Zugriff auf das Skript mit einem Passwort sichern.

Um opcache-gui zu nutzen, muss lediglich das PHP-File in den eigenen Webverzeichnis kopiert werden und über den Webbrowser aufgerufen werden.

Wer opcache-gui dauerhaft einsetzen will, der sollte den Zugang unbedingt mit einem Passwortschutz versehen.

OPcache Gui

1 Comment

  1. Anonymous

    Leider habe ich persönlich es mit opcache.file_cache nicht hinbekommen den OPcache vernünftig in einer Shared Hosting Umgebung ans Laufen zu bekommen.

    opcache_get_status wirft immer wirre Werte raus und es gibt unter PHP7.4 auch SEGFAULTS im error.log.