OPcache Dateisystem-Ueberlegungen unter Linux
AI generated
$
/etc
Linux · OPcache · PHP · Magento
OPcache Dateisystem-Ueberlegungen unter Linux
Warum der Storage-Layer ueber die Cache-Wirkung entscheidet

OPcache wird meist ausschliesslich als PHP-Konfiguration betrachtet, dabei haengt seine Wirksamkeit direkt vom darunterliegenden Linux-Dateisystem ab. Inode-Verhalten, Mount-Optionen und Netzwerk-Dateisysteme wie NFS koennen dieselbe OPcache-Konfiguration auf einem Server zuverlaessig und auf einem anderen unbrauchbar machen.

17 Min. Lesezeit validate_timestamps · Inodes · NFS · tmpfs PHP 8.x · Linux · Magento 2

1. Warum OPcache mehr als eine PHP-Einstellung ist

OPcache speichert kompilierten PHP-Bytecode im Shared Memory, damit der Zend-Compiler bei jedem Request nicht erneut alle PHP-Dateien parsen muss. Diese Beschreibung stimmt, verschweigt aber, dass OPcache staendig mit dem Linux-Dateisystem interagiert, um zu entscheiden, ob eine gecachte Datei noch aktuell ist. Genau an dieser Stelle entstehen die meisten Performance-Probleme, die faelschlich als PHP-Problem eingeordnet werden, obwohl die eigentliche Ursache im Storage-Layer liegt.

Jede Interaktion mit dem OPcache Dateisystem-Verhalten kostet Zeit, und diese Zeit unterscheidet sich massiv zwischen einem lokalen NVMe-Mount, einem Netzwerk-Dateisystem und einem containerisierten Overlay-Filesystem. Auf einem Magento-Server mit tausenden PHP-Dateien im Vendor-Verzeichnis summieren sich selbst kleine Latenzen pro Datei zu spuerbaren Verzoegerungen, wenn die falsche Kombination aus OPcache-Konfiguration und Dateisystem gewaehlt wird.

Dieser Artikel geht gezielt auf die OPcache Dateisystem-Wechselwirkungen ein, die in Standard-Tutorials meist fehlen: die Kosten von validate_timestamps, das Verhalten bei Symlink-basierten Deployments, die Fallstricke von NFS und die Moeglichkeit, den sekundaeren File-Cache gezielt auf schnellerem Storage abzulegen.

2. validate_timestamps und die Kosten von stat()

Mit opcache.validate_timestamps = 1 prueft PHP bei jedem Request, ob sich eine Datei seit dem letzten Caching-Vorgang geaendert hat. Diese Pruefung erfolgt ueber einen stat()-Systemaufruf, der die Modifikationszeit aus den Metadaten des Dateisystems liest. Auf einem lokalen ext4- oder XFS-Dateisystem mit warmem Page-Cache kostet dieser Aufruf nur Mikrosekunden, auf einem langsamen oder ueberlasteten Storage-Backend kann sich diese Zeit deutlich verlaengern, insbesondere bei den mehreren tausend Dateien, die Magento pro Request potenziell einbindet.

Das Intervall der Pruefung wird zusaetzlich mit opcache.revalidate_freq gesteuert, das angibt, wie viele Sekunden zwischen zwei Timestamp-Checks fuer dieselbe Datei mindestens vergehen muessen. Fuer produktive Magento-Server, bei denen Deployments ueber einen kontrollierten Prozess laufen und nicht durch direktes Bearbeiten von Dateien im laufenden Betrieb, ist opcache.validate_timestamps = 0 die deutlich performantere Wahl. Dabei entfaellt jeder stat()-Aufruf komplett, und ein manueller Cache-Reset nach dem Deployment ersetzt die automatische Pruefung.


; /etc/php/8.3/fpm/conf.d/10-opcache.ini
; Production setting: skip stat() calls entirely on the filesystem
opcache.enable = 1
opcache.validate_timestamps = 0
opcache.revalidate_freq = 0

; Staging/dev setting: check timestamps every 2 seconds per file
; opcache.validate_timestamps = 1
; opcache.revalidate_freq = 2

3. Inode-basierte Invalidierung und Symlink-Deployments

OPcache identifiziert gecachte Dateien nicht nur ueber den Pfad, sondern intern auch ueber die Inode-Nummer der Datei im OPcache Dateisystem-Kontext. Das wird relevant bei Deployment-Strategien, die mit atomaren Symlink-Wechseln arbeiten, ein verbreitetes Muster bei Capistrano-artigen Deployments, bei dem jeder Release-Ordner eine neue physische Kopie des Codes erhaelt und ein Symlink current danach umgebogen wird.

Da jede neue Release-Kopie neue Inodes erzeugt, auch wenn der Dateiinhalt identisch bleibt, erkennt OPcache bei aktivem validate_timestamps die neue Version zuverlaessig. Bei deaktiviertem validate_timestamps jedoch, was fuer maximale Performance ja gerade empfohlen wird, muss der OPcache-Speicher nach jedem Symlink-Wechsel aktiv geleert werden, sonst liefert PHP-FPM weiterhin den Bytecode des alten Release-Verzeichnisses aus, obwohl der Symlink bereits auf den neuen Pfad zeigt.


#!/usr/bin/env bash
# deploy-with-opcache-reset.sh — atomic symlink swap plus OPcache invalidation
set -euo pipefail

RELEASE_DIR="/var/www/magento/releases/$(date +%Y%m%d%H%M%S)"
CURRENT_LINK="/var/www/magento/current"

echo "[DEPLOY] Extracting new release to $RELEASE_DIR"
mkdir -p "$RELEASE_DIR"
tar -xzf /tmp/release.tar.gz -C "$RELEASE_DIR"

echo "[DEPLOY] Swapping symlink atomically"
ln -sfn "$RELEASE_DIR" "$CURRENT_LINK"

# Critical: new inodes are invisible to a warm OPcache with
# validate_timestamps=0 until workers are recycled or reset explicitly.
echo "[DEPLOY] Resetting OPcache via FPM reload"
systemctl reload php8.3-fpm

echo "[DEPLOY] Done — release live at $RELEASE_DIR"

4. NFS und andere Netzwerk-Dateisysteme

Wird der Magento-Code-Ordner ueber NFS zwischen mehreren Applikationsservern geteilt, entstehen zusaetzliche OPcache Dateisystem-Fallstricke, die auf lokalem Storage nicht existieren. Jeder Server pflegt seinen eigenen OPcache im lokalen Shared Memory, ohne Kenntnis davon, was auf den anderen Servern im Cache liegt. Aendert sich eine Datei auf dem NFS-Share, sehen die Server das nur, wenn ihr eigener validate_timestamps-Check die Aenderung erkennt, was bei deaktivierter Pruefung eben gerade nicht passiert.

Ein zweites, subtileres Problem: NFS cacht Metadaten clientseitig fuer eine gewisse Zeit, gesteuert ueber Mount-Optionen wie actimeo. Selbst mit aktivem opcache.validate_timestamps kann ein stat()-Aufruf auf einem NFS-Mount veraltete Metadaten zurueckliefern, weil der NFS-Client die tatsaechliche Anfrage an den Server gar nicht stellt, sondern seinen lokalen Metadaten-Cache bedient. Fuer Multi-Server-Setups mit gemeinsamem Code-Verzeichnis ist deshalb ein zentraler, koordinierter Deployment-Prozess mit explizitem OPcache-Reset auf allen Knoten Pflicht, ein einfaches touch auf eine Datei reicht bei NFS nicht zuverlaessig aus.


#!/usr/bin/env bash
# reset-opcache-cluster.sh — invalidate OPcache on all app servers after
# a shared NFS deployment, since local stat() caching hides changes
set -euo pipefail

declare -a APP_SERVERS=("app1.internal" "app2.internal" "app3.internal")

for host in "${APP_SERVERS[@]}"; do
  echo "[RESET] Reloading PHP-FPM on $host"
  ssh -o BatchMode=yes "deploy@${host}" "sudo systemctl reload php8.3-fpm"
done

echo "[RESET] OPcache invalidated on all ${#APP_SERVERS[@]} nodes"

5. opcache.file_cache auf tmpfs auslagern

Neben dem Shared-Memory-Cache bietet OPcache mit opcache.file_cache einen sekundaeren, dateibasierten Cache, der kompilierten Bytecode auch ueber einen PHP-FPM-Neustart hinweg erhaelt. Ohne diese Option muss nach jedem Neustart der komplette Bytecode neu kompiliert werden, was bei einem grossen Magento-Codebase mehrere Sekunden zusaetzliche Zeit fuer die ersten Requests nach dem Neustart bedeutet, waehrend der Shared-Memory-Cache noch leer ist.

Der Speicherort dieses File-Cache ist eine direkte OPcache Dateisystem-Entscheidung. Liegt opcache.file_cache auf einer langsamen Festplatte, verlangsamt sich das Aufwaermen nach einem Neustart entsprechend. Ein tmpfs-Mount, also ein RAM-basiertes Dateisystem, das ueber /etc/fstab eingerichtet wird, liefert deutlich schnellere Lese- und Schreibzugriffe fuer diesen sekundaeren Cache, mit dem Kompromiss, dass der Inhalt bei einem Server-Neustart komplett verloren geht und einmalig neu aufgebaut werden muss.


