Kubernetes-Migration geplant?

cluster-file-backend — TYPO3-Cache für Kubernetes, ohne Shared Filesystem.

TYPO3-Datei-Caches sicher über mehrere Kubernetes-Pods betreiben — ohne RWX-Volume. cluster-file-backend hält Cache-Payloads pod-lokal und Cache-Gültigkeit cluster-weit. Es ersetzt TYPO3s FileBackend und SimpleFileBackend für Cache-Workloads, unterstützt tag-basierte Invalidierung und entkoppelt Multi-Pod-Deployments vom Shared-Filesystem.

  • Composer-Paket:moselwal/cluster-file-backend:^2.3
  • Extension-Key:cluster_file_backend
  • TYPO3: 14.3+ (Composer-Mode only) · PHP: 8.5+ · MIT

TL;DR — Passt das zu meinem Setup?

Nutzen Sie es wenn …

Nutzen Sie es nicht wenn …

Migrations-Aufwand

Einmaliges Setup: Metadaten-Cache registrieren, Cache-Konfigurationen umschreiben, emptyDir mounten. Keine TYPO3-Core-Änderungen, kein Code-Eingriff in die Applikation.

Empfohlenes Metadaten-Backend

Produktion: moselwal/keyvalue-store mit KeyValueBackend (Valkey/Redis, sub-ms Latenz, taggable). Einstieg ohne extra Dependency: TYPO3-Cores Typo3DatabaseBackend.

Packagist

composer require moselwal/cluster-file-backend:^2.3

Paket auf Packagist →
Packagist

GitHub

Quellcode, Issues und Changelogs. MIT-lizenziert.

Auf GitHub ansehen →
GitHub

Was ist neu in v2.2 / v2.3

PhpCapableBackendInterface (v2.2)

Seit v2.2 implementiert ClusterFileBackend auch PhpCapableBackendInterface — damit bedient ein Backend sowohl VariableFrontend-Caches (pages, extbase, …) als auch PhpFrontend-Caches (typoscript, fluid_template). Der Payload-Store hängt bei PhpFrontend-Caches ein .php-Suffix an, damit OPcache die Dateien direkt ingestet. Kompression wird für PHP-Code erzwungen auf none. Cluster-Kohärenz kommt aus dem BackendVersion-gefalteten Hash-Pfad — jedes Deploy ergibt einen neuen Pfad, OPcache kühlt automatisch ab, kein opcache_invalidate() nötig.

Ein-Byte-Kompressionsmarker (v2.2)

0x00 = unkomprimiert, 0x01 = zstd, 0x02 = gzip. Der Leser wählt den Dekompressor anhand des Markers — der Schreiber kann Codecs mischen (z. B. kein Komprimieren bei kleinen Payloads, zstd für den Rest).

Skip-Compress für kleine Payloads (v2.2)

Option minCompressedBytes (Default 1024): Payloads unterhalb dieser Schwelle werden unkomprimiert gespeichert. Vermeidet den Fixed-Cost von gzdeflate/zstd_compress bei winzigen Werten. 0 = immer komprimieren.

Request-scoped Metadata-L1 (v2.2)

has() / get() / remove() treffen eine In-Memory-Map der jüngsten CacheMetadata-Lookups. Identische Identifier im selben Request überspringen den Valkey/DB-Roundtrip — ca. 200× schneller bei wiederholten has()-Aufrufen.

Request-scoped Payload-L1 (v2.3)

Vollständig dekodierte Payloads werden per LRU im RAM gecacht (Default: 32 Einträge / 4 MB). Wiederholte get()-Aufrufe auf ein heißes Identifier fallen von ca. 90 µs auf ca. 0,5 µs — 9–20× schneller als SimpleFileBackend auf jedem wiederholten Lesevorgang. Steuerbar über payloadL1MaxEntries und payloadL1MaxBytes. PhpFrontend-Caches überspringen den Payload-L1 (OPcache ist die bessere In-Memory-Repräsentation).

