CV laden
Zurück zu Business Cases

Redis

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.

Ein Monat Katalog-Traffic. Fast jeder Key ist eine Session, die niemand liest.
Ein Monat Katalog-Traffic. Fast jeder Key ist eine Session, die niemand liest.

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.

HTML-Eviction und Job-Eviction sind verschiedene Fehler. Sie teilen keine Policy.
HTML-Eviction und Job-Eviction sind verschiedene Fehler. Sie teilen keine Policy.
  • 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.

Zurück zu Business Cases