; /etc/php/8.3/fpm/conf.d/10-opcache.ini
; Secondary file-based cache survives php-fpm restarts (not server reboots)
opcache.file_cache = /var/cache/opcache-file
opcache.file_cache_only = 0
opcache.file_cache_consistency_checks = 1

# /etc/fstab — mount opcache file_cache directory on tmpfs (RAM-backed)
tmpfs /var/cache/opcache-file tmpfs rw,size=512M,mode=0755,uid=www-data,gid=www-data 0 0

# Apply without reboot:
# mkdir -p /var/cache/opcache-file
# mount /var/cache/opcache-file

6. Deployment-Strategien ohne Cache-Bruch

Die stabilste OPcache Dateisystem-Strategie fuer Magento kombiniert drei Elemente: validate_timestamps = 0 fuer maximale Performance im laufenden Betrieb, ein kontrollierter Deployment-Prozess mit explizitem systemctl reload nach jedem Symlink-Wechsel und ein sekundaerer File-Cache auf schnellem Storage fuer kurze Aufwaermzeiten nach geplanten Neustarts. Diese Kombination vermeidet sowohl die Performance-Kosten von staendigen stat()-Aufrufen als auch das Risiko, veralteten Bytecode auszuliefern.

Fuer Blue-Green-Deployments oder Canary-Releases, bei denen zwei Codeversionen gleichzeitig unter verschiedenen Pfaden existieren, muss zusaetzlich sichergestellt werden, dass jeder PHP-FPM-Pool exklusiv einer Codeversion zugeordnet ist. Teilen sich mehrere Codeversionen denselben PHP-FPM-Pool, mischt der Shared-Memory-Cache Bytecode-Eintraege unterschiedlicher Releases, was zu inkonsistentem Verhalten fuehren kann, wenn Klassen oder Funktionen zwischen den Versionen unterschiedlich definiert sind.

7. OPcache-Status pro Filesystem ueberwachen

Die Funktion opcache_get_status() liefert unter anderem die Anzahl der Cache-Treffer, Cache-Fehlschlaege und die aktuelle Speicherauslastung. Ein hoher Anteil an Cache-Fehlschlaegen (misses im Verhaeltnis zu hits) deutet meist darauf hin, dass der OPcache-Speicher zu klein dimensioniert ist oder dass staendige Invalidierungen durch das OPcache Dateisystem-Verhalten stattfinden, zum Beispiel durch ein zu kurzes revalidate_freq in Kombination mit einem langsamen Storage-Backend.

Ein einfaches Monitoring-Skript, das periodisch opcache_get_status() ueber ein internes Diagnose-Endpoint abfragt, macht sichtbar, ob opcache.memory_consumption ausreichend dimensioniert ist. Steigt die Anzahl der "Restarts" durch vollen Speicher regelmaessig an, muss entweder der zugewiesene Speicher erhoeht oder opcache.max_accelerated_files an die tatsaechliche Dateianzahl im Vendor-Verzeichnis angepasst werden.

8. Typische Fehler bei OPcache und Dateisystemen

Der haeufigste Fehler ist, validate_timestamps in der Produktion auf 1 zu belassen, aus Sorge, ein deaktivierter Timestamp-Check koennte zu Problemen fuehren. Dabei bringt genau dieser staendige Check auf einem stark frequentierten Magento-Server mit tausenden PHP-Dateien einen messbaren Overhead, ohne in einem kontrollierten Deployment-Prozess irgendeinen Mehrwert zu liefern, weil Dateien im laufenden Betrieb ohnehin nicht direkt bearbeitet werden sollten.

Der zweite haeufige Fehler betrifft Multi-Server-Setups: Nach einem Deployment wird nur der zuletzt aktualisierte Server neu geladen, waehrend die anderen Knoten im Cluster weiterhin alten Bytecode aus ihrem lokalen Shared-Memory-Cache ausliefern. Ohne einen zentralen Deployment-Schritt, der auf allen Applikationsservern gleichzeitig systemctl reload ausloest, entstehen inkonsistente Antworten je nachdem, welcher Server einen Request bedient, ein Fehlerbild, das oft erst nach laengerer Fehlersuche als OPcache-Problem erkannt wird.

9. Dateisystem-Optionen im Vergleich

Die Wahl des Dateisystems und der Mount-Optionen fuer den Magento-Codebase hat direkten Einfluss auf die OPcache Dateisystem-Performance, insbesondere in der Aufwaermphase und bei der Invalidierung.

Setup stat()-Latenz Multi-Server-Konsistenz Empfehlung
Lokal ext4/XFS Sehr niedrig Pro Server unabhaengig, Reload noetig Standard fuer Single-Server
NFS-Share Hoch, Metadaten-Cache verzoegert Erfordert koordinierten Reset Nur mit zentralem Deploy-Skript
tmpfs fuer file_cache Minimal, RAM-basiert Pro Server, Inhalt bei Reboot weg Fuer schnelles Aufwaermen nach Neustart
Overlay-FS (Container) Variabel, abhaengig vom Storage-Driver Pro Container isoliert memory_consumption grosszuegig setzen

