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

Сети и протоколы

Многоуровневый кеш и Cache-Control

Суть Как edge-кеш, origin shield и директивы Cache-Control работают вместе, чтобы 90%+ запросов никогда не достигали origin — и что задавать для каждого типа контента.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 12 min

CDN стоит перед origin, но alarm origin по-прежнему срабатывает при каждом деплое. Новые пользователи промахиваются по кешу, каждый edge POP одновременно запрашивает origin — и вдруг 200 edge-серверов генерируют 200 параллельных запросов к origin для одного и того же некешированного URL. Это не баг — это отсутствие архитектурного слоя: origin shield.

Четырёхуровневая иерархия кешей

Когда браузер делает запрос, четыре кеша могут ответить до origin:

  1. Кеш памяти браузера (~субмс, живёт в рамках вкладки)
  2. Дисковый кеш браузера (~10 мс, сохраняется между вкладками)
  3. Кеш CDN edge POP (~20–50 мс по сети от пользователя)
  4. CDN origin shield / региональный кеш (~50–100 мс)

Только если все четыре промахиваются, отвечает origin (~100–300 мс в зависимости от географии). Каждый слой подчиняется одним и тем же директивам Cache-Control, но применяет их независимо.

Директивы Cache-Control

Заголовок ответа Cache-Control сообщает каждому кеширующему слою, что делать с ответом:

ДирективаЗначение
max-age=3600Свежий 1 час в любом кеше: браузер и CDN
s-maxage=86400Свежий 1 день только в CDN (браузер игнорирует s-maxage)
publicЛюбой кеш (браузер, CDN, прокси) может хранить
privateТолько кеш браузера; CDN не должен хранить
no-storeНи один кеш не может хранить этот ответ
no-cacheПеред отдачей хранимой копии нужна ревалидация с origin
stale-while-revalidate=604800Отдавать устаревшее до 7 дней, обновляя в фоне
immutableНе ревалидировать — содержимое по этому URL никогда не изменится

Важнейшее правило: без Cache-Control: public (или s-maxage) CDN проксирует насквозь — кеширования не происходит. Заголовки ответа origin управляют кешируемостью; CDN не может кешировать то, что origin не разрешает.

Cache-Control по типу контента
Статические ассеты (JS/CSS с content-hash)
public, max-age=31536000, immutable
Изображения (с хешем в URL)
public, max-age=31536000, immutable
HTML-страницы (часто обновляемые)
public, max-age=300, stale-while-revalidate=3600
API-ответы (публичные, read-only)
public, s-maxage=60, stale-while-revalidate=600
User-specific API (требует auth)
private, no-store
Страницы оформления заказа
no-store

Архитектура origin shield

В каждом регионе CDN может быть десятки edge POP. Без shield промах кеша для популярного URL во всех 200 POP генерирует 200 одновременных запросов к origin — thundering herd (эффект гремящего стада).

Origin shield (называемый «Tiered Cache» у Cloudflare, «Origin Shield» у Fastly — одна фича) — это региональный промежуточный кеш между edge POP и origin. Все edge POP в регионе направляют промахи через один shield-узел. Shield поддерживает бо́льший кеш и обычно поглощает 90%+ промахов без обращения к origin.

Сценарий для «холодного» URL:

  1. 200 edge POP промахиваются одновременно.
  2. Все 200 пересылают запрос к региональному shield.
  3. Shield отправляет один запрос к origin; остальные 199 ставятся в очередь.
  4. Origin отвечает один раз; shield распространяет ответ на все 199 ожидающих edge.
  5. Origin увидел 1 запрос вместо 200.

Версионирование статических ассетов: избавиться от инвалидации

Умнейший трюк с кешем: включить content hash в имя файла (например, app.f3a2b8c.js). Задать max-age=31536000, immutable (1 год). Когда файл меняется — меняется хеш, меняется URL — в кеше нет записи для нового URL, и он автоматически загружается свежим. Purge не нужен. Это делают автоматически: Webpack, Vite, esbuild, Astro.