Prometheus-Counter cache_l1_hit_total (v2.3)

Neben cache_hit_total und cache_miss_total ermöglicht der neue Counter cache_l1_hit_total die Sichtbarkeit der drei-Schichten-Hit-Verteilung im Betrieb. Alert auf cache_miss_total{reason=metadata-error} für Frühwarnung bei Ausfall des Metadaten-Cache.

Drei-Schichten-Speicher und Architektur

┌─ FrankenPHP-Worker RAM ─────────────────────────────────────────┐
│  OPcache (kompilierter PHP-Code)     → PhpFrontend .php-Dateien │
│  Payload-L1 (dekomprimierte Bytes)   → VariableFrontend-Caches  │
│  Metadata-L1 (CacheMetadata-Objekte) → alle Caches              │
└─────────────────────────────────────────────────────────────────┘
                              ▲
┌─ Pod-lokales emptyDir ──────────────────────────────────────────┐
│  /<localPath>/<shard>/<sha256>[.php]                            │
│  • VariableFrontend: 1-Byte-Marker + komprimierte Bytes         │
│  • PhpFrontend: Klartext-PHP mit .php-Suffix                    │
│  → Source of Truth für die Payload-Bytes                        │
└─────────────────────────────────────────────────────────────────┘
                              ▲
┌─ Metadaten-Cache (Valkey / DB) ─────────────────────────────────┐
│  ~300-Byte-Records: { hash, checksum, lifetime, tags, state }   │
│  → Source of Truth für cluster-weite Cache-Gültigkeit           │
│  → kein PHP-Code, keine Payload-Bytes                           │
└─────────────────────────────────────────────────────────────────┘

Dieses Paket weiß nichts über Redis/Valkey/KV-Stores. Es spricht ausschließlich mit der TYPO3-Cache-API und delegiert die Cluster-Persistenz an ein vom Anwender gewähltes TYPO3-Cache-Backend.

TYPO3 Cache API → ClusterFileBackend
                      │
                      ├─► Metadata-Cache (zweites TYPO3-Cache-Frontend,
                      │   Backend frei wählbar: Typo3DatabaseBackend,
                      │   KeyValueBackend, MemcachedBackend, …)
                      │
                      └─► Local Payload Store (pod-lokal, emptyDir)

 

Was es ist

Was es nicht ist

Voraussetzungen

TYPO3-Kubernetes-Migration geplant oder bereits im Betrieb? Wir helfen bei Architektur-Review, Cache- und Storage-Design, Migration und Plattform-Setup. Anfragen →

Setup-Voraussetzungen — was Sie einmalig tun

Das Paket registriert die Caches bewusst nicht automatisch. Hostnamen, Ports, TLS, Pfade sind grundsätzlich site-spezifisch. Die folgenden Schritte sind ein einmaliges Setup.

Fünf erforderliche Schritte

  1. Composer-Installation: composer require moselwal/cluster-file-backend:^2.3
  2. Cluster-fähiges Cache-Backend für die Metadaten bereitstellen. Der Default verwendet TYPO3-Cores Typo3DatabaseBackend — funktioniert ohne zusätzliche Dependency, solange die Datenbank von allen Pods erreichbar ist (Galera, RDS Multi-AZ, …). Für höhere Performance moselwal/keyvalue-store installieren und dessen KeyValueBackend nutzen.
  3. TYPO3-Cache-Frontend (Konvention: cluster_meta) für die Metadaten registrieren.
  4. Die dateibasierten TYPO3-Caches (pages, pagesection, rootline, imagesizes, assets, hash) auf ClusterFileBackend umstellen und per metadataCacheIdentifier auf cluster_meta verweisen.
  5. Pod-lokales emptyDir unter /app/var/cache/cluster/ (oder dem konfigurierten localPath) mounten.

Was das Paket mitliefert

ArtefaktPfadZweck
Default-Config (ohne Extra-Deps)Configuration/Example/cache-configurations.example.phpDatenbank-basierte Metadaten plus Cluster-File-Caches — läuft auf jeder TYPO3-Installation
Redis/Valkey-Config (optional)Configuration/Example/cache-configurations-redis.example.phpPerformance-Variante mit moselwal/keyvalue-store
JSON-SchemaConfiguration/Backend/ClusterFileBackend.options.schema.jsonWird beim Backend-Konstruktor validiert — fehlerhafte Konfiguration führt zu InvalidCacheException mit Feldname
CLI-KommandosConfiguration/Commands.phpclusterfilebackend:gc, clusterfilebackend:warmup
Event-ListenerConfiguration/Services.yamlHängt sich in TYPO3s CacheWarmupEventbin/typo3 cache:warmup triggert die Cluster-Warmup mit
DI-BindingsConfiguration/Services.yamlAuto-Discovery für MetricsPort, ClockPort, CompressorPort

Konstruktor-Validation

Der ClusterFileBackend-Konstruktor validiert seine Optionen gegen ein JSON-Schema. Pflichtfelder (sonst InvalidCacheException): localPath (absoluter Pfad), metadataCacheIdentifier (Name des Metadata-Cache-Frontends), namespace.environment (prod, staging, testing oder development) und namespace.instance (Slug [a-z0-9-]{1,64}). Wenn der konfigurierte metadataCacheIdentifier nicht als TYPO3-Cache registriert ist, scheitert der Konstruktor sofort mit einer Nachricht, die den Config-Pfad benennt — kein stilles Fehlschlagen beim ersten set().

OptionsfeldDefaultBedeutung
compressionzstdzstd | gzip | none. Bei PhpFrontend-Caches immer auf none erzwungen.
serializerigbinaryigbinary | php. Wechsel invalidiert bestehende Einträge.
defaultLifetimeSeconds3600TTL wenn der Caller null übergibt. Minimum 1 (Schema lehnt 0 ab).
maxPayloadBytes10485760 (10 MB)Schreibvorgänge darüber werden mit InvalidDataException abgelehnt. Obere Grenze für unkomprimierte Reads (zstd-Bomb-Mitigierung).
minCompressedBytes1024Payloads unterhalb dieser Schwelle werden unkomprimiert gespeichert (1-Byte-Marker 0x00). Spart den Fixed-Cost von zstd_compress/gzdeflate bei winzigen Werten. 0 = immer komprimieren.
payloadL1MaxEntries32Maximale Einträge im request-scoped Payload-L1. 0 deaktiviert den Payload-L1 (Metadata-L1 bleibt aktiv). LRU-Eviction.
payloadL1MaxBytes4194304 (4 MB)Soft-Memory-Budget für den Payload-L1. Einträge, die das Budget überschreiten würden, werden in Insertionsreihenfolge evictet. Ein einzelner Payload größer als dieses Budget umgeht den L1 komplett. 0 = kein Byte-Budget.
backendVersionEnvVarIMAGE_TAGEnv-Variable mit dem Deploy-Identifier. Wird in jeden Payload-Hash gefaltet — jedes Deploy bekommt einen frischen Pfad-Baum. Überschreiben für CI-Konventionen wie CI_COMMIT_SHA.

Konfiguration — Quick-Start und Varianten

Quick-Start (null Extra-Dependencies)

Den Inhalt von vendor/moselwal/cluster-file-backend/Configuration/Example/cache-configurations.example.php in die config/system/settings.php (oder additional.php) kopieren und environment, instance und localPath auf das Deployment anpassen. Dieses Beispiel nutzt TYPO3-Cores Typo3DatabaseBackend für den Metadaten-Cache — cluster-sicher, sobald die Datenbank cluster-betrieben ist.

Redis/Valkey-Variante

