Перейти к основному содержимому

Интервью по System Design. youtube

· 26 мин. чтения

Сегодня мы разберём собеседование по проектированию системы видеохостинга, в ходе которого кандидат под руководством интервьюера последовательно определил функциональные и нефункциональные требования, оценил нагрузку и объёмы данных, а затем предложил микросервисную архитектуру с компонентами для загрузки, транскодирования, хранения и отдачи видео через CDN. Интервьюер активно направлял диалог, проверяя глубину понимания кандидатом принципов масштабирования, выбора технологий и балансировки нагрузки в распределённой системе.

Вопрос 1. Какие функциональные и нефункциональные требования предъявляются к сервису загрузки и просмотра видео (аналог YouTube)?

Таймкод: 00:01:03

Ответ собеседника: Правильный. Основные функции — загрузка и просмотр видео. Дополнительно: лайки, дизлайки, комментарии, плейлисты, шаринг, приватные видео. Для MVP достаточно загрузки и просмотра, остальное — в последующих версиях. Нефункциональные требования: персистентность (гарантия хранения загруженных видео), быстрая загрузка и воспроизведение, высокая доступность сервиса несмотря на сбои.

Правильный ответ:

Ответ кандидата корректен и хорошо структурирован. Для полноты картины стоит расширить оба раздела.

Функциональные требования:

Ядро (MVP):

  • Загрузка видео с клиента (поддержка различных форматов: MP4, AVI, MOV, WebM и др.)
  • Воспроизведение видео в браузере (адаптивный стриминг)
  • Регистрация и аутентификация пользователей
  • Профиль канала с загруженными видео

Расширенный функционал:

  • Система реакций: лайки, дизлайки, избранное
  • Комментарии с поддержкой ветвления дискуссий
  • Плейлисты и очереди воспроизведения
  • Шаринг видео через ссылки и встраивание (embed)
  • Настройки приватности: публичные, по ссылке, приватные видео
  • Подписки на каналы с уведомлениями о новых видео
  • Поиск и рекомендации
  • Система монетизации (для платформ с рекламой)
  • Модерация контента и система жалоб
  • Субтры и автоматическая генерация субтитров
  • Аналитика для авторов (просмотры, аудитория, вовлечённость)
  • Трансляции в реальном времени (live streaming)
  • Shorts / короткие видео

Нефункциональные требования:

Масштабируемость:

  • Горизонтальное масштабирование для поддержки миллионов одновременных просмотров
  • Эффективная обработка пиковых нагрузок (вирусные видео, события)
  • Архитектура, позволяющая масштабировать компоненты независимо

Производительность:

  • Минимальное время начала воспроизведения (time-to-first-frame) — целевое значение менее 2 секунд
  • Адаптивный битрейт-стриминг (ABR) для автоматической подстройки качества под скорость соединения пользователя
  • Эффективная обработка видео (транскодирование в несколько разрешений и битрейтов)
  • Оптимизация загрузки: resumable upload, параллельная загрузка чанков

Доступность и отказоустойчивость:

  • Целевая доступность 99.99% (four nines) для критичных компонентов
  • Географическое распределение серверов (CDN) для снижения латентности
  • Репликация данных и автоматическое переключение при сбоях
  • Graceful degradation — при отказе некритичных сервисов ядро продолжает работать

Персистентность и надёжность:

  • Гарантия сохранности загруженного контента (репликация видеофайлов, erasure coding)
  • Целостность метаданных и пользовательских данных
  • Резервное копирование и возможность восстановления

Безопасность:

  • Защита от несанкционированного доступа к приватному контенту
  • DRM (Digital Rights Management) для защищённого контента
  • Защита от DDoS-атак
  • Валидация и санитизация загружаемых файлов (защита от вредоносного контента)

Наблюдаемость:

  • Метрики производительности на каждом этапе (загрузка, транскодирование, доставка)
  • Распределённая трассировка запросов
  • Централизованное логирование и алертинг

Стоимость:

  • Оптимизация затрат на хранение и трафик (иерархическое хранение, горячее/холодное)
  • Эффективное использование ресурсов транскодирования

Вопрос 2. Нужно ли хранить видео в различных форматах/разрешениях и какие плюсы и минусы у транскодирования?

Таймкод: 00:04:00

Ответ собеседника: Правильный. Рекомендуется раскодировать исходное видео в несколько форматов (360p, 720p, 1080p и т.д.). Плюсы: гибкость в обеспечении QoS при плохом канале — можно уменьшать качество на лету; при хорошем канале пользователь получает видео в высоком качестве. Минусы: увеличивается объём занимаемого места на хранилище.

Правильный ответ:

Ответ кандидата в целом верный. Дополним его деталями для полноты.

Необходимость хранения нескольких форматов/разрешений:

Да, это стандартная практика для видеоплатформ. Технология называется Adaptive Bitrate Streaming (ABR). Видео транскодируется в набор разрешений и битрейтов (ladder):

  • 2160p (4K) — ~15-25 Mbps
  • 1080p — ~5-8 Mbps
  • 720p — ~2.5-5 Mbps
  • 480p — ~1-2.5 Mbps
  • 360p — ~0.5-1 Mbps
  • 240p — ~0.3-0.5 Mbps

Каждое разрешение нарезается на сегменты (чанки) длительностью 2-10 секунд, и клиент динамически переключается между ними в зависимости от текущей скорости соединения.

Форматы контейнеров и кодеки:

