CDN, статика и алгоритмы вытеснения

Доставить байты быстрее можно двумя путями: приблизить их географически (CDN) и грамотно решать, что хранить (вытеснение).

CDN (Content Delivery Network) — сеть серверов по всему миру, кэширующих статику ближе к пользователю, чтобы сократить задержку и разгрузить основной сервер.

Зачем нужен CDN

Если ваш сервер в Москве, а пользователь в Бразилии, каждый запрос летит через океан — это сотни миллисекунд только на дорогу. CDN держит копии файлов на edge-серверах рядом с пользователями. Бразилец получает картинку с ближайшего узла, а не из Москвы.

Что даёт CDNКак именно
Меньше задержкаконтент рядом с пользователем географически
Разгрузка серверастатику отдаёт CDN, а не ваши серверы
Защита от пиковedge поглощает всплески и часть DDoS
Экономия полосытяжёлые файлы не гоняются через ядро

Что отдавать через CDN

Идеальные кандидаты — статика, одинаковая для всех: картинки, видео, JS, CSS, шрифты. Динамический персональный контент (личная лента) кэшировать на CDN сложнее, хотя современные CDN умеют и это. Чтобы обновить файл, меняют его имя (версионируют: app.4f2a.js) — старое имя остаётся в кэшах, новое скачивается свежим. Это обходит проблему инвалидации у миллионов клиентов.

Почему нужна политика вытеснения

Память кэша конечна. Когда она заполнена, а пришёл новый элемент, что-то надо выкинуть. От выбора «жертвы» напрямую зависит hit rate. Хорошая политика выкидывает то, что вряд ли скоро понадобится.

Алгоритмы вытеснения

ПолитикаКого выкидываетИдея / когда хороша
LRU (Least Recently Used)давно не используемыйставка на локальность во времени; самый ходовой выбор
LFU (Least Frequently Used)реже всего используемыйхорош, когда популярность стабильна
FIFOсамый старый по добавлениюпрост, но игнорирует частоту использования
Randomслучайныйдёшево, без структур учёта
TTL-basedистёкший по срокукогда у данных естественный срок свежести

LRU — почему он по умолчанию

LRU выкидывает элемент, к которому дольше всего не обращались. Логика проста: если данные давно не нужны, скорее всего, не понадобятся и дальше. LRU отлично ловит временну́ю локальность (только что использованное вероятно используется снова) и реализуется за O(1) на хеш-таблице плюс двусвязном списке. Поэтому Redis и большинство кэшей берут его по умолчанию.

Кэш на 3 элемента, политика LRU:
доступ A, B, C        → [A B C]
доступ A (освежили)   → [B C A]
новый  D (нет места)  → выкидываем B (давний) → [C A D]

Итог

  • CDN приближает статику к пользователю, режет задержку и разгружает сервер; обновляют через версионирование имён.
  • Память кэша конечна — нужна политика вытеснения, она определяет hit rate.
  • LRU выкидывает давно не используемое, ловит временну́ю локальность и работает за O(1) — потому он по умолчанию.
Проверьте себя
1. Главная польза CDN — это…
Aхранение базы данных ближе к серверу
Bдоставка статики с серверов, географически близких к пользователю, что снижает задержку
Cускорение записи в базу
Dзамена балансировщика нагрузки
2. Что выкидывает алгоритм LRU при заполнении кэша?
Aсамый часто используемый элемент
Bэлемент, к которому дольше всего не обращались
Cсамый новый элемент
Dслучайный элемент
3. Как обычно обновляют файл в CDN, чтобы не сбрасывать кэш у миллионов клиентов?
Aвручную чистят кэш на каждом устройстве
Bверсионируют имя файла (app.4f2a.js), и новое имя скачивается свежим
Cотключают CDN на время
Dуменьшают TTL до нуля
Поддержать проект