Für Sub-Millisekunden-Latenz auf den Metadaten Configuration/Example/cache-configurations-redis.example.php nehmen. Verwendet den KeyValueBackend aus moselwal/keyvalue-store mit optionaler TLS- und Sentinel-Unterstützung.

Manuelles Setup

Schritt 1: Ein TYPO3-Cache-Frontend für die Metadaten definieren. Jedes Backend, das TaggableBackendInterface implementiert (für flushByTag), funktioniert.

 

$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cluster_meta'] = [
    'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
    'backend'  => \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class,
    'options'  => [],
    'groups'   => ['system'],
];

 

Schritt 2:ClusterFileBackend auf den Metadaten-Cache verweisen — für alle dateibasierten Caches gleichzeitig.

 

foreach (['pages', 'pagesection', 'rootline'] as $cacheName) {
    $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheName] = [
        'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
        'backend'  => \Moselwal\Typo3ClusterCache\Infrastructure\Cache\Backend\ClusterFileBackend::class,
        'options'  => [
            'localPath'               => '/app/var/cache/cluster/' . $cacheName,
            'metadataCacheIdentifier' => 'cluster_meta',
            'namespace' => [
                'environment' => 'prod',
                'instance'    => 'website-a',
            ],
        ],
        'groups' => ['pages'],
    ];
}

Kubernetes-Deployment, Warmup und Garbage Collection

Pod-Volume für Payloads

 

volumes:
  - name: cluster-cache
    emptyDir: { sizeLimit: 2Gi }
volumeMounts:
  - name: cluster-cache
    mountPath: /app/var/cache/cluster

 

Deployment-Time-Warmup

Nach einem Rolling-Deploy sollen neue Pods typischerweise erst prüfen, ob sie den Metadaten-Cache erreichen und ob localPath beschreibbar ist, bevor sie Traffic annehmen. Der Warmup lässt sich explizit triggern:

 

./vendor/bin/typo3 clusterfilebackend:warmup \
    --namespace=cfb:prod:website-a:pages \
    --namespace=cfb:prod:website-a:pagesection \
    --namespace=cfb:prod:website-a:rootline

 

Das Kommando emittiert eine JSON-Zeile pro Namespace und beendet sich mit Exit-Code ≠ 0, wenn irgendein Namespace die Health-Checks nicht besteht. Damit lässt es sich in Readiness-/Startup-Probes oder Post-Deploy-Jobs einbinden.

Alternativ den TYPO3-Standard-Warmup nutzen — der Event-Listener hängt sich automatisch ein:

 

./vendor/bin/typo3 cache:warmup

 

Garbage Collection als CronJob

 

apiVersion: batch/v1
kind: CronJob
metadata:
  name: clusterfilebackend-gc-pages
spec:
  schedule: "*/15 * * * *"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: typo3-cli
              args: ["clusterfilebackend:gc", "--namespace=cfb:prod:website-a:pages"]

 

Architektur intern

DDD-4-Layer (Domain → Application → Infrastructure → Presentation), enforced via deptrac. Die einzige Außenschnittstelle für „zentrale Wahrheit" ist der MetadataCachePort, implementiert vom Typo3MetadataCache-Adapter, der jeden beliebigen TYPO3-FrontendInterface annimmt.

Cluster-Konsistenz — was passiert beim Cache-Clear?

Häufige Frage: „Wenn ein Redakteur im TYPO3-Backend auf Alle Caches löschen klickt, woher wissen alle Pods davon?"

Kurze Antwort: Der Pod, der den Klick verarbeitet, löscht den zentralen Metadaten-Cache. Alle anderen Pods sehen das beim nächsten get(), weil sie den zentralen Metadaten-Cache abfragen und nicht ihr lokales Filesystem. Kein Pod-zu-Pod-Sync nötig, weil die Metadaten-Wahrheit nie auf einem Pod liegt.

Detailliert

 

