Вопрос с собеседования · Базы данных

Как работает паттерн cache-aside при чтении?

MiddleRedis и кэшированиеRedis
Ещё спрашивают так:
  • Что такое cache-aside?
  • Как кэшировать данные из базы в Redis?
Коротко

Cache-aside: приложение читает из кэша; при промахе идёт в базу, кладёт результат в кэш с TTL и возвращает. Источник истины — база.

  • При записи: обновить базу и удалить ключ из кэша
  • TTL ограничивает время расхождения
  • Риски: давка при истечении популярного ключа, кэширование несуществующего, гонки

А ещё Альтернативы: read-through (кэш сам ходит в базу), write-through

Подробно

Чтение:

  1. GET key из кэша;
  2. попадание — вернуть;
  3. промах — прочитать из базы, SET key value EX ttl, вернуть.

Запись: изменить данные в базе и удалить ключ (DEL key). Следующее чтение возьмёт свежие данные. Удаление вместо записи нового значения в кэш защищает от гонки, при которой старое значение перезаписывает новое.

Плюсы: просто, кэш содержит только то, что читают; при недоступности кэша можно читать из базы.

Что учесть:

  • TTL — даже при удалении ключей при записи: страховка от пропущенных инвалидаций;
  • давка — при истечении популярного ключа сотни запросов идут в базу: разброс TTL, пересчёт в один поток;
  • отрицательное кэширование — запоминать «не найдено», иначе запросы к несуществующим ключам всегда идут в базу;
  • сериализация и версия формата значения — при выкатке новая версия кода может прочитать старый формат.

Пример

def get_product(pid):
    if (cached := redis.get(f"product:{pid}")) is not None:
        return json.loads(cached)
    row = db.fetch_product(pid)
    redis.set(f"product:{pid}", json.dumps(row), ex=300 + random.randint(0, 60))  # TTL с разбросом
    return row

def update_price(pid, price):
    db.update_price(pid, price)
    redis.delete(f"product:{pid}")

Что хотят услышать

  • Шаги чтения и записи.
  • Удаление ключа при записи и почему.
  • TTL, давка, отрицательное кэширование.

Частые ошибки

  • Кэш без TTL.
  • Перезаписывать значение в кэше при записи.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Читаем кэш; при промахе — БД, и результат кладём в кэш
  • ✗Пишем и читаем только из кэша, минуя БД
  • ✗Читаем БД и параллельно обновляем кэш
  • ✗Кэш обновляется лишь по расписанию раз в сутки

Что спросят дальше

  • Что такое cache stampede?
  • Когда write-through лучше cache-aside?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования