Короткий ответ
Кэш на уровне приложения даёт наибольшее снижение нагрузки на БД и самую низкую латентность, но добавляет слой инвалидации, за которым нужно следить; read replica снимает нагрузку на чтение без изменения логики кэша, но стоит дополнительной инфраструктуры и несёт риск replication lag; материализованное представление ускоряет конкретные дорогие агрегирующие запросы, но данные в нём устаревают до следующего REFRESH.
Как это работает подробнее
Кэш хранит готовый результат вне БД и отдаёт его без обращения к БД до инвалидации/TTL; read replica — полноценная копия БД для SELECT-запросов, не трогающая primary; materialized view — заранее вычисленный результат сложного запроса, обновляемый командой REFRESH, а не пересчитываемый на каждый SELECT.
Сравнение
- Компромисс. Можно комбинировать все три подхода на разных частях каталога, но каждый добавленный слой — это дополнительная операционная сложность и ещё одна точка, где данные могут временно расходиться; критерий выбора — приемлемая для бизнеса степень устаревания данных (секунды для кэша с коротким TTL, секунды-минуты для replica lag, минуты-часы для materialized view) и готовность команды поддерживать соответствующую инфраструктуру.
Пример кода
example.py
import json
import redis
r = redis.Redis()
def get_product(product_id: int) -> dict:
cache_key = f"product:{product_id}"
cached = r.get(cache_key)
if cached:
return json.loads(cached)
product = Product.objects.values().get(id=product_id)
r.setex(cache_key, 300, json.dumps(product, default=str)) # TTL 5 минут
return product
def on_product_updated(product_id: int):
r.delete(f"product:{product_id}") # явная инвалидация при изменении товараЧто использовать на практике
- Практика. Для данных, которые меняются редко и читаются по понятному ключу, кэш даёт наибольший выигрыш при разумной инвалидации по событию обновления; для разнородных запросов (поиск, фильтрация) часто проще read replica; materialized view хорошо подходит для тяжёлых агрегаций, не обязанных быть в реальном времени.
Подводные камни
- Ошибка. Добавляют кэш без продуманной стратегии инвалидации, получая устаревшие цены/наличие товара; используют read replica и считают проблему производительности полностью решённой, не замечая, что сама primary продолжает деградировать из-за записи.