Pod A: TYPO3-Backend „Alle Caches löschen" / Editor speichert Page /
       `bin/typo3 cache:flush`
   │
   ▼
ClusterFileBackend::flush()                 auf Pod A
   │
   ▼  delegiert an Metadaten-Cache-Frontend (z. B. cluster_meta)
$metadataCache->flush()
   │
   ▼  TYPO3-Cache-API ruft das konfigurierte Backend
KeyValueBackend / DatabaseBackend / MemcachedBackend → flush()
   │
   ▼  passiert SERVER-SEITIG (Redis FLUSHDB, SQL TRUNCATE, Memcached flush_all)
Alle Pods sehen die leeren Metadaten sofort

 

Beim nächsten get(id) auf irgendeinem Pod:

 

$metadata = $this->metadataCache->get($identifier);   // → null (Cache geflushed)
if ($metadata === null) {
    // cache_miss_total{reason=no-metadata}++
    return null;   // ← Pod konsultiert sein lokales FS gar nicht erst
}

 

Test-Verifikation

Tests/Unit/Deployment/CrossPodFlushTest.php enthält fünf Tests, die das belegen: flush() propagiert ohne Sync sofort zu Pod B; flushByTag() invalidiert nur passende Einträge; lokale Files überleben den Flush als harmlose Waisen; Re-Write nach Flush stellt Konsistenz wieder her; Flush funktioniert für beliebige Pod-Anzahlen (keine Skalierungs-Annahme).

Komplexität — warum es im Cluster schneller ist

Sei C die Menge aller Cache-Einträge und Ct ⊆ C die Teilmenge der Einträge mit Tag t. Wir schreiben n := |C| für die Gesamtanzahl und m := |Ct| für die Anzahl der mit t getaggten Einträge — es gilt m ≤ n. Damit lässt sich der Unterschied sauber benennen: ClusterFileBackend liegt nicht nur bei kleinerem Argument, sondern in einer anderen Komplexitätsklasse, weil es Backend-native Algorithmen nutzt und keinen Pod-Faktor multipliziert.

Sei zusätzlich P die Anzahl der Pods und e ≤ n die Anzahl der TTL-abgelaufenen Einträge.

OperationTYPO3-Core-FileBackendClusterFileBackendSpeedup
flushByTagΘ(n) pro Pod — DirectoryIterator über jede Cache-Datei, 2× file_get_contents pro DateiΘ(m) — Backend liest Tag-Index direktAndere Komplexitätsklasse plus Tag-Indizes
findIdentifiersByTagΘ(n) pro PodO(m)dito
collectGarbageΘ(n) pro Pod, gesamt Θ(n · P)O(1) aktiv (Redis TTL Auto-Expire) oder O(e) server-seitig (DB)Backend-native plus Cluster-once
flushΘ(n) pro Pod, gesamt Θ(n · P)Θ(n) einmal server-seitigPod-Faktor entfällt, Konstanten ~100–1000× kleiner

Konkretes Beispiel

n = 10 000 Cache-Einträge, davon m = 100 mit Tag site_1, P = 5 Pods.

SetupFile-Readsunlink-CallsRound-Trips
Core-FileBackend bei flushByTag('site_1')2 · n = 20 000m = 100≈ 2 n + m = 20 100 lokale FS-I/O pro Pod
ClusterFileBackend (Redis)002 (SMEMBERS + Pipeline DEL) einmal cluster-weit

Rolling-Deploys mit Version-Skew

Während eines Rolling-Deploys liefern alte und neue Pods gleichzeitig Traffic aus. ClusterFileBackend bewahrt in jedem Skew-Szenario die Korrektheit, aber zwei Fälle ändern das Performance-Profil während des Deploy-Fensters — die sollte man verstehen.

A) Anwendungs-Code mit geändertem Cache-Layout

