Вопрос с собеседования · System design

После обновления строки приложение записывает новое значение в кэш. Изредка в кэше навсегда остаётся устаревшее значение. Что происходит и как правильно?

SeniorКэширование и CDN
Ещё спрашивают так:
  • Почему в кэше остаётся устаревшее значение?
Коротко

Гонка: читатель прочитал старое из базы, писатель обновил базу и кэш, читатель записал старое поверх. Лечится удалением ключа вместо перезаписи плюс TTL и версиями.

  • База и кэш меняются независимо — общего порядка нет
  • Удаление идемпотентно и не зависит от порядка
  • TTL ограничивает время жизни ошибки; версия в значении не даёт записать старое поверх нового

А ещё Остаточная гонка удаления закрывается отложенным повторным удалением

Подробно

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

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

  • Пошаговый сценарий гонки.
  • Удаление вместо перезаписи.
  • TTL и версионирование как страховка.

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

  • Обновлять кэш записью нового значения и считать порядок операций гарантированным.
  • Задавать кэшу бесконечное время жизни, полагаясь только на явную инвалидацию.

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

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

Показать варианты и ответ
  • ✗Проблема в сериализации значения — нужно сменить формат на бинарный
  • ✓Гонка: читатель кладёт в кэш старое значение после записи писателя; надёжнее удалять ключ, а не перезаписывать
  • ✗Так и должно быть при кэшировании: значение обновится при следующей записи
  • ✗Кэш вытесняет свежие записи при нехватке памяти, а старые копии остаются; нужно увеличить объём кэша и срок жизни ключей

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

  • Почему инвалидация через журнал изменений базы надёжнее вызова из кода приложения?
  • Как быть, если удаление ключа из кэша не удалось, а транзакция уже зафиксирована?

Разбор темы

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

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

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

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

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