Сеть доставки контента решает не просто задачу кэша ближе к пользователю. Это система про географию трафика, иерархию кэшей, свежесть данных и защиту исходного слоя под глобальной нагрузкой.
Глава помогает связать маршрутизацию через систему доменных имен, точки присутствия, промежуточный защитный слой и время жизни объектов в одну архитектуру, где скорость ответа постоянно спорит со свежестью контента.
В интервью и инженерных обсуждениях этот кейс быстро показывает, умеете ли вы мыслить за пределами одного региона, считать цену промаха кэша и защищать исходное хранилище при массовом трафике.
География трафика
Важно управлять тем, куда именно попадает пользовательский запрос: через маршрутизацию, ближайшую точку присутствия и резервные пути при сбое региона.
Иерархия кэшей
Пограничный кэш, промежуточный защитный слой и исходное хранилище должны работать как единая цепочка, а не как набор независимых узлов.
Свежесть контента
Нужно заранее определить, где хватает времени жизни, где нужен принудительный сброс, а где обязательны версионированные URL.
Защита исходного хранилища
При промахах кэша и резких всплесках трафика важно ограничить число одновременных обращений к исходному хранилищу, объединять одинаковые запросы и иметь понятный режим деградации.
— это географически распределённая сеть серверов, которая кэширует и отдаёт контент пользователям из ближайшей . Когда аудитория размазана по континентам, каждый поход до исходного сервера добавляет заметную задержку только на дорогу. Сеть доставки контента переносит ответ ближе к пользователю: уменьшает и снимает значительную часть нагрузки с исходных серверов.
Источник
Acing the System Design Interview
Подробный разбор архитектуры сети доставки контента, инвалидации кэша и ключевых компромиссов.
Зачем нужна сеть доставки контента?
- Снижение задержки: контент приходит с ближайшего пограничного узла
- Разгрузка исходного слоя: большая часть запросов завершается до обращения к исходному серверу
- Масштабируемость: трафик распределяется по регионам и точкам присутствия
- Отказоустойчивость: при сбое одной точки присутствия трафик можно увести на соседнюю
- Защита от массовых атак: распределённая инфраструктура лучше выдерживает всплески и злонамеренную нагрузку
Функциональные требования
Основные возможности
- Кэширование статического контента
- Географическая маршрутизация трафика
- Инвалидация и обновление кэша
- Переключение на резервный исходный сервер
Дополнительные возможности
- Ускорение динамического контента
- Выполнение простых вычислений на периферии
- Завершение защищённого соединения
- Преобразование запросов и ответов
Нефункциональные требования
| Требование | Целевое значение | Обоснование |
|---|---|---|
| Задержка | < 50 мс на 99-м перцентиле | Пользователь не должен ждать начало загрузки |
| Доля попаданий в кэш | > 95% | Минимизировать нагрузку на исходный слой |
| Доступность | 99.99% | Это критическая часть внешнего контура сервиса |
| Пропускная способность | Tbps+ | Нужно выдерживать глобальный трафик и пиковые всплески |
Архитектура сети доставки контента
Компоненты системы
1. Маршрутизация через систему доменных имен
На входе работает . В глобальном контуре её часто дополняют GeoDNS и , чтобы направить пользователя в ближайшую точку присутствия с минимальной задержкой.
2. Пограничные узлы в точках присутствия
Эти узлы принимают пользовательские запросы, отдают данные из локального кэша и при необходимости проксируют запрос глубже по цепочке.
3. Промежуточный защитный слой
Промежуточный собирает промахи кэша от множества точек присутствия и не даёт исходному слою получить лавину одинаковых запросов.
4. Исходный сервер
Это сервер или объектное хранилище, к которому сеть обращается только тогда, когда контент не найден в промежуточных кэшах.
Путь запроса через сеть доставки контента
Готово к запуску
Нажмите кнопку, чтобы показать путь запроса.
Предварительная загрузка и кэширование по запросу
Выбор сводится к одному вопросу: знаем ли мы заранее, что попросят. Известный и критичный для первой загрузки контент можно разложить по узлам заранее. А вот библиотеку, которая постоянно меняется и состоит в основном из , раскладывать целиком бессмысленно — здесь чаще выбирают . Цена у него очевидна: первый пользователь платит за .
Предварительная загрузка
Контент раскладывается по узлам заранее, ещё до первого пользовательского запроса.
Преимущества:
- Нет задержки первого обращения
- Предсказуемая производительность
- Полный контроль над распространением
Ограничения:
- Нужно заранее управлять выкладкой
- Редкий контент занимает место зря
- Сложнее поддерживать синхронность между регионами
Кэширование по запросу
Контент попадает на пограничный узел только после первого запроса пользователя.
Преимущества:
- Автоматически подстраивается под реальный спрос
- Экономит место на редком контенте
- Проще в эксплуатации
Ограничения:
- Первый запрос платит за промах кэша
- Промахи увеличивают нагрузку на исходный слой
- Задержка менее предсказуема
Инвалидация кэша
Свежестью на пограничных узлах управляют тремя рычагами, и забыть про любой из них дорого. Слишком большое — и пользователь видит устаревшие данные; нет понятного механизма принудительного сброса — и срочную правку не выкатить; нет правила, что обновлять в фоне, а что нет, — и каждое протухание превращается в промах до исходного слоя.
Стратегии инвалидации кэша
Истечение по TTL
Контент автоматически перестаёт считаться свежим после заданного времени жизни.
Преимущества
- •Простая настройка через HTTP-заголовки
- •Не требует интеграции с API провайдера
- •Предсказуемое поведение кэша
Ограничения
- •Обновление ждёт истечения TTL
- •Сложно подобрать правильное значение
- •Нет мгновенной инвалидации
Стратегии кэширования
Что стоит кэшировать?
| Тип контента | Кэшируемость | Рекомендуемое время жизни |
|---|---|---|
| Статические файлы (JS, CSS) | Высокая | 1 год с версионированием |
| Изображения | Высокая | От 1 месяца до 1 года |
| HTML-страницы | Средняя | От 5 минут до 1 часа |
| Публичные API-ответы | Средняя | От 1 минуты до 1 часа |
| Персонализированный контент | Низкая | Обычно не кэшировать |
Проектирование ключа кэша
Ключ кэша определяет, какие версии контента считаются разными объектами. Ошибка на этом уровне приводит либо к загрязнению кэша, либо к низкой доле попаданий.
# Простой ключ (только URL):
cache_key = hash(url)
# Расширенный ключ:
cache_key = hash(url + headers["Accept-Encoding"] +
headers["Accept-Language"] +
query_params["version"])
# Заголовок Vary указывает, какие поля включать в ключ:
Vary: Accept-Encoding, Accept-LanguageБезопасность и защита исходного слоя
Внешний контур сети первым встречает и атаку, и трафик, который нужно расшифровать, — а значит, и проектировать его приходится с обоих краёв сразу. Отсюда четыре опоры: защита от , корректное завершение , а также политики вроде и проверки сертификатов через .
Защита от массовых атак
- Ограничение частоты запросов на пограничном узле
- Эникаст для распределения всплесков трафика
- Центры очистки трафика
- Выявление ботов и аномалий
Шифрование соединений
- Завершение защищённого соединения на пограничном узле
- Общие и выделенные сертификаты
- Шифрование соединения с исходным сервером
- Строгая политика HTTPS и stapling статуса сертификатов
Контроль доступа
- Подписанные URL и cookies
- Токены доступа
- Белые списки IP-адресов
- Ограничения по географии
Защита исходного слоя
- Промежуточный защитный слой
- Объединение одинаковых запросов
- Скрытое имя исходного сервера
- Правила межсетевого экрана только для IP-адресов сети доставки
Метрики и наблюдаемость
Три метрики показывают, действительно ли сеть работает на пользователя: отвечает за ощущение скорости, доля ответов из кэша — за разгрузку, а объём трафика до исходного слоя показывает, сколько защита на самом деле не удержала.
Процент запросов, обслуженных без похода в исходный слой
Скорость, с которой пользователь получает первый байт ответа
Объём переданных данных и всплески по регионам
Ключевые алерты:
- Доля попаданий в кэш < 90% → проверить время жизни и структуру ключей
- Ошибки исходного слоя > 1% → проблема в исходном хранилище или промежуточной защите
- Время до первого байта на 99-м перцентиле > 100 мс → проверить маршрутизацию и путь до исходного слоя
- Резкий всплеск трафика → возможна атака или внезапный рост популярности контента
Вопросы на интервью
Как обеспечить согласованность при инвалидации кэша?
Использовать версионированные URL для неизменяемого контента, API принудительного сброса для срочных обновлений и подходы вроде устаревший ответ с фоновой повторной проверкой там, где допустим короткий период устаревших данных.
Как защитить исходный слой от лавины одинаковых запросов при промахе кэша?
Использовать объединение одинаковых запросов, защитный слой исходного хранилища, и предварительный прогрев кэша для популярных объектов.
Когда выбирать предварительную загрузку, а когда кэширование по запросу?
Предварительная загрузка подходит для ограниченного набора критичного контента. Кэширование по запросу лучше работает для больших библиотек и длинного хвоста редко востребованных объектов.
Как работать с динамическим контентом?
Использовать , кэширование фрагментов, короткое время жизни с фоновой повторной проверкой или для сборки персонализированного ответа ближе к пользователю.
Ключевые выводы
- 1.На глобальном масштабе сеть доставки контента решает сразу две задачи: держит задержку близкой к пользователю и не даёт исходному слою захлебнуться трафиком.
- 2.Инвалидация кэша остаётся главным источником сложности, поэтому время жизни, версионирование и принудительный сброс нужно проектировать вместе.
- 3.Защитный слой исходного хранилища снижает число одновременных обращений к исходному серверу и помогает переживать массовые промахи кэша.
- 4.Выбор между предварительной загрузкой и кэшированием по запросу зависит от характера контента, требований к свежести и цены промаха.
- 5.Если из всех метрик смотреть на две, берите долю попаданий в кэш и время до первого байта — они точнее всего показывают, что сеть доставки контента меняет в пользовательском пути.
Связанные главы
- Acing the System Design Interview (краткий обзор) - даёт базовую рамку для разбора кейса: требования, оценка масштаба, архитектура и ключевые компромиссы.
- Object Storage (S3) - раскрывает исходный слой: хранение объектов, долговечность, жизненный цикл данных и поведение при промахе кэша.
- Designing Data-Intensive Applications, 2nd Edition (short summary) - усиливает фундамент по репликации, консистентности и распределённым компромиссам в глобальной сети доставки.
- Стратегии кэширования: ленивое заполнение, чтение через кэш и запись через кэш - дополняет практику выбора времени жизни, инвалидации и управления долей попаданий в кэш на пограничных узлах.
- Лента видеохостинга - показывает тяжёлый медиасценарий, где геораспределённая доставка и защита исходного слоя становятся критичными.
- Система доменных имен (DNS) - поясняет маршрутизацию через систему доменных имен и выбор ближайшей точки присутствия с помощью GeoDNS и эникаста.
- Примеры задач по системному дизайну - ставит задачу про сеть доставки контента в общий контекст интервью и облегчает сравнение с другими архитектурными кейсами.
- Uber/Lyft - даёт пример глобальной системы с жёсткими требованиями по задержке, где распределение трафика между регионами критично.
- URL Shortener (TinyURL) - показывает смежный сценарий с глобальными редиректами, где ответ ближе к пользователю разгружает исходный слой.