Wenn das neue Image für denselben Cache-Identifier eine andere Payload-Struktur schreibt (zusätzliche Felder, geänderte serialisierte Klassen, anders aufgebaute Value-Objects) und Sie nicht explizit invalidieren, passiert Folgendes:

  1. Pod-alt schreibt Payload v1 → Metadaten enthalten hashv1.
  2. Pod-neu liest, sieht hashv1, hat lokal keinen Blob → Blob-Miss → TYPO3-Frontend ruft den Rebuild des Callers → Pod-neu schreibt Payload v2 → Metadaten werden mit hashv2 überschrieben.
  3. Pod-alt liest, sieht hashv2, hat lokal keinen Blob → Blob-Miss → baut v1 neu → Metadaten zurück auf hashv1.
  4. Hash-Thrashing für die Dauer des Rolling-Deploys.

Das größere Risiko ist stiller Layout-Drift: kann Pod-neu die Bytes von Pod-alt zwar technisch deserialisieren, das resultierende Objekt ist aber falsch (fehlende Felder, alte Enum-Cases, entfernte Properties), sieht der User stale oder korrupten Content. PHPs unserialize verifiziert die Klassen-Shape jenseits des Klassennamens nicht.

Empfehlung: Cache-Identität an den Deploy koppeln

Damit jedes Release automatisch eine neue BackendVersion bekommt und stale Einträge unerreichbar werden, liest ClusterFileBackend eine Environment-Variable — per Default IMAGE_TAG — und faltet ihren Wert via crc32 in den Payload-Hash. Im Deployment-Manifest:

 

# Helm-Values, Kustomize-Patch oder plain Pod-Spec
env:
  - name: IMAGE_TAG
    value: "{{ .Values.image.tag }}"  # oder $CI_COMMIT_SHA, Release-Semver, ...

 

Pro Cache lässt sich der Variablenname überschreiben, falls die CI-Konvention anders heißt:

 

'options' => [
    'localPath'              => '/app/var/cache/cluster/pages',
    'metadataCacheIdentifier' => 'cluster_meta',
    'namespace'              => ['environment' => 'prod', 'instance' => 'site'],
    'backendVersionEnvVar'   => 'CI_COMMIT_SHA',
],

 

Ist die Variable unset oder leer, fällt das Backend auf die package-interne BackendVersion::current() zurück — sicher für lokale Entwicklung, in Production sollten Sie die Variable aber explizit verdrahten, um deploy-scoped Invalidierung zu bekommen.

Alternative Invalidierungs-Strategien

Bei nicht-brechenden Layout-Änderungen (additiv, vom alten Code ignoriert) kann man das temporäre Thrashing akzeptieren — die Korrektheit bleibt erhalten.

B) PHP-Major/Minor-Version-Wechsel

Der Identity-Hash enthält PHP_MAJOR.PHP_MINOR (Classes/Application/Hash/ComputePayloadHash.php). PHP 8.4 ↔ 8.5 (oder jeder andere Major/Minor-Sprung) erzeugt automatisch divergente Hashes — keine manuelle Aktion nötig. Korrektheit garantiert. Die Kosten sind dasselbe Thrashing wie in (A) für die Dauer des Rollouts. blob_miss_total in Prometheus beobachten; ein anhaltender Spike über das Deploy-Fenster hinaus deutet darauf hin, dass die Version-Skew nicht konvergiert (z. B. ein Pod im alten Image hängen geblieben).

PHP-Patch-Updates (8.5.4 → 8.5.5) invalidieren nicht — nur Major und Minor sind im Hash.

Operative Empfehlung

Operative Anforderungen

Pod-Uhrsynchronisation

Cache-Lifetimes werden gegen die lokale Uhr jedes Pods ausgewertet. Weichen Pods in der Wanduhrzeit um mehr als ein paar Sekunden ab, behandelt ein Pod mit vorausgehender Uhr Einträge als abgelaufen, bevor Peers das tun — Korrektheit bleibt erhalten, Performance leidet. In Kubernetes ist das normalerweise kein Problem (Nodes synchronisieren per chrony/systemd-timesyncd gegen Cluster-NTP). Sanity-Check bei Incidents:

 

