Получить доступ

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

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

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

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

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

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

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

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

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

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

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

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

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

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

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

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

Разбор темы

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

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем