Очередь прогрева работала, рендеры шли, ошибок не было. А вторая–шестая страницы каталога спустя часы после обмена отдавали MISS по 0,9–2,3 секунды. Не иногда — всегда.
Это десятая часть цикла «Кэш фрагментов и Redis».
Почему хвост не доходил
Обмен с 1С шёл волнами примерно каждые 10 минут. Каждая волна заново ставила в очередь первую страницу всех задетых категорий — самую важную. Бюджет прогона уходил на них. До вторых и дальних страниц очередь не доходила никогда: к тому моменту приходила следующая волна и снова ставила первые страницы вперёд.
Это классическое голодание: приоритетная работа никогда не кончается, и неприоритетная не начинается.
Лечение: резерв в бюджете
- бюджет прогона поднят с 12 до 18 рендеров;
- последние 4 рендера прогона зарезервированы только под дальние страницы (вторая и дальше);
- горячие задачи — устаревшие ячейки, которые уже запросил посетитель, — идут вне квоты.
$budget = 18;
$reserve = 4; // только для page > 1
$done = 0;
foreach (warm_queue_ordered() as $task) { // hot → page1 → дальние
$is_hot = !empty($task['hot']);
$is_deep = ($task['args']['page'] ?? 1) > 1;
if (!$is_hot && !$is_deep && $done >= $budget - $reserve) {
continue; // место под дальние страницы занимать нельзя
}
frag_warm($task);
if (!$is_hot && ++$done >= $budget) {
break;
}
}
Порядок приоритетов
| Очередь | Что там | Почему так |
|---|---|---|
| горячая | устаревшие ячейки, которые уже кто-то открыл | посетитель получил STALE и может вернуться |
| первые страницы | вход в категории | их открывают чаще всего |
| дальние страницы | вторая и дальше | гарантированный резерв в каждом прогоне |
Принцип: у каждого класса задач должна быть гарантированная доля, а не только место в очереди. Иначе при постоянном притоке важного неважное не наступает никогда.
Дальние страницы каталога всегда медленные?
Пришлите адрес — проверю, доходит ли до них очередь прогрева.
// загружаю комментарии…