Session-Keys, die nie ablaufen
Redis lief voll mit laravel_session-Blobs. Horizon verlor reserved Jobs an allkeys-lru.
An einem ruhigen Dienstag verlor Horizon reserved Jobs. Redis INFO sagte used_memory_human 1,9G, maxmemory 2G, evicted_keys stieg. SCAN auf laravel_session:* lieferte 1,79 Millionen Keys. expires auf der ganzen db war 12. Queue-Keys lagen neben Session-Blobs unter allkeys-lru. Ein Listen-Lock und ein reserved Job gingen zusammen.
SESSION_DRIVER war redis, weil Sanctum-Cookie-Auth eine Session auf dem API-Host braucht. Anonyme Katalog-Hits erzeugten trotzdem eine Session. Die Cookie-Lifetime in der Config war 120 Minuten. Der Redis-Key hatte kein TTL. Ein Crawler, der nicht zurückkam, ließ einen Hash für immer stehen.
Das Problem waren Session-Keys ohne EXPIRE neben Horizon unter LRU. Ruhiger Traffic füllte Redis trotzdem. Jobs verschwanden. Ich brauchte TTL beim Write, keine Session auf öffentlichen Katalog-Routen und noeviction, damit volles Redis fehlert statt einen reserved Job zu werfen.
Wofür Redis hier ist
Queue, Locks, das Dirty-ID-Set und Sessions eingeloggter Nutzer. HTML bleibt in Memcached. Anonyme Requests starten StartSession auf den öffentlichen Katalog-Routen nicht. Der Session-Key bekommt EXPIRE 7200 beim Write. maxmemory-policy ist noeviction. Ist Redis voll, bekommt der Web-Worker einen Fehler. Ein reserved Job verschwindet nicht.
- auth_token bleibt httpOnly auf dem Cookie. Redis speichert die Session-ID, nicht den Token in JSON.
- FLUSHDB ist kein Fix. Der nächste Crawler füllt dieselben Keys ohne TTL.
- Horizon-Prefix und Session-Prefix sitzen auf einer Instanz. Der Prefix rettet nicht vor LRU.
used_memory fiel auf Queue plus ein paar tausend lebende Sessions. Failed Jobs mit leerem Payload hörten auf. Die interessante Zahl beim ersten INFO war expires, nicht used_memory.
Was ich daraus mitnehme
INFO expires ist die erste Zahl, die ich jetzt lese. used_memory ohne TTL ist eine Bombe neben Horizon.
allkeys-lru behandelt einen reserved Job wie ein Session-Blob. noeviction macht Fülle zu einem Web-Fehler, den ich sehe, statt zu einem stillen Job-Verlust.
Anonyme Katalog-Hits brauchen keine Session. Sanctum hat eine nach Login. Diese Trennung ist billiger als 1,79 Millionen Hashes.
