Этот вопрос проверяет, умеешь ли ты проектировать кеш так, чтобы он ускорял систему и при этом не ломал актуальность данных и устойчивость.
Обычно кеширование делают так: данные сначала ищут в кеше, а если там нет — берут из источника (БД/API) и кладут в кеш с TTL. Ключи кеша делают стабильными и понятными (например, user:123:profile:v1). Важно заранее продумать, как кеш будет обновляться: через TTL, явную инвалидацию при изменениях или их комбинацию. Ещё нужно учитывать проблемы вроде “толпы” запросов при истечении TTL и “устаревших” данных.
Кеширование — это не “положить в Redis и забыть”, а набор решений: что кешируем, как называем ключи, как долго живут данные и как не сломать консистентность.
Кеширование — это хранение копии часто запрашиваемых данных в более быстром месте, чтобы уменьшить задержки и нагрузку на основной источник.
Пробуем прочитать из кеша по ключу.
Если ключ есть — возвращаем данные.
Если ключа нет — читаем из БД/сервиса, сохраняем в кеш с TTL, возвращаем.
Небольшой пример:
import json
def get_user_profile(user_id, redis, db):
key = f"user:{user_id}:profile:v1"
cached = redis.get(key)
if cached:
return json.loads(cached)
data = db.load_user_profile(user_id) # запрос в БД
redis.setex(key, 300, json.dumps(data)) # TTL 5 минут
return data
Частые чтения и редкие изменения (справочники, профили, настройки).
Тяжёлые вычисления (агрегации, отчёты), если допустима небольшая задержка актуальности.
Внешние API, где дорого или медленно ходить.
Просто и надёжно.
Подходит, если допустима “примерная актуальность”.
При обновлении записи в БД удаляем/обновляем ключ кеша.
Важно обеспечить, чтобы это было сделано всегда (иначе “вечная” устаревшая копия).
Часто лучший практический вариант: TTL как страховка, инвалидация как основной механизм.
Ситуация: TTL истёк, много запросов одновременно пошли в БД.
Решения:
Лок/“одиночный пересчёт” (один запрос строит кеш, остальные ждут или получают старое).
“Мягкий TTL”: заранее обновлять кеш до полного истечения.
Джиттер: добавлять случайность к TTL, чтобы ключи не истекали одновременно.
Ситуация: ключа нет и в БД тоже нет → каждый раз промах.
Решения:
Кешировать “пустой результат” на короткий TTL.
Проверять валидность входных данных раньше.
Решения:
Чётко определить SLA актуальности (например, “данные могут отставать до 5 минут”).
Для критичных данных не кешировать, либо использовать короткий TTL/явную инвалидацию.
Хороший кеш строится вокруг паттерна cache-aside, понятных ключей, TTL и продуманной инвалидации, а также защиты от массовых промахов и устаревания.