Кэширование при масштабе: обзор с выбором ответа
Синтез всего раздела кэширования в формате с выбором ответа: стратегии чтения/записи и их консистентность, вытеснение и TTL, арифметика hit ratio, шардирование консистентным хешированием, стампида и анти-паттерн источника истины.
Шесть вопросов через весь раздел. Каждый — решение, что ты принимаешь, добавляя кэш, ревьюя дизайн кэширования или отлаживая его в проде: не определение для пересказа, а компромисс консистентности, арифметика hit ratio и сбои, видимые лишь при масштабе.
Убедись, что умеешь выбрать стратегию чтения/записи по её обещанию консистентности, выбрать политику вытеснения и TTL, превратить изменение hit ratio в нагрузку БД, шардировать кэш, не уничтожив его, распознать и починить стампиду и отвергнуть анти-паттерн кэш-как-источник-истины.
Нужно, чтобы кэш никогда не устаревал относительно базы на записях, а задержка записи не важна. Какая стратегия записи подходит и какова её цена?
Кэш на пределе памяти всё вытесняет главную (читаемую постоянно, вставленную при старте), сохраняя отчёт раз-в-день. Какая политика вытеснения настроена и какой должна быть?
Кэш перед 100 000 чтений/с падает с hit ratio 99% до 90% после деплоя. Во сколько раз растёт нагрузка чтения на базу?
Ты шардируешь кэш и хочешь, чтобы добавление или удаление узла тревожило как можно меньше кэша. Какая схема и почему не очевидная?
Один горячий ключ с TTL 60с отдаёт 50 000 RPS; каждые 60с базу бьёт всплеск тысяч идентичных запросов. Что это и самая прямая починка?
Дизайн пишет заказы только в Redis, подтверждает клиенту и сбрасывает в Postgres асинхронно, читая Redis как авторитетное значение. Каково ключевое возражение?
- 01Почему падение hit ratio 99%→90% плавит базу?
- 02Почему шардировать кэш консистентным хешированием, а не модуло, и как остановить стампиду горячего ключа?
Сквозная мысль: кэширование — набор осознанных компромиссов, а не переключатель. Стратегия записи фиксирует обещание консистентности: write-through никогда-не-устаревает-на-записи (два похода, churn), write-back быстрее всех, но лоссова и неконсистентна в окне сброса, write-around минует кэш (промах на первом чтении) — а read-path cache-aside допускает устаревшие чтения до TTL/инвалидации. Вытеснение должно учитывать доступ (LRU/LFU, не FIFO, никогда noeviction для кэша), а TTL ограничивает устаревание, но должен быть с джиттером. Число, что важно — это hit ratio, ведь база чувствует долю промахов: 99%→90% попаданий — это 10× всплеск нагрузки БД. Масштаб вширь требует консистентного хеширования (при rescale двигается лишь ~1/N ключей против массового ремаппинга модуло), переживает потерю узла репликацией (асинхронной, потому слегка устаревшей) и должен защищать стампиду через single-flight. А глубочайшее правило — что кэш это одноразовая копия авторитетного надёжного хранилища, никогда не источник истины. Прими эти шесть решений верно — и кэш делает чтения быстрыми, не делая систему хрупкой.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.