200 000 страниц: кешируем HTML, сохраняем динамику
На affiliate-платформе в iGaming — около 200 000 страниц, 15 доменов и 5 локалей. В пики нагрузки росло время ответа: пользователи ждали, показатели PageSpeed ухудшались. Это создавало и риски для SEO.
Около 90% контента типичной страницы одной локали не менялись. Но готовый HTML нужно было отдавать с учётом персонализации, географии и разных правил актуальности.
Рассмотрели Varnish. Но вариативные 5–10% страницы требовали сложной сборки: состав, доступность и порядок геоблоков зависели от страны посетителя и внутренних правил платформы. По нашей оценке, интеграция этой логики с внешним кешем слишком усложняла решение.
Поэтому HTML-кеш реализовал на границе инфраструктурного слоя приложения. Общую часть страницы переиспользовали, а динамические блоки собирали там, где уже работала вся логика выбора контента. Общий HTML сохраняли в файлы: весь объём в Redis обходился слишком дорого по памяти. Персональное меню дорендеривали, геозависимые фрагменты кешировали отдельно в Redis.
Изменения мета-шаблонов, включая критичные SEO-настройки, сразу сбрасывали кеш. Для правок заголовков и новых виджетов допускали прежнюю версию до фонового обновления.
Ревалидацию запускали события, для подстраховки использовали TTL с разбросом сроков. Пока обновляли кеш, продолжали отдавать готовый HTML. Блокировка защищала от параллельной пересборки; после сбоя воркера её срок истекал, и работу могло забрать другое задание.
TTFB — время до первого байта — снизился примерно с 700 до 50–100 мс. Основную часть страницы больше не приходилось собирать при каждом запросе. Такие дела!