Определение простыми словами
Кэширование — это «не делать одну и ту же работу дважды». Если страница уже сгенерирована для одного посетителя, отдадим тот же HTML следующему за миллисекунды вместо повторного запроса в базу. Если ответ от платёжного API не меняется минуту — храним его в памяти и не дёргаем сервис партнёра на каждом клике.
На веб-проекте кэш работает слоями: браузер хранит статику локально, CDN отдаёт картинки и JS из ближайшего города, Nginx или Varnish держит готовый HTML, приложение использует Redis или Memcached, а база данных кэширует часто запрашиваемые планы запросов.
Сравнение слоёв кэша
| Слой | Что хранит | Время жизни |
|---|---|---|
| Браузер | Статика: CSS, JS, шрифты, картинки | Дни и недели по Cache-Control |
| CDN | HTML, статика, медиафайлы | Минуты и часы, инвалидация по событию |
| Reverse proxy (Nginx, Varnish) | Готовый HTML популярных страниц | Секунды и минуты |
| Redis / Memcached | Сериализованные объекты, сессии, фрагменты | От секунд до часов |
| База данных | Планы запросов, страницы данных в RAM | До перезагрузки сервера |
Кейсы использования
- Магазин с тысячей товаров — Nginx fastcgi_cache держит готовый HTML каталога, нагрузка на PHP падает в 10-50 раз.
- API на FastAPI или Express — Redis хранит ответы, которые меняются редко, и снимает нагрузку с PostgreSQL.
- Картинки товаров идут через CDN с заголовком Cache-Control: max-age=2592000 — посетитель не качает их при каждом визите.
- Сессии пользователей переезжают из файлов в Redis — горизонтальное масштабирование становится возможным.
- Сайт на WordPress с кэшем LiteSpeed Cache или WP Super Cache выдерживает десятки тысяч посетителей на скромном тарифе.
Негативный сценарий: кэш без инвалидации — это «вечно старая цена». Если после смены цены товара кэш не очистился, покупатель видит одну сумму в карточке, а другую в корзине. Перед внедрением кэша всегда продумайте сценарий очистки: по событию, по тегам или по короткому TTL.
Технические детали
cat > /etc/nginx/conf.d/cache.conf <<'CONF'
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=site:100m max_size=2g inactive=60m;
CONF
nginx -t && systemctl reload nginx
redis-cli set 'product:42' '{"price":1990}' EX 600
redis-cli get 'product:42'
redis-cli flushdb
curl -I https://example.com/style.css | grep -i 'cache-control|expires|age'
🔥 Где это применяется
Частые вопросы
Какой кэш ставить первым?
Сначала браузерный — настроить Cache-Control и Expires для статики. Потом OPcache для PHP. Потом серверный кэш страниц (Nginx fastcgi_cache или плагин WordPress). Только после этого имеет смысл подключать Redis для объектов и CDN.
Как понять, что кэш реально работает?
Откройте сайт через curl -I и проверьте заголовки X-Cache, Age, Cache-Control. Значение HIT и ненулевой Age означают, что ответ отдан из кэша. В логах Nginx есть переменная $upstream_cache_status — её удобно выводить в access.log.
Чем Redis лучше Memcached?
Redis поддерживает сложные структуры данных, репликацию, персистентность на диск и pub/sub. Memcached проще, но умеет только строки. Для кэша HTML-фрагментов разница невелика, для очередей и счётчиков выбирают Redis.