Помимо разрешений, важно хранить видео в нескольких форматах:

  • HLS (HTTP Live Streaming) — сегменты в формате .ts или .mp4, манифест .m3u8 (Apple-экосистема, широкая поддержка)
  • DASH (Dynamic Adaptive Streaming over HTTP) — сегменты .m4s, манифест .mpd (открытый стандарт)
  • Кодеки: H.264 (совместимость), H.265/HEVC (эффективность), VP9 и AV1 (открытые, экономия трафика)

Плюсы транскодирования:

  • Адаптивность к каналу — плавное переключение качества без буферизации, пользователь всегда получает оптимальное качество для своего соединения
  • Совместимость устройств — разные устройства поддерживают разные кодеки и разрешения; набор вариантов покрывает весь спектр
  • Экономия трафика — мобильные пользователи с лимитным интернетом получают меньший битрейт, что снижает их расходы и повышает удержание
  • CDN-эффективность — популярные разрешения кэшируются на edge-серверах, снижая нагрузку на origin
  • Снижение нагрузки на клиент — мобильные устройства не тратят ресурсы на декодирование 4K, если экран не поддерживает такое разрешение

Минусы транскодирования:

  • Увеличение объёма хранилища — каждый вариант занимает место; при наличии 5-6 разрешений общий объём может быть в 3-5 раз больше исходного файла
  • Вычислительные затраты — транскодирование ресурсоёмко, особенно для 4K и длительных видео; требуются GPU-ускорители или выделенные фермы
  • Задержка публикации — после загрузки видео недоступно до завершения транскодирования; для длинных видео это может занимать минуты или часы
  • Сложность инфраструктуры — необходим оркестратор задач транскодирования, очереди, мониторинг, повторные попытки при сбоях
  • Финансовые затраты — стоимость хранения, вычислений и CDN-трафика растёт кратно

Оптимизации:

  • Just-in-time транскодирование — генерировать разрешения по запросу, а не для каждого видео; экономия ресурсов для непопулярного контента
  • Перцептивное кодирование — использовать per-title encoding, при котором битрейт подбирается индивидуально под сложность контента (анимация требует меньше битрейта, чем динамичный экшен)
  • Холодное хранилище — редко запрашиваемые разрешения перемещать в дешёвое хранилище (S3 Glacier и аналоги)
  • Прогрессивная обработка — сначала публиковать видео в низком разрешении (для быстрого доступа), затем фоново генерировать высокие

Вопрос 3. Какова географическая аудитория сервиса и с каких устройств пользователи будут получать доступ?

Таймкод: 00:05:50

Ответ собеседника: Правильный. Сервис рассчитан на весь мир. Пользователи будут получать доступ с различных устройств: смартфоны, планшеты, ноутбуки, компьютеры, Smart TV.

Правильный ответ:

Ответ кандидата корректен, но для полноценного проектирования системы необходимо детализировать оба аспекта.

Географическая аудитория:

При проектировании глобального сервиса важно учитывать региональные особенности:

  • Северная Америка и Европа — высокая скорость интернета, доминирование десктопа и Smart TV, высокие требования к качеству (4K), строгие требования к персональным данным (GDPR, CCPA)
  • Азиатско-Тихоокеанский регион — крупнейшая аудитория, мобильный трафик доминирует (70-80%), разнообразие скоростей соединения, необходимость поддержки локальных языков и кодировок
  • Латинская Америка, Африка, Ближний Восток — преимущественно мобильный доступ, низкая средняя скорость интернета, критична поддержка низких разрешений (240p-360p), экономия трафика — ключевой фактор удержания

Региональные особенности влияют на архитектуру: размещение дата-центров, CDN-провайдеров, соблюдение локального законодательства (хранение данных в пределах юрисдикции), поддержка локальных способов оплаты и языков.

Устройства доступа:

Мобильные устройства (iOS, Android):

  • Доминирующий канал в большинстве регионов (60-80% трафика)
  • Ограничения по трафу, батарее, размеру экрана
  • Необходимость нативных приложений с поддержкой фонового воспроизведения, Picture-in-Picture, загрузки офлайн
  • Разнообразие экранов и аппаратных декодеров

Десктоп (браузеры):

  • Широкий спектр браузеров и версий
  • Поддержка HTML5 Video, Media Source Extensions (MSE) для ABR
  • Высокие ожидания по качеству (1080p-4K)
  • Поддержка горячих клавиш, полноэкранного режима

Smart TV и стриминговые устройства (Roku, Apple TV, Chromecast, Fire TV, игровые консоли):

  • Растущий сегмент с высоким средним временем просмотра
  • Ограниченные вычислительные ресурсы, специфические SDK
  • Управление через пульт (навигация без мыши)
  • Поддержка 4K, HDR, Dolby Vision, Dolby Atmos

Планшеты:

  • Промежуточный сегмент между мобильными и десктопом
  • Часто используются для потребления контента дома по Wi-Fi

Влияние на архитектуру:

  • Необходимость поддержки нескольких протоколов стриминга (HLS, DASH) для совместимости со всеми устройствами
  • Разные форматы рекламы (pre-roll, mid-roll, overlay) для разных платформ
  • Адаптивный UI/UX под каждый форм-фактор
  • Тестирование на реальных устройствах и эмуляторах
  • Разные стратегии кэширования и предзагрузки для мобильных и десктопных клиентов

Вопрос 4. Каковы ключевые числовые характеристики сервиса: количество ежедневных активных пользователей, среднее время просмотра, процент загружающих видео, средний объём загрузки? Какой объём хранилища потребуется в день?

Таймкод: 00:06:55

