awesome-everything EN
↑ Обратно к восхождению

Кеширование

Cache stampede: собрать и укротить стадо

Суть Практический проект — собрать stampede-склонный cache-aside сервис, воспроизвести стадо, наслоить митигации и доказать каждый шаг числами до/после.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 240 min

Читать про stampede — не то же, что смотреть, как падает твоя БД, а потом возвращать её к жизни. Соберите небольшой cache-aside сервис, специально загоните горячий ключ в stampede и добавляйте митигации юнита слой за слоем — измеряя стадо до и после каждого.

Цель

Превратите ментальную модель юнита в воспроизводимый цикл: воспроизведите всплеск, инструментируйте отпечаток, затем наслоите single-flight, distributed lock, SWR, TTL-джиттер и negative caching — доказывая метриками, что каждый слой ограничивает то стадо, которое должен.

Проект
0 из 7
Цель

Соберите cache-aside HTTP-сервис на Redis и нарочито медленном origin, воспроизведите cache stampede на горячем ключе, затем наслаивайте митигации юнита, пока всплеск на границе TTL не достигнет origin как единственный rebuild — доказывая каждый шаг измерениями до/после, а не оценками.

Требования
Критерии приёмки
  • Таблица до/после на каждую митигацию: origin-запросы на границу TTL, p99 латентность запроса и rate промахов кеша — всё измерено под идентичным нагрузочным тестом, а не оценено.
  • С включённым полным стеком граница TTL под устойчивой нагрузкой на горячий ключ даёт не более одного origin-rebuild, а пилообразный отпечаток origin-запросов исчез из метрик.
  • Демонстрация, что single-flight в одиночку оставляет один rebuild на инстанс, и только добавление межнодового lock (или фонового обновления SWR) сворачивает его к одному на весь флот — доказывая, что вы понимаете область действия каждого слоя.
  • Короткое описание: для каждого слоя назвать, какое именно стадо он ограничил (внутри процесса, всего флота, время ожидания, многоключевое, негативное) и почему этот слой понадобился поверх предыдущего.
Senior-стретч
  • Реализуйте XFetch probabilistic early expiration на горячем ключе и покажите, что он обновляет до границы с ~1 ранним rebuild на окно и нулём промахов при истечении; затем покажите, что он проигрывает на холодном ключе, читаемом раз в TTL.
  • Добавьте проверку fencing-token (или монотонной версии) на запись rebuild и сконструируйте тест, где EX lock'а короче медленного rebuild, доказав, что guard отвергает устаревшую дублирующую запись.
  • Воспроизведите metastable failure: добавьте клиентские ретраи с коротким backoff, доведите origin до насыщения и покажите, что он остаётся прибитым после снятия нагрузки; затем разорвите цикл шлюзом 503-on-overload и измерьте время восстановления.
  • Добавьте minimum-viable dashboard с алертами (всплеск rate промахов, пилообразный rate origin, lock-wait выше rebuild p99) и одностраничный on-call runbook: триаж по панелям, лестница митигаций и gate 'прогреть кеш до переключения трафика'.
Итог

Это цикл, который вы будете прогонять на любом реальном слое кеша: воспроизведите всплеск, прежде чем доверять фиксу, инструментируйте отпечаток, затем добавляйте митигации в порядке областей — single-flight для стада процесса, lock для стада флота, SWR для ожидания, джиттер для синхронного многоключевого истечения, negative caching для miss-storm — и проверяйте каждый числами до/после под идентичной нагрузкой. Сделать это раз на игрушечном сервисе — вот что превращает продакшен-версию и инцидент в 3 ночи в мышечную память.

Продолжить восхождение ↑ETag и условные запросы: 304 экономит байты, но не round-trip
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.