Video Hosting (YouTube-like) — TUS resumable upload, FFmpeg/GPU transcoding pool with CMAF/HLS multi-bitrate ladder, Kafka job queue, S3 raw + variants, mid-tier + edge CDN PoPs, ABR player with quality switching, view counter via Redis HLL, Cassandra watch history, Postgres meta, Elasticsearch search, recsys, plus live streaming RTMP -> LL-HLS pipeline. Five scenarios: upload+transcode, playback ABR with quality downshift, viral CDN cache hit, view counter at scale, live streaming with packet loss recovery. ADR-001: pre-transcode vs JIT. ADR-002: HLS vs DASH vs CMAF.
Video hosting соединяет почти все крупные системные темы: resumable upload, object storage, message queue, transcoding, CDN, adaptive bitrate streaming, metadata APIs, search, recommendations, counters, watch history и live streaming. Это хороший case study, потому что у него два разных мира: creator upload pipeline и viewer playback path. Первый терпит минуты обработки, второй требует низкой задержки и плавного воспроизведения.
Масштаб YouTube-like продукта экстремальный. Сотни часов видео загружаются каждую минуту, ежедневный прирост storage может измеряться petabytes, а просмотренные часы создают terabits per second egress. Поэтому архитектура не может отдавать видео из application servers. Нужны object storage для origin, transcode pipeline для renditions, CDN edge caches для доставки и ABR player, который адаптируется к сети пользователя.
Связанные темы: ::concept{slug="object-storage-s3"}, ::concept{slug="cdn-design"}, ::concept{slug="message-queues"}, ::concept{slug="search-engine"}, ::concept{slug="caching-patterns"}, ::concept{slug="back-of-envelope"}.
Ментальная модель: видео платформа это control plane и data plane. Control plane хранит metadata: video id, uploader, title, visibility, status, manifest URI, thumbnails, comments, likes, moderation state. Data plane переносит байты: upload raw video, transcode to ladder, store segments, deliver through CDN.
Upload path асинхронный. Creator загружает файл через TUS или multipart upload на upload edge. Raw file попадает в S3-like origin. Затем Kafka job отправляет video id в transcoder pool. Workers читают raw, генерируют HLS/DASH/CMAF renditions: 240p, 360p, 480p, 720p, 1080p, иногда 4K и AV1. Когда manifest готов, metadata API переводит видео в ready.
Playback path синхронный для пользователя. Viewer получает metadata и signed manifest URL, скачивает master playlist, выбирает bitrate по текущей сети и буферу, запрашивает маленькие segments у CDN. Если edge cache hit, origin не участвует. Если miss, edge идет к mid-tier/origin shield и затем к object storage.
ABR важнее, чем кажется. Пользователь не скачивает один MP4 целиком. Он получает последовательность segments и может переключаться между rungs на границе segment, чтобы избежать buffering.
Диаграмма показывает Upload + Transcode plane: creator, upload edge, S3 raw origin, transcode queue, FFmpeg/GPU workers и S3 HLS variants. Это объясняет, почему upload не должен блокироваться на transcoding: пользователь может завершить загрузку быстро, а обработка идет асинхронно.
Metadata plane включает Video API, Postgres для video metadata, Cassandra для watch history, Elasticsearch для поиска, Redis HyperLogLog для view counters и recommendation service. Разные хранилища выбраны под разные access patterns: Postgres для сущностей, Cassandra для append-heavy per-user history, Elasticsearch для search, Redis для high-QPS counters.
Delivery plane показывает CDN edge PoP, mid-tier/origin shield и viewer. Это ключевой cost и latency слой. Горячее видео должно обслуживаться с edge cache; origin должен видеть лишь небольшую долю запросов.
Live streaming plane показывает streamer, RTMP ingest, live transcoder и live edge. Live отличается от VOD: segments короткоживущие, latency важнее compression efficiency, а failure recovery должен быть быстрее.
Upload + transcode показывает asynchronous processing. Файл загружается chunked/resumable, затем raw сохраняется в object storage, job попадает в Kafka, worker генерирует ladder и обновляет metadata. Урок: transcode jobs должны быть idempotent, с lease/timeout, retry и dead-letter queue, потому что FFmpeg может падать на corrupt input.
Playback ABR показывает, что player сначала получает manifest, затем выбирает 720p или другой rung по bandwidth estimate. Когда сеть деградирует, player переключается на 480p на следующем segment boundary. Урок: aligned CMAF/HLS segments позволяют менять качество без разрыва воспроизведения.
CDN hot video показывает viral spike. 100 тысяч viewers не должны создать 100 тысяч origin requests. Edge cache, request collapsing, mid-tier и origin shield превращают это в один fill на PoP или region. Immutable video segments можно кэшировать долго, что сильно снижает egress from origin.
View counter scenario показывает, почему нельзя делать UPDATE videos SET views = views + 1 на каждый просмотр. Viral видео создаст hot row. Redis counters и HyperLogLog дают быстрый approximate unique count, а Postgres получает rollup асинхронно.
Live streaming scenario показывает другую latency model. OBS отправляет RTMP в ingest, live transcoder делает LL-HLS segments, CDN доставляет rolling window. При packet loss нужны dual ingest, buffers и быстрый failover. Для интерактивного live может потребоваться WebRTC, но для массового просмотра LL-HLS проще масштабировать.
Pre-transcode против JIT. Полный pre-transcode дает лучший viewer experience и простой CDN cache, но storage умножается на несколько renditions. JIT экономит storage для long tail, но первый viewer может ждать transcode. Hybrid часто разумен: популярные rungs precompute, 4K/AV1 для long-tail генерировать по спросу.
HLS, DASH и CMAF. HLS хорошо поддерживается Apple ecosystem, DASH удобен в web/Android, CMAF позволяет хранить один набор fragmented MP4 segments и отдавать разные manifests. Цена CMAF: сложнее packager и edge cases с legacy devices.
CDN cache TTL. Длинный TTL идеален для immutable segments, но metadata, manifests и live playlists требуют короткого TTL или cache invalidation. Ошибка в TTL может либо перегрузить origin, либо показать старый state.
Counters: exact vs approximate. Точные unique views требуют много памяти и dedup state. HyperLogLog дает небольшую ошибку, но масштабируется. Для денег и billing approximation недопустима, для public view count обычно приемлема.
Recommendations повышают watch time, но добавляют privacy, feedback loops и cold start. На архитектурной диаграмме recsys лучше держать отдельным сервисом, а не смешивать с playback critical path.
YouTube использует глобальную CDN/edge инфраструктуру, массовый transcoding, search, recommendations и live streaming. Netflix похож в delivery части, но catalog curated и заранее кодируется per-title encoding, а upload от пользователей отсутствует. Twitch делает упор на live ingest, chat и low latency. Vimeo ближе к creator-focused hosting. TikTok добавляет short-video feed, aggressive recommendations и mobile-first upload.
Для building blocks используются S3/GCS/Azure Blob или внутренние object stores, Kafka/PubSub для jobs, FFmpeg/NVENC/ASIC encoders для transcoding, HLS/DASH/CMAF для delivery, Cassandra/Bigtable-like stores для watch history, Elasticsearch/OpenSearch для поиска.
Первый anti-pattern: отдавать видео через application servers. Это быстро приводит к огромному egress bill, плохой latency и падению API при viral spike.
Второй anti-pattern: синхронно ждать full transcode в upload request. HTTP request истечет, retry создаст дубли, а creator получит плохой UX. Нужны background jobs и status transitions.
Третий anti-pattern: хранить только один bitrate. Пользователи на мобильной сети будут буферизоваться, а пользователи с хорошей сетью получат низкое качество. ABR ladder обязателен.
Четвертый anti-pattern: считать просмотры транзакционным SQL counter. Hot row и lock contention убьют базу. Нужны sharded counters, Redis, stream aggregation или approximate structures.
Пятый anti-pattern: не проектировать moderation и abuse. Video hosting без scanning, copyright, visibility, takedown и rate limits быстро становится operational risk.
Не стройте YouTube-like pipeline для продукта, которому нужно загрузить несколько обучающих роликов. Managed video платформы, Cloudflare Stream, Mux, Vimeo OTT или S3+CloudFront могут быть дешевле и надежнее.
Не используйте HLS/CDN для ultra-low-latency интерактива вроде видеозвонков, аукционов или игр. WebRTC подходит лучше, хотя масштабировать его сложнее.
Не делайте собственный transcoder fleet, если объем малый и latency обработки не критична. Managed transcoding снимет заботу о codec updates, GPU scheduling и corrupt media.
Не используйте public CDN для приватного видео без signed URLs, token auth и коротких TTL manifests. Иначе ссылки будут утекать и жить дольше политики доступа.
Разберите HLS master/variant playlists, DASH MPD, CMAF fragmented MP4, GOP/keyframes, bitrate ladder design, TUS resumable upload и multipart upload. Затем изучите CDN request collapsing, origin shield, signed URLs, cache invalidation и live LL-HLS. Для storage и async частей читать ::concept{slug="object-storage-s3"}, ::concept{slug="message-queues"}, ::concept{slug="cdn-design"}, ::concept{slug="search-engine"}. Для расчетов потренируйтесь оценивать upload PB/day, transcode GPU-hours/day, CDN egress Tbps и cache hit ratio.