Ответ собеседника: Правильный. Приняты следующие допущения: 20 млн ежедневных активных пользователей, в среднем 50 минут просмотра в день. 0,1% пользователей (20 000) загружают видео, каждый загружает в среднем одно часовое видео в 4К — примерно 100 ГБ. Итого: 20 000 × 100 ГБ = 2 000 000 ГБ = 2000 ТБ ≈ 2 петабайта в день.

Правильный ответ:

Ответ кандидата в целом верен по подходу и допущениям. Расчёт корректен: 20 000 × 100 ГБ = 2 000 000 ГБ = 2 ПБ/день. Допущения реалистичны и хорошо обоснованы. Дополним анализ для полноты.

Допущения и их обоснование:

Ежедневные активные пользователи (DAU): 20 млн

  • Реалистичная цифра для крупного, но не доминирующего сервиса (YouTube ~2 млрд DAU, региональные платформы — 10-50 млн)

Среднее время просмотра: 50 минут/день

  • Соответствует индустриальным метрикам (YouTube ~40-60 мин, TikTok ~50-60 мин)
  • Влияет на расчёт исходящего трафика и нагрузку на CDN

Процент загружающих: 0,1%

  • Типичное соотношение creator/viewer для платформ с пользовательским контентом
  • Из 20 млн DAU = 20 000 загрузок в день

Средний размер загрузки: 100 ГБ (1 час 4K)

  • 4K видео с битрейтом ~20-25 Mbps даёт примерно 9-11 ГБ в час; при более высоком битрейте или исходнике без сжатия — до 100 ГБ вполне реалистично
  • На практике исходники варьируются от 1 ГБ (сжатое 1080p) до сотен ГБ (профессиональное 4K/8K raw)

Расчём хранилища:

  • 20 000 загрузок × 100 ГБ = 2 000 000 ГБ = 2 ПБ/день
  • С учётом транскодирования в 5 разрешений (множитель ×3-5): 6-10 ПБ/день суммарного хранилища
  • За год: ~2-4 ЭБ (экзабайт) нового контента

Дополнительные метрики для проектирования:

  • Пиковый RPS на загрузку: 20 000 загрузок за ~8 часов пиковой активности ≈ ~0,7 RPS в среднем, с пиками до 5-10 RPS
  • Пиковый RPS на просмотр: 20 млн × 50 мин / 86400 сек ≈ ~11 500 одновременных стримов в среднем; с учётом пикового коэффициента ×3 = ~35 000 одновременных стримов
  • Исходящий трафик CDN: 11 500 × 5 Mbps (средний битрейт) ≈ 57,5 Gbps в среднем; пиковый ~170 Gbps
  • Количество запросов метаданных: порядок сотен тысяч RPS (поиск, рекомендации, лента)

Оптимизации хранилища:

  • Per-title encoding для снижения битрейта без потери качества
  • Хранение исходника + производных разрешений; при необходимости — только исходник с JIT-транскодированием
  • Иерархическое хранение: горячее (SSD) для популярного контента, холодное (HDD/S3) для редко запрашиваемого
  • Дедупликация контента (для борьбы с повторными загрузками)

Вопрос 5. Как долго будет храниться загруженный контент и как планировать масштабирование хранилища?

Таймкод: 00:12:33

Ответ собеседника: Правильный. Видео будет храниться бессрочно. Можно заложить хранилище на определённый горизонт (например, 10 лет) и по мере заполнения горизонтально масштабироваться — заранее выкупать дополнительные мощности. Резервировать место рациональнее часто, например раз в год, чтобы не платить за неиспользуемое хранилище на 9 лет вперёд.

Правильный ответ:

Ответ кандидата содержит правильные идеи. Дополним его системным подходом к планированию хранения.

Политика хранения контента:

Бессрочное хранение по умолчанию — стандартный подход для крупных платформ. Однако на практике существуют нюансы:

  • Контент удаляется по запросу автора, по жалобам (DMCA, нарушение правил), при блокировке аккаунта
  • Для неактивных аккаунтов может применяться политика архивации (перемещение в холодное хранилище)
  • Некоторые платформы вводят лимиты хранения для бесплатных аккаунтов

Стратегия масштабирования хранилища:

Горизонтальное масштабование:

  • Использование распределённых объектных хранилищ (S3-совместимые, HDFS, Ceph)
  • Шардирование по идентификатору видео или по времени загрузки
  • Линейное наращивание ёмкости без downtime

Планирование ёмкости:

  • Прогнозирование роста на основе метрик: количество загрузок/день, средний размер, коэффициент транскодирования
  • Закупка ёмкости квартально или ежемесячно на основе тренда, а не на годы вперёд
  • Использование гибридной модели: собственное хранилище для горячего контента + облако для эластичного масштабирования и холодного хранения

Иерархическое хранение (Storage Tiering):

  • Hot tier (SSD/NVMe): последние загрузки и популярный контент, высокий IOPS, минимальная латентность
  • Warm tier (HDD): контент средней популярности, сбалансированная стоимость и производительность
  • Cold tier (S3 Glacier, tape): редко запрашиваемый контент, минимальная стоимость хранения, высокая латентность доступа
  • Автоматическое перемещение между тирами на основе паттернов доступа (lifecycle policies)

Оптимизация затрат:

  • Дедупликация: обнаружение идентичных или похожих видео для исключения дубликатов
  • Erasure coding вместо полной репликации: снижение накладных расходов с 3× до 1.5×
  • Per-title encoding: оптимизация битрейта под конкретный контент, экономия 20-40% объёма
  • JIT-транскодирование: генерация разрешений по запросу для непопулярного контента

Мониторинг и прогнозирование:

  • Дашборды с текущим заполнением, трендом роста, прогнозом исчерпания
  • Автоматические алерты при достижении порогов (70%, 85%, 95%)
  • Ежемесячный пересчёт прогноза на основе фактических метрик

