Horizon-Jobs, die das ganze Model mitnahmen
Redis lief voll mit serialisiertem Eloquent. Die Queue war langsam, weil das Payload der Katalog war.
Horizon zeigte einen gesunden Durchsatz, bis er es nicht mehr tat. Fehlgeschlagene Jobs lagen in Redis, Retries häuften sich, der Queue-Container wuchs über 1 GB RSS. Auf dem Papier waren die Jobs klein: eine Katalogseite neu bauen. Das Payload war es nicht.
Jeder Job speicherte eine serialisierte Product-Collection. Relationen, Casts und drei Locales fuhren mit. Ein Retry schrieb denselben Blob erneut. Redis stieß an maxmemory, danach verlor Horizon die Lock-Keys, die die Web-Worker brauchten.
Das Problem war eine Fahrkarte, die den Katalog mitnahm. Listings standen, während Redis Locks warf. Auf der Leitung brauchte ich ID und Locale, nicht 1,4 MB Eloquent bei jedem Retry.
Was über die Leitung ging
Ich habe einen reserved Job ausgegeben. 1,4 MB PHP-Serialize. Vierzig Produkte, jedes mit Title-JSON für en, ru und de. Der Worker unserialisierte den Graphen, renderte HTML, schrieb Memcached und starb. Der nächste Retry tat dasselbe aus demselben Blob.
Die Job-Klasse hatte eine öffentliche $products-Collection. Laravel serialisiert Konstruktor-Argumente nach Redis. Ein toter Worker ließ den Blob reserviert. Redis hielt Kopien für das Retry-Fenster. So fraß eine Rebuild-Queue maxmemory.
IDs, keine Models
Der Job bekommt Seiten-ID und Locale. Er lädt, was er braucht, aus MySQL oder aus dem kompakten DTO in Memcached. Redis speichert ein paar Integers und einen String.
- Job-Timeout kürzer als die Redis-Reservation.
- Drei Versuche, dann die failed_jobs-Tabelle, kein endloser Retry mit 1,4 MB Payload.
- Horizon --memory=128, damit ein fettes Unserialize den Worker tötet, nicht den Host.
Der Queue-RSS fiel auf PHP plus Redis-Client-Buffer. Katalog-Rebuilds laufen weiter nach Writes. Sie hören nur auf, den Katalog in der Fahrkarte mitzunehmen.
Was ich daraus mitnehme
Ein Queue-Payload ist eine Fahrkarte, kein Cache. Kann der Worker die Zeile laden, soll der Job sie nicht tragen.
Retries multiplizieren Größe. 1,4 MB Serialize mit drei Fehlern sind vier Kopien in Redis plus der failed_jobs-Dump.
--memory=128 ist ein Zaun für fettes Unserialize. Das Design bleibt eine ID-Liste.
