Скачать CV
Назад к бизнес-кейсам

Очередь

Job в Horizon, который вёз всю модель

Redis забился serialize Eloquent. Очередь тормозила, потому что payload был каталогом.

Horizon показывал нормальный throughput, пока не перестал. Упавшие job сидели в Redis, ретраи копились, контейнер очереди вырос за 1 ГБ RSS. На бумаге job были маленькими: пересобрать страницу каталога. Payload маленьким не был.

Каждый job хранил сериализованную коллекцию Product. С ним ехали связи, касты и три локали. Ретрай писал тот же блоб ещё раз. Redis упёрся в maxmemory, и Horizon начал терять lock-ключи, которые нужны веб-воркерам.

Проблема была в билете, который вёз каталог. Листинги вставали, пока Redis вытеснял lock. На проводе нужны id и локаль, не 1.4 МБ Eloquent на каждый ретрай.

Job живут в Redis. HTML каталога нет. В payload должен быть список id.
Job живут в Redis. HTML каталога нет. В payload должен быть список id.

Что ехало по проводу

Я снял один reserved job. 1.4 МБ PHP serialize. Сорок товаров, у каждого title JSON на en, ru и de. Воркер разворачивал этот граф, рендерил HTML, писал Memcached и умирал. Следующий ретрай делал то же из того же блоба.

У класса job была публичная коллекция $products. Laravel сериализует аргументы конструктора в Redis. Упавший воркер оставлял блоб в резерве. Redis держал копии на окно ретрая. Так очередь пересборки съедала maxmemory.

Id, не модели

Job получает id страницы и локаль. Нужное читает из MySQL или из компактного DTO уже в Memcached. Redis хранит несколько чисел и строку.

  • Timeout job короче резерва Redis.
  • Три попытки, потом таблица failed_jobs, а не бесконечный ретрай с payload 1.4 МБ.
  • Horizon --memory=128, чтобы жирный unserialize убивал воркер, а не хост.

RSS очереди сел до размера PHP плюс буферы клиента Redis. Пересборки каталога после записи остались. Они просто перестали возить каталог внутри билета.

Какой опыт из этого

Payload очереди это билет, не кэш. Если воркер может прочитать строку, job не должен её возить.

Ретраи множат размер. Serialize на 1.4 МБ с тремя падениями это четыре копии в Redis плюс дамп failed_jobs.

--memory=128 это забор для жирного unserialize. Дизайн всё равно список id.

Назад к бизнес-кейсам