Вопрос 6. Как спроектировать верхнеуровневую архитектуру процесса загрузки видео, включая метаданные, транскодирование и взаимодействие компонентов?

Таймкод: 00:22:50

Ответ собеседника: Правильный. Пользователь авторизован и приходит с токеном в API Gateway. API Gateway проверяет доступ, обращается к базе метаданных и создаёт запись, после чего отвечает пользователю, что он может загружать видео в отдельное blob-хранилище. После завершения загрузки upload-сервис через брокер сообщений формирует задачи для воркеров-транскодеров, каждый отвечает за свой формат. Воркеры забирают видео, транскодируют и обновляют запись в базе метаданных ссылками на результаты.

Правильный ответ:

Ответ кандидата демонстрирует хорошее понимание архитектуры. Дополним деталями и расширим схему.

Верхнеуровневая архитектура загрузки видео:

1. Инициализация загрузки:

Клиент → API GatewayUpload Service

POST /api/v1/videos/upload/init
Authorization: Bearer <token>
Body: {title, description, tags, visibility, content_type, file_size}

Upload Service:

  • Валидирует запрос (размер файла, формат, квоты пользователя)
  • Создаёт запись в Metadata DB со статусом UPLOADING
  • Генерирует уникальный video_id
  • Запрашивает у Storage Service presigned URL для прямой загрузки в объектное хранилище
  • Возвращает клиенту: video_id, upload_url, chunk_size, max_chunks

2. Загрузка файла:

Клиент → Object Storage (S3-совместимое) — напрямую, минуя серверную часть

Поддержка resumable upload:

  • Файл разбивается на чанки (например, по 5-10 МБ)
  • Каждый чанк загружается отдельным запросом
  • При сбое — повторная загрузка только неудачных чанков
  • После загрузки всех чанков — отправляется запрос на завершение

3. Уведомление о завершении загрузки:

Клиент → Upload Service: POST /api/v1/videos/{video_id}/upload/complete

Или Object Storage → Upload Service через event notification (S3 Event → SQS/SNS)

Upload Service:

  • Верифицирует целостность файла (checksum, размер)
  • Обновляет статус в Metadata DB на PROCESSING
  • Публикует событие в Message Broker (Kafka/RabbitMQ/SQS)

4. Оркестрация транскодирования:

Transcoding Service (оркестратор):

  • Подписан на очередь задач транскодирования
  • Получает video_id и ссылку на исходный файл
  • Определяет набор целевых форматов (ladder) на основе исходного разрешения и контента
  • Создаёт N задач для Transcoding Workers (по одной на каждое разрешение)
  • Отправляет задачи в отдельные очереди или с приоритетами

5. Транскодирование:

Transcoding Workers (горизонтально масштабируемые):

  • Забирают задачу из очереди
  • Скачивают исходный файл из Object Storage
  • Транскодируют в целевое разрешение (FFmpeg, GPU-ускорение)
  • Загружают результат в Object Storage
  • Публикуют событие о завершении

6. Агрегация результатов:

Transcoding Service или отдельный Aggregation Service:

  • Собирает события от всех воркеров
  • По завершении всех форматов — обновляет Metadata DB: статус READY, записывает ссылки на все варианты
  • Генерирует HLS/DASH манифесты
  • Публикует событие VideoReady для других сервисов (поиск, рекомендации, уведомления)

Схема метаданных:

videos:
- video_id (UUID)
- user_id
- title, description, tags[]
- visibility (public/unlisted/private)
- status (uploading/processing/ready/failed)
- original_url (ссылка на исходник в Object Storage)
- variants[]:
- resolution (360p, 720p, 1080p)
- codec (h264, h265, av1)
- bitrate
- url
- manifest_url (HLS/DASH)
- duration, file_size, created_at, updated_at

Паттерны и принципы:

  • Асинхронность: транскодирование длительное — не блокируем клиента
  • Event-driven: компоненты взаимодействуют через события, слабая связанность
  • Горизонтальное масштабирование: воркеры транскодирования масштабируются независимо от остальной системы
  • Idempotency: повторная обработка одного события не приводит к дублированию
  • Dead letter queue: задачи, завершившиеся ошибкой, попадают в DLQ для повторной обработки или ручной модерации
  • Circuit breaker: при сбое Object Storage или воркеров — остановка каскадных отказов

Вопрос 7. Как спроектировать архитектуру поиска и отдачи видео пользователю, включая роль CDN и кэширование популярного контента?

Таймкод: 00:30:59

Ответ собеседния: Правильный. Пользователь приходит в API Gateway с поисковым запросом или запросом списка видео. Запрос обрабатывается сервисом поиска, который ищет по метаданным. Из метаданных берутся ссылки на видео в blob-хранилище. Перед хранилищем ставится CDN для отдачи популярного контента, размещаясь ближе к геолокации пользователей.

Правильный ответ:

Ответ кандидата корректен. Дополним архитектуру деталями.

Архитектура поиска:

Поисковый запрос: Клиент → API GatewaySearch Service

Search Service:

  • Принимает поисковый запрос, фильтры (дата, длительность, категория), параметры пагинации и сортировки
  • Обращается к поисковому индексу (Elasticsearch/OpenSearch) для полнотекстового поиска по заголовкам, описаниям, тегам, имени автора
  • Применяет ранжирование: релевантность, популярность, свежесть, персонализация
  • Возвращает список video_id с метаданными (без ссылок на видеофайлы)