Паттерны инвалидации кеша (когда всё-таки нужны)

  1. Истечение TTL — ждать, пока истечёт max-age. Дёшево, без API-вызовов, но медленно при срочных исправлениях.
  2. Явный purge — API-вызов CDN: POST /purge {"url": "/api/products"}. Быстро, но медленно при purge тысяч URL на деплое.
  3. Cache tags — теговать ответы на origin (Cache-Tag: article-1001), чистить по тегу (POST /purge {"tag": "article-1001"}). Максимальная гибкость; требует enterprise-тира CDN (Fastly, Cloudflare Enterprise).

Условные запросы и 304 Not Modified

После истечения локального кеша браузер ревалидирует с If-None-Match: <etag>. Если ответ не изменился, CDN (или origin) возвращает 304 Not Modified — пустое тело, экономия трафика. CDN прозрачно обрабатывает ETag для кешируемых ответов, пересылая к origin только при реально изменившемся ETag.

Викторина

Что делает директива s-maxage в отличие от одного max-age?

Викторина

Почему URL статических ассетов обычно содержат content hash (например, app.f3a2b8c.js)?

Проследи
1/5

Трассировка холодной загрузки страницы статьи через всю иерархию CDN-кеша.

1
Step 1 of 5
Браузер DNS-резолвит hostname. Что получает?
2
Locked
Браузер открывает TCP + TLS к edge. Edge проверяет локальный кеш — промах. Куда форвардит?
3
Locked
Origin отвечает. Что несёт ответ, чтобы быть кешируемым?
4
Locked
Shield кеширует ответ и форвардит к edge. Edge кеширует и возвращает браузеру. Следующий пользователь запрашивает тот же URL в течение 3600 секунд?
5
Locked
Вы деплоите новую версию статьи. max-age=3600, прошло только 10 минут. Как пользователи получат новую версию?
Расставь шаги по порядку

Упорядочите директивы Cache-Control от наиболее кешируемой к наименее:

  1. 1 public, max-age=31536000, immutable — 1 год, никогда не перезагружается
  2. 2 public, max-age=3600 — 1 час в любом кеше
  3. 3 public, max-age=60, stale-while-revalidate=600 — 60 с свежести, затем устаревшая версия 10 мин
  4. 4 private, max-age=300 — только браузер, 5 мин
  5. 5 no-cache — кеши обязаны ревалидировать при каждом запросе
  6. 6 no-store — ни один кеш не может хранить это вообще
Вспомните перед уходом
  1. 01
    Почему URL-версионирование с content-hash предпочтительнее ручного purge для статических ассетов?
  2. 02
    Origin shield стоит между edge и origin. 200 edge одновременно промахиваются по одному URL. Сколько запросов генерирует shield к origin?
  3. 03
    HTML-страница имеет Cache-Control: public, max-age=3600. Вы пушите hotfix. Пользователи видят старую страницу до 1 часа. Как сделать, чтобы все CDN edge раздавали новую версию за секунды?
Итог

Иерархия CDN-кеша имеет четыре слоя — память браузера, диск браузера, edge POP и origin shield — каждый подчиняется одним директивам Cache-Control. Ключевые директивы: max-age задаёт окно свежести для всех кешей; s-maxage переопределяет его только для shared-кешей (CDN); private исключает CDN-кеширование; no-store запрещает любое кеширование. Origin shield предотвращает thundering herd, сворачивая все edge-промахи в регионе в один запрос к origin. URL с content-hash и immutable, max-age=31536000 полностью устраняют проблему инвалидации кеша для статических ассетов. Для изменяемого контента выбирайте между истечением TTL (просто), purge по URL (быстро, но URL-специфично) или purge по cache-тегу (гибко, требует enterprise-тира).

Связанные уроки
встречается в162
Продолжить восхождение ↑Заголовок Vary и cache keys
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.