Ответ вслух Senior Кеширование обновлено

Согласованность кеша и базы

Вопрос

Как обеспечить согласованность кеша и базы при конкурентных записях? Какие гонки возможны?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Образцовый ответ: «Принимаю, что база это источник истины, а кеш в общем случае согласован в конечном счёте, и проектирую, насколько можно устареть.

Что должно прозвучать в ответе

  • Гонка: удаление до коммита и повторное заполнение старым значением

  • Гонка: два читателя кладут значения в разном порядке

  • Инвалидация после коммита, повторное удаление с задержкой

  • Версии и TTL как ограничение устаревания

  • Источник истины база, кеш допускает eventual consistency

  • Для критичных данных чтение из базы или блокировки

Что могут спросить следом

  • Что такое double delete?
  • Как инвалидировать кеш на нескольких серверах при кеше в памяти процесса?

Разбор

Образцовый ответ: «Принимаю, что база это источник истины, а кеш в общем случае согласован в конечном счёте, и проектирую, насколько можно устареть. Классическая гонка: запись удаляет ключ до коммита, параллельный читатель видит промах, читает из базы ещё старое значение и кладёт его в кеш, после чего коммит уже ничего не исправит. Поэтому удаляю ключ после коммита, через on_commit. Вторая гонка: медленный читатель прочитал старое значение до записи, а положил в кеш уже после инвалидации. От неё помогает повторное удаление с небольшой задержкой (double delete), запись в кеш с проверкой версии или просто короткий TTL. Версионирование ключей упрощает инвалидацию групп. Для кеша в памяти процесса на нескольких серверах нужен канал инвалидации, например pub/sub Redis, или очень короткий TTL. А для данных, где устаревание недопустимо, кеш не использую: читаю из базы с блокировкой».

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.