Поисковый индекс:

  • Elasticsearch/OpenSearch для полнотекстового поиска с поддержкой морфологии, автодополнения, исправления опечаток
  • Данные индексируются через событие VideoReady после завершения транскодирования
  • Возможна отдельная индексация субтитров для поиска внутри видео

Персонализация и рекомендации:

  • Отдельный Recommendation Service формирует персонализированные ленты
  • Использует коллаборативную фильтрацию, контентные фичи, историю просмотров
  • Кэширует результаты для каждого пользователя с TTL

Архитектура отдачи видео:

Просмотр видео: Клиент → API GatewayVideo Service

Video Service:

  • Проверяет права доступа (приватность, возрастные ограничения, геоблокировка)
  • Обращается к Metadata DB за информацией о видео
  • Генерирует signed URL с ограниченным временем жизни для доступа к манифесту (HLS/DASH)
  • Возвращает клиенту: метаданные видео, URL манифеста, информацию о доступных субтитрах

Воспроизведение: Клиент (видеоплеер) → CDN EdgeCDN OriginObject Storage

  • Клиент загружает манифест (.m3u8 / .mpd), содержащий ссылки на сегменты
  • Видеоплеер запрашивает сегменты через CDN
  • CDN Edge кэширует сегменты; при попадании в кэш (cache hit) — отдаёт напрямую
  • При промахе (cache miss) — CDN запрашивает сегмент у CDN Origin / Object Storage, кэширует и отдаёт клиенту

Роль CDN:

  • Географическое распределение: edge-серверы в сотнях точек присутствия по всему миру, контент доставляется с ближайшего узла
  • Снижение латентности: время до первого сегмента сокращается с сотен миллисекунд до единиц
  • Снижение нагрузки на origin: 90-99% запросов контента обслуживается CDN, Object Storage получает минимальный трафик
  • Абсорбция пиковых нагрузок: вирусные видео и события не влияют на origin-инфраструктуру
  • Экономия стоимости: исходящий трафик из Object Storage значительно дороже, чем из CDN

Стратегия кэширования:

  • Популярный контент: автоматически кэшируется на edge-серверах благодаря частым запросам
  • Предзагрузка (prefetching): новые эпизоды популярных шоу, ожидаемые релизы загружаются на edge до публикации
  • Cache TTL: для видеосегментов — длительный (дни/недели), для манифестов — короткий (минуты) для актуальности списка сегментов
  • Cache invalidation: при удалении или замене видео — инвалидация кэша через API CDN

Адаптивный стриминг:

  • Клиентский плеер мониторит скорость загрузки сегментов
  • Автоматически переключается между разрешениями (ladder) в манифесте
  • При ухудшении соединения — снижает битрейт; при улучшении — повышает
  • Переключение происходит на границах сегментов, без прерывания воспроизведения

Signed URLs для безопасности:

  • URL манифеста и сегментов содержат подпись и срок действия
  • Предотвращает hotlinking и несанкционированный доступ
  • Позволяет реализовать геоблокировку и проверку прав на уровне CDN

Вопрос 8. Почему выбрана микросервисная архитектура, а не монолит, и какие есть альтернативы?

Таймкод: 00:34:23

Ответ собеседника: Правильный. Сервисы stateless, данные хранятся в БД, поэтому легко балансировать нагрузку. В монолите функциональности пересекаются, сложнее поддерживать и деплоить. Микросервисы позволяют независимо масштабировать компоненты, упрощают мониторинг, и падение одного сервиса не тянет за собой другие.

Правильный ответ:

Ответ кандидата корректен. Дополним анализ более детальным сравнением.

Преимущества микросервисной архитектуры для видеоплатформы:

Независимое масштабирование:

  • Компоненты системы имеют разные профили нагрузки: загрузка (write-heavy, пиковая), просмотр (read-heavy, постоянная), транскодирование (CPU/GPU-intensive, фоновая), поиск (latency-sensitive)
  • Каждый сервис масштабируется независимо: воркеры транскодирования — по длине очереди, API-сервисы — по RPS, поиск — по объёму индекса
  • Экономия ресурсов: не нужно масштабировать весь монолит из-за одного узкого места

Отказоустойчивость:

  • Падение сервиса транскодирования не влияет на просмотр уже обработанных видео
  • Падение сервиса рекомендаций — fallback на популярный контент
  • Изоляция сбоев через circuit breaker, bulkhead pattern

Независимый деплой:

  • Команды могут выпускать релизы своих сервисов без координации с другими
  • Разные циклы разработки: критичные исправления — горячий деплой, новые фичи — по расписанию
  • Снижение риска: баг в одном сервисе не затрагивает остальные

Технологическая гибкость:

  • Сервис транскодирования — Go/C++ с GPU-ускорением
  • Поиск — Java/Kotlin с Elasticsearch клиентом
  • API Gateway — Go/Node.js
  • Каждая команда выбирает оптимальный стек под свою задачу

Организационная масштабируемость:

  • Отдельные команды владеют отдельными сервисами
  • Чёткие границы ответственности через API-контракты
  • Упрощение onboarding новых разработчиков

Альтернативы и сравнение:

Монолит:

  • Проще на старте: один репозиторий, один деплой, отсутствие сетевых вызовов между компонентами
  • Подходит для MVP и небольших команд (до 10-15 разработчиков)
  • Проблемы при росте: время сборки, конфликты при мерже, невозможность изолировать сбои
  • Переход от монолита к микросервисам возможен через паттерн Strangler Fig

Модульный монолит:

  • Компромиссный вариант: один деплойный артефакт, но с чёткими модульными границами
  • Модули взаимодействуют через внутренние интерфейсы, а не через сеть
  • Сохраняет простость деплоя, но позволяет выделить сервисы при необходимости
  • Хороший выбор для средних проектов

