Зачем кэшировать и где кэш живёт
Кэш — это быстрое хранилище часто запрашиваемых данных. Он может жить в браузере, на CDN, в памяти приложения или в отдельном сервисе вроде Redis.
Почему это важно: Запрос к базе данных занимает 5–50 мс, обращение к Redis — 0.5 мс, к RAM — наносекунды. Кэширование — самый быстрый способ ускорить приложение без переписывания бизнес-логики.
Главная идея
Кэш хранит результат дорогой операции и отдаёт его повторно, пока данные не устареют. Эффективность кэша зависит от hit rate — доли запросов, которые обслуживаются из кэша.
Как это выглядит на практике
- Пользователь запрашивает страницу каталога товаров
- Приложение проверяет, есть ли результат в кэше (cache lookup)
- Cache miss: данных нет — запрос идёт в базу, результат сохраняется в кэш
- Следующие 100 пользователей получают тот же каталог из кэша (cache hit)
- Через 5 минут TTL истекает — кэш инвалидируется
- Следующий запрос снова идёт в базу и обновляет кэш
Примеры кода
Простой кэш в Rails
# Кэширование в Rails с TTL 5 минут
class ProductsController < ApplicationController
def index
@products = Rails.cache.fetch('products:catalog', expires_in: 5.minutes) do
# Этот блок выполнится только при cache miss
Product.includes(:category).published.order(:name).to_a
end
end
end
# Инвалидация при изменении товара
class Product < ApplicationRecord
after_save { Rails.cache.delete('products:catalog') }
end
Кэш с Redis в Python
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
def get_user_profile(user_id: int) -> dict:
cache_key = f'user:{user_id}:profile'
# Попробовать прочитать из кэша
cached = r.get(cache_key)
if cached:
return json.loads(cached) # cache hit
# Cache miss — запрос в БД
profile = db.query('SELECT * FROM users WHERE id = %s', user_id)
r.setex(cache_key, 300, json.dumps(profile)) # TTL = 300 сек
return profile
Что происходит под капотом
- L1/L2/L3 кэш процессора, RAM, SSD, сеть — каждый уровень на порядок медленнее предыдущего
- Hit rate = cache hits / (hits + misses) — метрика эффективности кэша, цель > 90%
- Cold start: после рестарта кэш пуст, все запросы идут в базу — нагрузка может вырасти в 10–100 раз
- Thundering herd: при инвалидации кэша сотни запросов одновременно обращаются к базе
- Размер кэша ограничен — нужна стратегия вытеснения (eviction): LRU, LFU, TTL
Типичные ошибки и заблуждения
- «Кэш решает все проблемы производительности» — он ускоряет чтение, но не помогает при медленных записях
- «Больше кэша = лучше» — кэширование всего подряд приводит к stale data и сложной инвалидации
- «TTL можно поставить побольше» — длинный TTL = устаревшие данные, нужен баланс между свежестью и скоростью
Ключевые выводы
- Кэш ускоряет чтение, сохраняя результат дорогих операций для повторного использования
- Hit rate > 90% — хороший показатель, ниже 50% — кэш бесполезен
- Уровни кэширования: браузер → CDN → приложение (RAM) → Redis/Memcached → БД
Термины урока
Связь с работой backend-разработчика
Кэширование — первый инструмент, к которому стоит обращаться при оптимизации производительности. Начинайте с профилирования: найдите самые частые и тяжёлые запросы, кэшируйте их с разумным TTL.
Мини-разбор реальной ситуации
Интернет-магазин с 10 000 товарами: каждая загрузка каталога делала JOIN на 4 таблицы (300 мс). После добавления Redis-кэша с TTL 2 минуты среднее время ответа упало до 3 мс, а нагрузка на БД снизилась на 85%.
Что запомнить
- Кэш = быстрое хранилище для часто запрашиваемых данных с ограниченным TTL
- Всегда измеряйте hit rate — если он ниже 50%, пересмотрите стратегию
- Начинайте с кэширования самых тяжёлых и частых запросов
Итог
Кэш — слой быстрого хранилища между приложением и источником данных. Правильно настроенный кэш с хорошим hit rate может ускорить приложение в десятки раз, но требует продуманной стратегии инвалидации.
Комментарии к уроку
Войдите, чтобы оставить комментарий.
Пока нет комментариев — будьте первым.