kubectl exec deploy/typo3 -- date -u

 

Ein Skew >30 Sekunden über Pods hinweg ist die Schwelle, ab der blob_miss_total und cache_miss_total{reason=expired} in Prometheus sichtbar auseinanderdriften.

Metadaten-Cache-Verfügbarkeit

Der Metadaten-Cache (Redis/Valkey/DB) ist die einzige Source of Truth. Ist er nicht erreichbar:

Kompatible Metadaten-Cache-Backends

Der Metadaten-Cache muss ein TaggableBackendInterface-Backend nutzen, sonst wird flushByTag zur No-Op. Geprüfte Backends:

BackendTaggableHinweis
Typo3DatabaseBackendZero-Dependency-Default
KeyValueBackend (moselwal/keyvalue-store)Redis/Valkey, empfohlen für hohen Traffic
MemcachedBackend (TYPO3 Core)Unterstützt keine Tags — inkompatibel
RedisBackend (TYPO3 Core)Nicht taggable — stattdessen moselwal/keyvalue-store verwenden

IMAGE_TAG-Konsistenz über alle Pods

Jeder Container, der auf denselben Metadaten-Cache zeigt, muss denselben IMAGE_TAG (oder die konfigurierte backendVersionEnvVar) sehen. Läuft der Web-Pod mit IMAGE_TAG=1.2.3 und ein Worker/Cron-Pod noch mit IMAGE_TAG=1.2.2, berechnen beide unterschiedliche BackendVersion-Werte und behandeln gegenseitige Writes als Blob-Misses. Symptom: persistentes Thrashing in gemischten Deployments. Helm/Kustomize-Tipp: Tag in einen einzigen Value extrahieren und von jeder Pod-Spec aus referenzieren.

Y2K38-Einschränkung für Unlimited-Lifetime-Einträge

Lifetime::unlimited() mappt auf expiresAt = 2147483647 (spiegelt TYPO3-Cores Typo3DatabaseBackend::FAKED_UNLIMITED_EXPIRE). Am 2038-01-19 03:14:07 UTC wird dieser Timestamp zu „jetzt“ und als unbegrenzt gespeicherte Einträge gelten als abgelaufen. Praktische Auswirkung bis dahin: keine.

crc32-basierte BackendVersion-Faltung

BackendVersion::fromString(…) faltet den Deploy-Identifier via crc32 auf ein 32-Bit-Integer. Geburtstags-Kollisionen treten bei ca. 77 000 eindeutigen Deploy-Identifiern auf — bei realistischer Release-Kadenz (einige Deploys pro Tag über die Laufzeit eines Projekts) bleibt die Kollisionswahrscheinlichkeit unter 1:10⁵. Wer regelmäßig Tausende unterschiedliche Identifier durchläuft, sollte auf einen stabilen, menschenlesbaren Semver-String statt rohen Commit-SHAs setzen.

Häufige Fallstricke

Nächster Schritt

TYPO3 unter Kubernetes betreiben?

Wenn Sie TYPO3 in einem K8s-Cluster ohne RWX-Volume betreiben oder ein bestehendes FileBackend-Setup für Multi-Pod auslegen, hilft cluster-file-backend. Sprechen Sie uns für Architektur-Beratung, Migration oder Plattform-Setup an.

K8s-Setup besprechen

Oder direkt schreiben: kontakt@moselwal.de

Setzen wir ein bei …

Dieses Paket übernimmt die dateibasierte Cache-Schicht in TYPO3 Kubernetes — eine der Voraussetzungen für Multi-Pod-Cluster, die unter Open Source & Digitale Souveränität beschrieben sind. In der betreuten Variante: AI-Ready CMS as a Service.