Серверless (FaaS):

  • Отдельные функции для обработки событий (загрузка завершена → запустить транскодирование)
  • Автоматическое масштабирование, оплата за фактическое использование
  • Ограничения: cold start, ограничение времени выполнения, vendor lock-in
  • Подходит для вспомогательных задач, не для высоконагруженных сервисов

Практическая рекомендация:

Для видеоплатформы с нагрузкой уровня 20 млн DAU микросервисная архитектура — обоснованный выбор. Начинать можно с модульного монолита и постепенно выделять сервисы по мере роста нагрузки и команды. Критичные для производительности компоненты (транскодирование, отдача контента) выделяются первыми.

Вопрос 9. Что представляет собой blob-хранилище, какие примеры существуют и как организовать попадание в популярного контента через CDN?

Таймкод: 00:37:09

Ответ собеседника: Правильный. Blob-хранилище — минималистичное хранилище в форме «загрузить/прочитать», хорошо работает с большими объёмами данных. Пример — S3. Для попадания популярного контента в CDN предлагается сервис аналитики, который собирает счётчики использования и даёт задачу на загрузку в CDN.

Правильный ответ:

Ответ кандидата корректен. Дополним техническими деталями.

Blob-хранилище (Object Storage):

Blob-хранилище — тип хранилища, оптимизированный для хранения неструктурированных данных (binary large objects): видео, изображения, бэкапы, логи. Ключевые характеристики:

  • Модель данных: плоское пространство «ключ → объект» (bucket + key), без иерарпии папок (хотя синтаксически ключи могут имитировать путь)
  • Операции: PUT (загрузка), GET (чтение), DELETE (удаление), HEAD (метаданные объекта)
  • Метаданные: каждый объект сопровождается системными (Content-Type, Content-Length, Last-Modified) и пользовательскими метаданными
  • Согласованность: strong read-after-write consistency (для новых объектов) в современных реализациях
  • Долговечность: 99.999999999% (11 девяток) за счёт erasure coding и географической репликации

Примеры blob-хранилищ:

  • Amazon S3 — стандарт индустрии, S3-совместимый API поддерживается большинством облачных и on-premise решений
  • Google Cloud Storage — интеграция с GCP-экосистемой
  • Azure Blob Storage — часть Microsoft Azure
  • MinIO — open-source S3-совместимое хранилище, развёртывается on-premise
  • Ceph RGW — объектный интерфейс распределённого хранилища Ceph
  • Backblaze B2 — бюджетная альтернатива S3

Почему не SQL для видеофайлов:

  • SQL-базы оптимизированы для структурированных данных и транзакций, а не для хранения файлов размером в гигабайты
  • Запись больших blob в БД приводит к фрагментации, росту времени бэкапа, увеличению размера WAL
  • Метаданные видео (заголовок, описание, статус) хранятся в SQL/NoSQL, а сам файл — в blob-хранилище; в метаданных сохраняется только ссылка (URL/key)

Организация попадания контента в CDN:

На практике контент попадает в CDN двумя способами:

1. Pull-based (автоматический, наиболее распространённый):

  • CDN настроен с Object Storage как origin-сервер
  • Когда клиент запрашивает сегмент видео, CDN Edge при промахе кэша автоматически запрашивает его у origin (Object Storage)
  • Сегмент кэшируется на edge-сервере с указанным TTL
  • Популярный контент естественным образом оказывается в кэше благодаря частым запросам
  • Не требует дополнительной инфраструктуры

2. Push-based (предзагрузка)::

  • Для ожидаемых событий (премьера сериала, вирусное видео) контент загружается на CDN заранее
  • Analytics Service отслеживает метрики: количество просмотров, скорость роста просмотров, география
  • При превышении порога — публикует событие в очередь
  • CDN Prefetch Worker получает событие и инициирует загрузку сегментов на CDN edge-серверы через API CDN (например, Cache Prefetch API в CloudFront или CDN Purge/Prefetch в Akamai)
  • Также можно использовать Origin Shield — промежуточный кэш между edge и origin для снижения нагрузки на Object Storage

Гибридный подход:

  • Основной трафик обслуживается pull-based CDN
  • Push-based используется для прогнозируемых событий и контента с известным паттерном популярности
  • Холодный контент (старые видео с редкими просмотрами) не вытесняет горячий из кэша благодаря LRU/LFU eviction policies CDN

Вопрос 10. Какие проблемы могут возникнуть с метаданными, как спроектировать схему хранения и обеспечить масштабируемость при росте числа записей?

Таймкод: 00:40:23

Ответ собеседника: Правильный. Запись метаданных создаётся единожды и обновляется ограниченное число раз. Счётчики просмотров лучше вынести в отдельную таблицу. Для масштабируемости — master-slave репликация. Объём метаданных ~5 КБ на запись, ~10 МБ в день — SQL-база справится.

Правильный ответ:

Ответ кандидата содержит правильные идеи. Дополним техническими деталями и исправим неточности.

Проблемы с метаданными:

Высокая частота обновлений счётчиков:

  • Счётчик просмотров обновляется при каждом просмотре — для популярного видео это тысячи обновлений в секунду
  • Прямое обновление строки в основной таблице приводит к contention (блокировкам) и деградации чтения
  • Решение: выносить счётчики в отдельную таблицу или использовать счётчики в Redis с периодической фиксацией в БД

Рост объёма данных:

  • При 20 000 загрузок/день за год накопится ~7,3 млн записей
  • При 5 КБ на запись — ~35 ГБ в год только основные метаданные
  • С учётом индексов, счётчиков, истории изменений — объём кратно больше