Fuer produktive Magento-Server ist die Kombination aus lokalem ext4- oder XFS-Storage fuer den Code, deaktivierter Timestamp-Pruefung und einem tmpfs-basierten sekundaeren File-Cache die stabilste OPcache Dateisystem-Konfiguration. NFS-Setups sind machbar, verlangen aber zwingend einen koordinierten Deployment-Prozess, der den Cache auf allen beteiligten Knoten synchron invalidiert.

Mironsoft

Linux-Server-Tuning und Performance-Optimierung fuer Magento

Liefert Ihr Server nach jedem Deployment veralteten Code aus?

Wir pruefen Ihre OPcache-Konfiguration im Zusammenspiel mit dem Dateisystem, richten koordinierte Cache-Invalidierung fuer Multi-Server-Setups ein und optimieren die Aufwaermzeit nach Neustarts.

OPcache-Audit

validate_timestamps, memory_consumption und file_cache pruefen und optimieren

Deployment-Automatisierung

Koordinierte Cache-Invalidierung fuer alle Applikationsserver einrichten

Storage-Beratung

Passende Dateisystem- und Mount-Strategie fuer Ihren Magento-Stack

10. Zusammenfassung

Die OPcache Dateisystem-Wechselwirkung wird in den meisten Tutorials auf eine einzelne Einstellung reduziert, dabei entscheidet der zugrunde liegende Storage erheblich mit ueber die tatsaechliche Performance. Deaktivierte Timestamp-Pruefung spart jeden stat()-Aufruf im laufenden Betrieb, verlangt dafuer aber einen kontrollierten Deployment-Prozess mit explizitem Cache-Reset. Symlink-basierte Deployments erzeugen neue Inodes, die ohne aktiven Reset unsichtbar bleiben.

NFS-Setups bringen zusaetzliche Komplexitaet durch clientseitiges Metadaten-Caching, das selbst aktivierte Timestamp-Pruefungen aushebeln kann. Ein sekundaerer File-Cache auf tmpfs verkuerzt die Aufwaermzeit nach geplanten Neustarts erheblich. Wer diese OPcache Dateisystem-Zusammenhaenge versteht, vermeidet sowohl unnoetigen Performance-Verlust als auch das Risiko, veralteten Code an Kunden auszuliefern.

OPcache Dateisystem-Ueberlegungen — Das Wichtigste auf einen Blick

Timestamps

validate_timestamps = 0 in Produktion, dafuer expliziter Reset nach jedem Deployment via reload.

Symlink-Deployments

Neue Inodes bleiben ohne aktiven Cache-Reset unsichtbar fuer den Shared-Memory-Cache.

NFS-Fallstricke

Client-seitiges Metadaten-Caching verlangt koordinierten Reset auf allen Applikationsservern.

file_cache

Auf tmpfs auslagern fuer minimale Aufwaermzeit nach PHP-FPM-Neustarts.

11. FAQ: OPcache Dateisystem-Ueberlegungen unter Linux

1Warum ist OPcache abhaengig vom Dateisystem?
stat()-Aufrufe pruefen Dateimetadaten, deren Latenz je nach Storage-Typ stark variiert.
2Sollte validate_timestamps in Produktion aktiviert sein?
Nein, deaktivieren und stattdessen explizit nach jedem Deployment zuruecksetzen.
3Was passiert bei Symlink-Deployments?
Neue Inodes bleiben unsichtbar, bis der Cache explizit ueber Reload geleert wird.
4Warum ist NFS problematisch?
Clientseitiges Metadaten-Caching kann veraltete Zeitstempel liefern, selbst bei aktiver Pruefung.
5Was ist opcache.file_cache?
Ein sekundaerer Cache, der Bytecode ueber FPM-Neustarts hinweg erhaelt.
6Sollte file_cache auf tmpfs liegen?
Ja, fuer minimale Latenz, dabei geht der Inhalt bei Reboot verloren.
7Wie invalidiert man OPcache im Cluster?
Zentrales Deployment-Skript mit gleichzeitigem Reload auf allen Knoten.
8Was zeigt opcache_get_status()?
Treffer, Fehlschlaege und Speicherauslastung als Diagnosewerte.
9Reicht touch fuer NFS-Updates?
Nein, ein expliziter Reload auf allen Knoten ist zuverlaessiger.
10Was ist die stabilste Konfiguration?
Lokales ext4/XFS, deaktivierte Timestamp-Pruefung, tmpfs fuer den sekundaeren Cache.