Кэширование
Работал с кэшированием на нескольких уровнях:
- HTTP / браузерный кэш;
- серверный application cache;
Redisкак backend для cache и lock-механизмов;- build-time кэширование;
- локальный in-memory cache на frontend;
- кэширование идемпотентных и условно-повторяемых запросов.
Серверное кэширование
Есть опыт прикладного кэширования данных и готовых ответов на уровне backend.
Что использовал на практике:
- кэширование JSON-ответов в
Redis; - revision-based invalidation;
ETagи условные запросы;- выборочное кэширование публичных и пользовательских списков;
- разделение payload cache и revision key;
- инвалидацию кэша при изменении данных.
Использовал revision-based схему для Redis JSON response cache:
- публичные списки кэшируются с
ETagи304 Not Modified; - пользовательские списки тоже имеют отдельную схему кэширования;
- при изменении данных ревизия увеличивается, и старый кэш становится неактуальным без грубой очистки всего store.
HTTP caching: ETag и conditional requests
Реализовывал HTTP Conditional Requests для API и файловых ответов.
Что обычно настраивал:
ETag;Cache-Control;304 Not Modifiedпри совпадении условия;- разделение публичного и приватного кэширования;
- безопасное поведение для изменяемых и чувствительных данных.
На практике это использовалось, например:
- для index/list endpoint-ов с условной отдачей данных;
- для списка сохранённых пользователем сущностей;
- для файловых/изображений endpoint-ов с
ETagи cache headers.
Revision-based invalidation
Есть опыт более аккуратной инвалидации кэша, чем простое удаление всех ключей.
Подход, который использовал:
- отдельный revision key для группы данных;
- payload cache keys в
Redis, завязанные на текущую ревизию; - bump revision при изменении данных;
- прикладные invalidator-классы и команды для управления инвалидацией.
Использовал отдельные invalidator-реализации и artisan-команду для bump revision у публичного списка рецептов.
Redis как cache backend и distributed locks
Использовал Redis как инфраструктурный backend для cache-механизмов.
Что обычно использовал:
- хранение кэша;
- lock-механизмы;
- временные ключи с TTL;
- служебные данные для антидублей и координации конкурентных запросов.
Redis может участвовать в двух разных ролях:
- инфраструктурный state: sessions, queues, rate limiter, locks и idempotency/replay keys;
- ручной HTTP-cache: revision-based payload cache для отдельных GET endpoint-ов вроде списков рецептов и сохранённых рецептов.
Idempotency и replay cache
Есть опыт использования кэша не только для ускорения чтения, но и для обеспечения корректного поведения write-операций.
Это выражается через idempotency middleware, которое:
- строит cache key по idempotency key + запросу + identity;
- хранит успешный ответ в
Redis; - возвращает cached replay для повторного запроса;
- использует lock и in-progress markers, чтобы не допускать конкурентную повторную обработку одной и той же операции.
Кэширование статики и ассетов
Есть опыт настройки кэширования на уровне web-server и фронтенд-ассетов.
Что использовал:
- точечный
fastcgi_cacheдля публичных GET endpoint-ов; Cache-Controlдля статических ресурсов;immutableдля versioned/hash-named build-ассетов;X-Cache-Statusдля диагностики web-server cache;- раздельные правила для динамики и статики;
- более короткие или строгие правила для изменяемого контента.
На практике это включало точечный fastcgi_cache для публичного GET /api/v1/timezones, кэширование ассетов /build и отдельные cache headers для изображений.
Build-time cache
Есть опыт использования build/runtime cache-механизмов фреймворка и инфраструктуры.
Из практики:
config:cache;route:cache;view:cache;- подготовка production-конфигурации с уже прогретыми/собранными артефактами.
Frontend caching
Есть опыт клиентского кэширования на frontend-стороне.
Что использовал:
- in-memory GET cache в API-клиенте;
- локальное хранение уже загруженного состояния в store/service-слое;
- принудительное обновление данных (
force reload) при необходимости; - cache-busting для отдельных запросов и ресурсов;
- preload сценарии для изображений и часто используемых данных.
Из практики:
- in-memory cache в API client для GET-запросов;
- cache-aware store/service-логике;
- отдельным возможностям отключать кэш на уровне конкретного запроса.