Сложные запросы:

  • Поиск по множеству полей: заголовок, теги, категория, дата, длительность, рейтинг
  • Пагинация и сортировка по различным полям
  • Персонализированные запросы (подписки, история, рекомендации)

Схема хранения:

Основная таблица метаданных (PostgreSQL/MySQL):

CREATE TABLE videos (
video_id UUID PRIMARY KEY,
user_id BIGINT NOT NULL,
title VARCHAR(500) NOT NULL,
description TEXT,
visibility SMALLINT NOT NULL DEFAULT 0, -- 0=public, 1=unlisted, 2=private
status SMALLINT NOT NULL DEFAULT 0, -- 0=uploading, 1=processing, 2=ready, 3=failed
duration INT, -- секунды
file_size BIGINT,
original_key VARCHAR(500), -- ключ в Object Storage
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
published_at TIMESTAMPTZ
);

CREATE INDEX idx_videos_user_id ON videos(user_id, created_at DESC);
CREATE INDEX idx_videos_status_published ON videos(status, published_at DESC) WHERE status = 2;

Таблица вариантов транскодирования:

CREATE TABLE video_variants (
video_id UUID NOT NULL REFERENCES videos(video_id),
resolution VARCHAR(10) NOT NULL, -- '360p', '720p', '1080p'
codec VARCHAR(10) NOT NULL, -- 'h264', 'av1'
bitrate INT,
file_size BIGINT,
storage_key VARCHAR(500) NOT NULL,
manifest_url VARCHAR(1000),
PRIMARY KEY (video_id, resolution, codec)
);

Таблица счётчиков (отдельно от основной):

CREATE TABLE video_counters (
video_id UUID PRIMARY KEY REFERENCES videos(video_id),
views BIGINT NOT NULL DEFAULT 0,
likes INT NOT NULL DEFAULT 0,
dislikes INT NOT NULL DEFAULT 0,
comments INT NOT NULL DEFAULT 0,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Теги (многие-ко-многим):

CREATE TABLE tags (
tag_id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL
);

CREATE TABLE video_tags (
video_id UUID NOT NULL REFERENCES videos(video_id),
tag_id INT NOT NULL REFERENCES tags(tag_id),
PRIMARY KEY (video_id, tag_id)
);

Масштабируемость:

Read Replicas:

  • Запись идёт в master, чтение распределяется по read replicas
  • Для поиска и ленты — чтение с реплик, возможно с eventual consistency
  • Для критичных операций (проверка прав доступа) — чтение с master

Шардирование:

  • При росте объёма — шардирование по video_id (hash-based) или по user_id (для запросов по каналу)
  • Шардирование по video_id обеспечивает равномерное распределение
  • Шардирование по user_id группирует все видео автора на одном шарде, упрощая запросы «все видео канала»

Кэширование:

  • Метаданные популярных видео кэшируются в Redis/Memcached
  • Cache-aside pattern: при запросе сначала проверяется кэш, при промахе — запрос к БД с последующим заполнением кэша
  • TTL зависит от типа данных: статичные метаданные — часы, счётчики — минуты

Вынос поиска в отдельный индекс:

  • Полнотекстовый поиск — Elasticsearch/OpenSearch, синхронизация через CDC (Change Data Capture) или event-driven
  • Это снимает нагрузку с основной БД и обеспечивает возможности поиска, недоступные в SQL (морфология, релевантность, автодополнение)

Примечание по LSM-деревьям: Кандидат упомянул SQL-базу на LSM-деревьях. Это неточность: LSM (Log-Structured Merge Tree) — это внутренняя структура хранения, используемая в NoSQL-базах (Cassandra, RocksDB, LevelDB). Классические SQL-базы (PostgreSQL, MySQL/InnoDB) используют B+-деревья для индексов. Для метаданных видеоплатформы реляционная БД с B+-деревьями — стандартный и оправданный выбор.

Вопрос 11. Нужен ли балансировщик для сервиса ответов (response service) и как распределить нагрузку между его инстансами, учитывая геораспределённость?

Таймкод: 00:45:36

Ответ собеседника: Правильный. Запросы идут на API Gateway, затем на балансировщик, распределяющий между инстансами. В геораспределённой системе — маршрутизация к ближайшему региону. Пример — Nginx.

Правильный ответ:

Ответ кандидата корректен. Дополним многоуровневой архитектурой балансировки.

Необходимость балансировщика:

Да, балансировщик необходим по нескольким причинам:

  • Горизонтальное масштабирование: один инстанс не справится с нагрузкой 20 млн DAU
  • Отказоустойчивость: при падении инстанса трафик перенаправляется на здоровые
  • Rolling deployments: обновление сервисов без downtime
  • Health checking: автоматическое исключение неработающих инстансов из пула

Многоуровневая балансировка:

1. DNS-балансировка (Global Server Load Balancing — GSLB):

  • Первый уровень: DNS-резолвер определяет геолокацию пользователя и возвращает IP ближайшего дата-центра
  • Пример: Route 53 (AWS) с latency-based или geolocation-based routing
  • Пользователь из Европы получает IP европейского кластера, из Азии — азиатского
  • TTL DNS-записей — низкий (30-60 секунд) для быстрого failover

2. L4-балансировка (Transport Layer):

  • Распределение TCP/UDP-соединений между инстансами или между L7-балансировщиками
  • Примеры: AWS NLB, Google Cloud TCP/UDP Load Balancer, HAProxy в TCP-режиме
  • Высокая производительность, минимальные накладные расходы
  • Алгоритмы: round-robin, least connections, source IP hash

3. L7-балансировка (Application Layer):

  • Инспектирует HTTP-запросы: пулы, заголовки, cookies
  • Примеры: AWS ALB, Nginx, Envoy, HAProxy в HTTP-режиме
  • Возможности: path-based routing (/api/v1/* → API service, /static/* → CDN), sticky sessions, rate limiting, SSL termination

Алгоритмы балансировки:

  • Round Robin — равномерное распределение по кругу; подходит при одинаковой мощности инстансов
  • Least Connections — запрос направляется на инстанс с наименьшим числом активных соединений; оптимально при разном времени обработки
  • Weighted — инстансам назначаются веса пропорционально мощности
  • Consistent Hashing — один и тот же ключ (например, video_id) всегда направляется на один инстанс; полезно для кэширования

Геораспределённая маршрутизация:

  • Anycast: один IP-анонсируется из нескольких дата-центров; маршрутизация BGP направляет пользователя к ближайшему
  • Geo-based routing: DNS или L7-балансировщик определяет регион пользователя и направляет в соответствующий кластер
  • Cross-region failover: при недоступности региона — трафик перенаправляется в ближайший доступный

Пример стека:

Пользователь


DNS (Route 53 / Cloudflare) ─── Geo-based resolution


CDN (CloudFront / Cloudflare) ─── Кэширование статики и видео


API Gateway (Kong / AWS API Gateway) ─── Rate limiting, Auth, Routing


L7 Load Balancer (Nginx / Envoy / ALB) ─── Path-based routing


Service Mesh (Istio / Linkerd) ─── Межсервисная коммуникация, mTLS, Circuit Breaker


Response Service Instances (Kubernetes Pods)

Kubernetes Ingress:

При развёртывании в Kubernetes балансировка инстансов сервиса выполняется на нескольких уровнях:

  • Service (ClusterIP): внутренний L4-балансировщик, распределяет Pod'ы сервиса
  • Ingress Controller (Nginx/Envoy): L7-балансировка с маршрутизацией по путям и хостам
  • Horizontal Pod Autoscaler (HPA): автоматическое масштабирование количества Pod'ов на основе CPU, пользовательских метрик (RPS, длина очереди)

Вопрос 12. Какие языки программирования и технологии выбрать для различных компонентов системы: upload-сервис, брокер сообщений, хранилище метаданных?

Таймкод: 00:50:50

Ответ собеседника: Правильный. Для upload-сервиса — Python с Flask. Для брокера сообщений — Kafka. Для метаданных — PostgreSQL.

Правильный ответ:

Ответ кандидата содержит рабочие варианты, но для системы с нагрузкой 20 млн DAU выбор технологий требует более строгого обоснования.

Upload Service:

Кандидат предложил Python с Flask. Это допустимо для прототипа, но для production с высокой нагрузкой есть более эффективные варианты.

  • Go — оптимальный выбор: высокая производительность при обработке сетевых запросов, нативная поддержка concurrency (goroutines), быстрая компиляция, низкое потребление памяти, отличная экосистема для микросервисов (gRPC, Prometheus metrics)
  • Java/Kotlin + Spring Boot — зрелая экосистема, отличные библиотеки для работы с БД и брокерами, но более высокое потребление памяти
  • Python + FastAPI — быстрая разработка, хорошая производительность для I/O-bound задач (async/await), но GIL ограничивает CPU-bound операции; подходит для сервисов с умеренной нагрузкой

Для upload-сервиса основная нагрузка — I/O-bound (обращения к БД, Object Storage, брокеру), поэтому Python с асинхронным фреймворком приемлем, но Go даст лучшую производительность при меньших ресурсах.

Брокер сообщений:

  • Apache Kafka — правильный выбор для основного брокера: высокая пропускная способность, персистентность сообщений, возможность повторного чтения, партиционирование для параллельной обработки, exactly-once semantics
  • RabbitMQ — для сценариев с более сложной маршрутизацией сообщений, приоритетными очередями, RPC-паттернами
  • Amazon SQS/SNS — managed-решение, проще в эксплуатации, но менее гибкое

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

Хранилище метаданных:

  • PostgreSQL — правильный выбор: ACID-транзакции, богатые типы данных (JSONB, массивы), полнотекстовый поиск, зрелая экосистема репликации, расширения (PostGIS для геоданных, pg_trgm для fuzzy search)
  • MySQL/MariaDB — альтернатива, но менее богатые возможности
  • MongoDB — для документ-ориентированных метаданных с гибкой схемой, но отсутствие JOIN и транзакций между коллекциями — ограничение
  • Redis — как кэш поверх PostgreSQL, не как основное хранилище

Расширенный стек для других компонентов:

  • Transcoding Workers: Go/C++ с FFmpeg, GPU-ускорение (NVIDIA NVENC/NDEC)
  • Search Service: Java/Kotlin + Elasticsearch клиент
  • API Gateway: Go (Echo/Gin) или Envoy
  • Analytics/Metrics: ClickHouse или Apache Druid для аналитики, Prometheus + Grafana для мониторинга
  • Object Storage: MinIO (on-premise) или AWS S3
  • CDN: CloudFront, Cloudflare, Akamai
  • Оркестрация: Kubernetes, Docker
  • Service Mesh: Istio или Linkerd для межсервисной коммуникации

Принцип выбора:

Выбор технологии должен определяться не предпочтениями команды, а профилем нагрузки: I/O-bound vs CPU-bound, latency-sensitive vs throughput-oriented, strong consistency vs eventual consistency. Для каждого компонента — свой оптимальный стек.