- Тема и целевая аудитория
- Расчет нагрузки
- Глобальная балансировка нагрузки
- Локальная балансировка
- Логическая схема БД
- Физическая схема БД
- Алгоритмы
- Технологии
- Обеспечение надежности
- Схема проекта
- Базовый расчёт аппаратных ресурсов
Twitch - видеостриминговый сервис.
- Регистрация/авторизация
- Создать стрим
- Смотреть стрим
- Подписка на стримера
- Писать в чат
- Ставить реакции стриму, лайк/дизлайк
- Поиск стримеров по категориям, тегам, ключевым словам
- Хранение записи стрима после завершения
- Просмотр записи
- рекомендации стримов на основе интересов
- бесконечная лента прямых трансляций
- 7 дней хранения записи прямых трансляций для обычных пользователей и 60 дней для партнеров, на количество самих записей в этот период ограничений нет 1
- буферизация прямых трансляций и записей
- MAU 240M2
- DAU 30M2
- общее количество посещений за январь 2025 - 1.2B 3
- В месяц 7M человек запускает стрим хотя бы раз, активных стримеров в день 1.2M 3
- одновременно просматривает в среднем 2.5M пользователей, пик 7M 3
- одновременное количество прямых трансляций 100K 3
- среднее количество стримов в месяц более 7M 3
- среднее время общей длительности стримов за месяц - 65.7M, за день - 2.5M 3
- было отправлено более 28B ообщений в чате за год, т.е ~80M в день, ~2.33B в месяц (2023 год) 4
- на мобильные устройства приходится 35% всех просмотров 2
- средняя продолжительность прямой трансляции на Twitch 3 часа5
- смотрят в среднем 1,7B часов контента в месяц 3
- среднее время сессии 36 минут 6
- одновременное количество зрителей - 3.44M
- максимальное количество подписчкиков - 19M
- 52% пользователей в возрасте 25-34 лет 5
- 22% пользователей в возрасте 35-44 лет 5
- 72% пользователей - мужчины
Десктоп трафик в 2024 5
| № | Страна | Количество пользователей | % от общего числа |
|---|---|---|---|
| 1 | США | 49.5M | 20.6% |
| 2 | Германия | 16.9M | 7.17% |
| 3 | Россия | 11.6M | 4.85% |
| 4 | Франция | 11.44M | 4.61% |
| 5 | Япония | 10.5M | 4.39% |
Аудитория 2
| Тип | Количество |
|---|---|
| MAU | 240M |
| DAU | 30M |
| Тип | Среднее в месяц от 1 юзера |
В месяц от всех юзеров |
|---|---|---|
| Регистрация/авторизация | 0.05 | 2M (регистраций) + 12M = 14M |
| Проведение стрима |
3ч | 75M часов |
| Просмотр стрима |
14мин* | 1.7B часов 3 |
| Подписки | 3 | 720M |
| Сообщения в чате |
9.7 | 2.33B 4 |
| Реакций на стрим |
1.5 | 360M |
| Поиск | 20 | 4.8B |
| Посещения профиля |
4 | 960M |
| Сохранение записи стрима | 1.5** | 10.5M |
| Просмотр записи | 5 | 1.2B |
- ( * ) Из расчета, что MAU 240M2
- ( ** ) Из расчета, что активных стримеров 7M, в среднем в месяц проходит 3 стрима, половина стримов сохраняется
| Тип | Размер |
|---|---|
| Аватарка | 200КБ |
| Фото баннер | 200КБ |
| Общая информация* | ~2КБ |
| Итого | 402КБ |
- ( * ) Имя пользователя и отображаемое имя пользователя до 25 символов, информация о себе до 300 символов, кодировка utf8 - 4б, итого 350 * 4б / 1024 ~ 2КБ
- Максимальный размер загружаемых аватарки/банеров 10МБ, но сжимается до 200КБ
| Тип | Размер |
|---|---|
| Стримы* | 75ГБ |
| Чат** | 126Мб |
| Итого | 75,16Гб |
У Twitch нет возможности вести прямую трансляцию в 2к и 4к, это находится на этапе тестирования 7. Twitch рекомендует делать трансляцию в 1080р с битрейтом 6000кбит/с 7 . Средний размер файла на 1минуту с таким разрешением 40МБ. Но так как при просмотре записи Twitch предлагает выбор из качеств видео: 720р60 - в среднем 30МБ/мин, 480 - 11МБ/мин, 360 - 7МБ/мин, 240 - 5МБ/мин, 144 - 3МБ/мин.
Без потери качества можно сжать на 30%
- ( * ) Отсюда, информация, что общая длительность прямых трансляций 65.6M, и средняя продолжительность стрима - 3ч, и 7M активных стримеров в месяц (т.е проводят хотя бы 1 трансляцию в месяц) => 65.7M/7M = 9.4ч на стримера в месяц или ~3 стрима в месяц. Запись хранится 60 дней, т.е 2 месяца Посчитаем размер хранилища за 2 месяца: 2 * 9.4 * 60мин * (40 + 30 + 11 + 7 + 5 + 4) = 109416МБ. Итого после сжатия 109 416МБ* 0.7 = 76591.2МБ ~ 75ГБ.
- ( ** ) Из расчетов действий пользователя получим, что среднее количество сообщений в чате 1100, максимальный размер сообщения 500 символов 8 , при кодировке utf8 1100 * 500 * 4Б * 60= 126МБ
Точных данных по количеству зарезарегистрированных аккаунтов на Twitch нет, при MAU 240M2 пусть общее количество будет 2.4B (1 к 10). Стримеров в месяц 7M3
| Тип | Размер |
|---|---|
| Пользователи | 49.1ТБ |
| Стримеры | 501.75ПБ |
| Итого | 501.8ПБ |
Twitch работает по протоколу RTMP 9 , который работает поверх TCP. Раз в секунду делается запрос на получение фрагмента стрима.
| Тип | Средний RPS | Сетевой трафик (средний) |
Пиковый RPS | Сетевой трафик (пиковый) |
|---|---|---|---|---|
| регистрация /авторизация |
6 | 12Мбит/с | 12 | 24Мбит/с |
| Проведение стрима |
100К | 0.6Тбит/с | 250K | 1.2Тбит/с |
| Просмотр стрима |
2.5M | 15Тбит/с | 5M | 30Тбит/с |
| Подписки | 300 | 240Мбит/с | 600 | 480Мбит/с |
| Чат | 1000 | 20Мбит/с | 2000 | 40Мбит/с |
| Реакции | 250K | 120Мбит/с | 500K | 240Мбит/с |
| Поиск | 2K | 1000Мбит/с | 4К | 2000Мбит/c |
| Переход в профиль |
370 | 1200Мбит/с | 740 | 2400Мбит/с |
| Хранение записи | 300 | 1.72Гбит/с | 600 | 3.44Гбит/с |
| Просмотр записи стрима | 5 | 0.05Гбит/с | 10 | 0.1Гбит/с |
| Итого | 2.9M | 15.6Тбит/с | 5.8M | 32.7Тбит/с |
Основной тип нагрузки приходиться на сервис стриминга и просмотра стрима, логично вывести их в отдельный домен.
Twitch не предоставляет гарантии единой задержки для всех пользователей и может меняться в зависимости от скорости интернета, к примеру на картинке снизу, настройка слева - "4g - быстрый", справа - "4g - медленный", и задержка может замедлиться динамически при замедлении интернета и исчерпании буфера.
При отсутствии гарантии по длительности задержки ДЦ Twitch можно расположить исходя из плотности населения и популярности сервиса в регионе.
В части 1, привел информацию по десктоп трафику, но нужно расширить и на мобильный трафик.
Так как точные данные по трафику не раскрыты, можно сделать некоторые выводы из локальности языков 10, нужно чтобы расширить список стран, где Twitch популярен:
| Язык | Среднее количество одновременных зрителей |
Среднее количество одновременных стримов |
|---|---|---|
| Английский | 1134.2K | 56.1K |
| Русский | 253.7K | 7.1K |
| Испанский | 185.5K | 8.1K |
| Немецкий | 161K | 4.6K |
| Французкий | 159.6K | 4.9K |
| Португальский | 156.1K | 4.5K |
| Японский | 142.2K | 4.5K |
- На испанском языке говорят в следующих странах: Испания, страны Латинской Америки
- На немецком языке говорят в следующих странах: Германия, Австрия, Лихтенштейн, а также одним из официальных языков Швейцарии, Люксембурга и Бельгии.
- На русском языке говорят в следующих странах: Россия и Беларусь
- На французком языке говорят:
- в странах Европы: Франция, Бельгия, Люксембург и др
- в странах Америки: Канада, США
- в странах Африки
- На португальском говорят в следующих странах: Бразилия, в странах Африки
Исходя из этой информации, общий трафик Twitch будет из этих стран:
| № | Страна / Регионы | Основной язык | Десктоп (пользователей, млн / доля) | (сред. зрители / стримы) |
|---|---|---|---|---|
| 1 | США | Английский | 49.5M / 20.6% | 1134.2K / 56.1K |
| 2 | Германия и сопутств. страны (Австрия, Швейцария, Лихтенштейн) | Немецкий | 16.9M / 7.17% | 161K / 4.6K |
| 3 | Россия, Беларусь, Казахстан | Русский | 11.6M / 4.85% | 253.7K / 7.1K |
| 4 | Франция и франкофонные регионы (Бельгия, Люксембург, Канада, часть США и др.) | Французский | 11.44M / 4.61% | 159.6K / 4.9K |
| 5 | Япония | Японский | 10.5M / 4.39% | 142.2K / 4.5K |
| 6 | Испания и Латинская Америка | Испанский | – | 185.5K / 8.1K |
| 7 | Бразилия и африканские страны | Португальский | – | 156.1K / 4.5K |
Расположение ЦОД:
- Америка:
- Северная Америка:
- В США, часть серверов, при резком увеличении трафика, могут облуживать Мексику и Канаду (10шт):
- Нью-Йорк, может брать на себя часть трафика из Канады
- Вашингтон
- Майами, может брать на себя часть трафика из Мексики
- Атланта
- Колумбус, может брать на себя часть трафика из Канады
- Канзас-Сити
- Хьюстон, может брать на себя часть трафика из Мексики
- Сан-Франциско, может брать на себя часть трафика из Канады
- Денвер, может брать на себя часть трафика из Канады
- Лос-Анджелес, может брать на себя часть трафика из Мексики 11. Эль-Пасо 12. Ноксвилл 13. Чикаго 14. Мемфис 15. Даллас 16. Миннеаполис , может брать на себя часть трафика из Канады
- Канада:
- Эдмонтон
- Монреаль, может брать на себя часть трафика из США 3. Ванкувер, может брать на себя часть трафика из США
- Мексика
- Мехико
- Масалтан
- В США, часть серверов, при резком увеличении трафика, могут облуживать Мексику и Канаду (10шт):
- Южная Америка (3шт):
- Лима
- Буэнос-Айрес 3. Форталеза 4. Рио-де-Жанейро
- Северная Америка:
- Европа
- Великобритания:
- Лондон, может брать трафик на себя из Ирландии
- Ирландия:
- Дублин
- Франция:
- Париж, трафик Франции
- Лион, трафик Франции и Италии 3. Марсель
- Италия:
- Милан
- Испания
- Бальбао, может брать трафик на себя из Франции и Испании
- Лиссабон, может брать трафик на себя из Северной Африки
- Германия:
- Франкфурт
- Мюнхен, может брать трафик на себя из Италии
- Австрия:
- Вена, может брать трафик на себя из Германии и восточной Европы
- Польша: 1. Варшава, Трафик из Восточной Европы
- Греция:
- Афины, может брать трафик на себя из Турции, Юго-Восточной Европы
- Швеция:
- Стокгольм
- Западная часть России:
- Санкт-Петербург, , может брать на себя часть трафика из Финляндии
- Москва
- Воронеж
- Сербия:
- Белград
- Великобритания:
- Южная Африка
- Яунде
- Азия:
- Восточная частть России:
- Новосибирск
- Сингапур
- Япония:
- Токио
- Осака
- Австралия:
- Сидней
- Восточная частть России:
| № | ЦОД | Доля | средний RPS | Средние сетевые нагркузки в Гбит/с |
|---|---|---|---|---|
| 1 | Нью-Йорк | 3% | 87K | 480 |
| 2 | Вашингтон | 2% | 58K | 320 |
| 3 | Майами | 2% | 58K | 320 |
| 4 | Атланта | 2% | 58K | 320 |
| 5 | Колумбус | 2% | 58K | 320 |
| 6 | Канзас-Сити | 1% | 29K | 160 |
| 7 | Хьюстон | 3% | 87K | 480 |
| 8 | Сан-Франциско | 2% | 58K | 320 |
| 9 | Денвер | 2% | 58K | 320 |
| 10 | Лос-Анджелес | 3% | 87K | 480 |
| 11 | Эль-Пасо | 2% | 58K | 320 |
| 12 | Ноксвилл | 2% | 58K | 320 |
| 13 | Чикаго | 3% | 87K | 480 |
| 14 | Мемфис | 3% | 87K | 480 |
| 15 | Даллас | 2% | 58K | 320 |
| 16 | Миннеаполис | 3% | 87K | 480 |
| 17 | Эдмонтон | 2% | 58K | 320 |
| 18 | Монреаль | 2% | 58K | 320 |
| 19 | Ванкувер | 2% | 58K | 320 |
| 20 | Мехико | 2% | 58K | 320 |
| 21 | Масалтан | 2% | 58K | 320 |
| 22 | Лима | 1% | 29K | 160 |
| 23 | Буэнос-Айрес | 2% | 58K | 320 |
| 24 | Форталеза | 2% | 58K | 320 |
| 25 | Рио-де-Жанейро | 3% | 87K | 480 |
| 26 | Лондон | 2% | 58K | 320 |
| 27 | Дублин | 1% | 29K | 160 |
| 28 | Париж | 2.5% | 72.5K | 400 |
| 29 | Лион | 2.5% | 72.5K | 400 |
| 30 | Марсель | 2.5% | 72.5K | 400 |
| 31 | Милан | 2% | 58K | 320 |
| 32 | Бальбао | 2% | 58K | 320 |
| 33 | Лиссабон | 2% | 58K | 320 |
| 34 | Франкфурт | 2.5% | 72.5K | 400 |
| 35 | Мюнхен | 2.5% | 72.5K | 400 |
| 36 | Вена | 2.5% | 72.5K | 400 |
| 37 | Варшава | 1% | 29K | 160 |
| 38 | Стокгольм | 1% | 29K | 160 |
| 39 | Москва | 3% | 87K | 320 |
| 40 | Санкт-Петербург | 3% | 87K | 480 |
| 41 | Воронеж | 2% | 58K | 320 |
| 42 | Новосибирск | 2% | 58K | 320 |
| 43 | Белград | 1% | 29K | 160 |
| 44 | Токио | 3% | 95.7K | 480 |
| 45 | Осака | 3% | 95.7K | 480 |
| 46 | Сингапур | 1% | 29K | 160 |
| 47 | Сидней | 2% | 58K | 320 |
Поскольку дата-центры Twitch расположены по всему миру, целесообразно использовать GeoDNS. Пользователь, отправляя DNS-запрос, получает ответ от глобальной системы, которая основывается на географическом положении пользователя. Она направляет запросы на ближайший ДЦ к пользователю
| Area | Основные ДЦ |
|---|---|
| Северо-восток США и Канада | Нью-Йорк, Вашингтон, Монреаль, Колумбус, Чикаго, Торонто, Миннеаполис |
| Юго-восток США и Мексика | Майами, Атланта, Ноксвилл, Хьюстон, Эль-Пасо, Мехико Даллас, Мемфис |
| Запад США и Канады | Сан-Франциско, Лос-Анджелес, Ванкувер, Денвер, Эдмонтон Хомер |
| Южная Америка | Рио-де-Жанейро, Форталеза, Лима, Буэнос-Айрес |
| Западная Европа | Лондон, Дублин, Париж, Лион, Марсель, Франкфурт, Мюнхен |
| Южная Европа и Африка | Бальбао, Лиссабон, Милан, Афины, Яунде |
| Восточная Европа и Россия | Варшава, Белград, Вена, Санкт-Петербург, Москва, Воронеж, Стокгольм |
| Восточная Азия | Токио, Осака, Новосибирск |
| Юго-Восточная Азия | Сингапур, Сидней |
Для обеспечения быстрого отклика и отказоустойчивости Twitch объединяет несколько географически распределённых серверов под одним Anycast IP-адресом. Запросы пользователей направляются через глобальную BGP-сеть к ближайшему узлу, на основе маршрутов сети провайдера т.е по hop'ам
Для выбора NGINX балансировщика используем L3 балансировщик
стоят несколько балансировщиков, используется схема active-passive, один работает, другие следят за его работой, при падении ввыбирается следующий по приоритету
При помощи NGINX
- Для доставки видеопотоков и сообщений чата используется алгоритм Least Connections, который направляет запросы на серверы с минимальной текущей нагрузкой.
- Некритичные к задержкам запросы балансируются по Weighted Round Robin
Для взаимодействия между внутренними сервисами используется отдельный внутренний балансировщик Nginx, настроенный на Weighted Round Robin.
- Регулярная проверка состояния серверов (Healthcheck) с помощью встроенных механизмов Kubernetes
- Если сервер перестает отвечать, балансировщик исключает его из маршрутизации
- Регулярная проверка софта, с помощью специальных запросов
- Таймаут на основе квантилей, если сервер начинает отвечать медленнее, чем 95% других серверов, его соединения закрываются, а новые запросы перенаправляются на более производительные серверы.
- Выполняется асинхронная репликация данных между дата-центрами (например, чат-сообщения и метаданные о стримах), чтобы минимизировать потери информации в случае аварий.
- В случае сбоя одного сервера или кластера нагрузка автоматически перераспределяется на резервные серверы с минимальной задержкой переключения.
- SSL-терминация выполняется на уровне балансировщика Nginx, после чего внутри дата-центра обмен между сервисами осуществляется по протоколу HTTP, снижая нагрузку на софт.
- В каждом ДЦ несколько балансировщиков 5-15 (в зависимости от нагрузки), для того чтобы при падении одного балансировщика, остальные перенимали нагрузку
- Использование отдельного auth сервиса, для того чтобы не нагружать тяжелые бекенды.
- Использование кеширования SSL-сессий,
Расчет для среднего RPS
- Полный handshake (PFS) 2 мс
- Возобновление сессии из кэша 0.5 мс
| Тип запроса | Доля | RPS | Время CPU | Итого CPU |
|---|---|---|---|---|
| Полный handshake | 30% | 870,000 | 2мс | 1,740,000мс |
| Session cache | 70% | 2,030,000 | 0.5мс | 1,015,000мс |
| Итого: | 100% | 2,900,000 | – | 1,885,000мс |
1,885,000мс=1,885c CPU
В пиковое 3.77c CPU
- синий: Tarantool
- голубой: S3
- фиолетовый: ElasticSeatrch
- оранжевый: YDB
- желтый: ClickHouse
- серый: ydb topic service
| Имя столбца | Описание | size | Особенности распределения нагрузки по ключам | Нагрузки |
|---|---|---|---|---|
user_id (PK) |
Идентификатор UUID, PK |
16Б |
частота доступа может быть неравномерной популярные/активные пользователи - горячие точки чтения | Чтение: Вход + Переход на профиль + для стримеров для отображения в ленте Запись: Регистрация + подписки + редактирование |
banner_url |
Идентификатор UUID, FK | 16Б | - | |
avatar_url |
Идентификатор UUID, FK | 16Б | - | |
username |
Имя пользователя text |
~25Б | - | |
email |
Email пользователя, уникальное, text | ~100Б | Доступ по email может быть неравномерным. |
|
phone_number |
Номер телефона | ~15Б | Доступ по phone_numberможет быть неравномерным. |
|
description |
Описание профиля | ~2КБ | - | |
password |
Хеш пароля | ~100Б | - | |
followers |
Количество подписчиков | ~8Б | Обновления могут быть частыми для популярных пользователей | |
is_deleted |
Флаг удаления | 1Б | - | |
is_blocked |
Флаг блокировки | 1Б | - | |
unblock_date |
Дата разблокировки | 12Б | - | |
updated_at |
Время последнего обновления | 12Б | - | |
created_at |
Время создания | 12Б | - |
На запись в среднем 600Б, всего 2.5млрд пользователей Итого: ~ 1.36ТБ
| Имя столбца | Описание | size | Особенности распределения нагрузки по ключам | Нагрузка |
|---|---|---|---|---|
stream_id (PK) |
Идентификатор UUID, PK | 16Б | горячие -- популярные активные стримы | Запись при старте/стопе (~2.7 RPS avg). Обновление статуса (часть 100K RPS Streaming?). Чтение (часть 2.5M RPS Watching + 370 RPS Profile). Высокая. |
user_id (FK) |
Идентификатор UUID, FK | 16Б | - | |
video_id (FK) |
Идентификатор UUID, FK | 16Б | - | |
title |
Название стрима | 100Б | - | |
description |
Описание стрима | 1КБ | - | |
status |
Статус стрима (live, offline, etc.) | 10Б | - | |
start_time |
Время начала стрима | 12Б | - | |
end_time |
Время окончания стрима | 12Б | - | |
tags |
Теги стрима | 200Б | - | |
category |
Категория | 30Б | - | |
category_id |
Идентификатор UUID, FK | 16Б | ||
likes |
Количество лайков | 8Б | Частые обновления для популярных стримов. | Обновляется асинхронно через reaction_q. |
updated_at |
Время последнего обновления | 12Б | - | |
created_at |
Время создания | 12Б | - |
На строку 1484Б На таблицу ~20ГБ
| Имя столбца | Описание | size |
|---|---|---|
category_id (PK) |
Идентификатор категории (UUID, ), PK | 16Б |
name |
Название категории | 30Б |
picture_url |
Ключ изображения категории в S3 | 16Б |
updated_at |
Время последнего обновления | 12Б |
created_at |
Время создания | 12Б |
Строка 86Б Допустим 100 категорий => 8,4КБ
| Имя столбца | Описание | size | Требования к консистентности | Особенности распределения нагрузки по ключам | нагрузки |
|---|---|---|---|---|---|
id (PK) |
Идентификатор UUID PK | 16Б | Strong | Равномерное по id. |
Нагрузка: Запись (300 RPS avg). Чтение (для списков подписок/подписчиков...). |
user_id (FK) |
Идентификатор UUID, FK | 16Б | Strong | Запросы по user_id (если индекс) могут быть неравномерными. |
|
follow (FK) |
Идентификатор UUID, FK | 16Б | Strong | Запросы по follow (если индекс) будут крайне неравномерными, с горячими точками на популярных пользователях. |
|
created_at |
Время создания подписки | 12Б | Strong | - |
На строку 60Б На таблицу 33,53ГБ (~600М подписок)
| Имя столбца | Описание | Размеры данных и нагрузки | Особенности распределения нагрузки по ключам |
|---|---|---|---|
role_id (PK) |
Идентификатор роли (UUID, 16 байт), PK | 16Б | Равномерное по role_id. |
streamer_id |
Идентификатор стримера (UUID, 16 байт) | 16Б | Неравномерное: Запросы к ролям конкретного стримера -> горячие точки. Нужен индекс по streamer_id. |
user_moders |
Массив ID модераторов (N * 16 байт) | 160Б | - |
user_blocked |
Массив ID заблокированных нужно держать отсортированным, для лучшего поиска |
1КБ | - |
updated_at |
Время последнего обновления | 12Б | - |
created_at |
Время создания | 12Б | - |
Строка 1240Б Таблица 23ГБ
| Имя столбца | Описание | size | Особенности распределения нагрузки по ключам |
|---|---|---|---|
user_id (PK) |
Идентификатор пользователя UUID, PK | 16Б |
Частота доступа зависит от активности пользователя. |
value |
токен сессии, UUID | 16Б | - |
ttl |
Время жизни сессии | 12Б | - |
region |
Регион | 100Б | - |
language |
Язык | 20Б | - |
updated_at |
Время последнего обновления | 12Б | - |
created_at |
Время создания | 12Б | - |
Строка 200Б Таблица ~44,7ГБ
| Имя столбца | Описание | size | Особенности распределения нагрузки по ключам | нагрузки |
|---|---|---|---|---|
message_id (PK) |
Идентификатор UUID, PK | 16Б | Равномерное по message_id (если UUID). |
Запись (1K RPS avg, 2K peak). Чтение (часть 2.5M RPS Watching). |
user_id |
Идентификатор UUID, FK | 16Б | - | |
stream_id (FK) |
Идентификатор стрима (UUID, 16 байт), FK (шард. ключ) | 16Б | Крайне неравномерное: Нагрузка концентрируется на "горячих" stream_id. Требует шардирования по stream_id. |
|
text |
Текст сообщения (до 500 симв) | 500Б | - | |
is_deleted |
Флаг удаления | 1Б | - | |
updated_at |
Время последнего обновления | 12Б | - | |
created_at |
Время создания (индекс + TTL ключ) | 12Б | Используется для сортировки и TTL. |
Строка 1096Б Таблица 2.5ТБ
| Имя столбца | Тип данных | Описание | size | Особенности распределения нагрузки по ключам | Нагрузка |
|---|---|---|---|---|---|
stream_id (PK) |
uuid |
Идентификатор UUID, PK | 16Б | Крайне неравномерное: Нагрузка концентрируется на "горячих" stream_id. Требует шардирования по stream_id. |
Нагрузка: Атомарные инкременты/декременты (часть 100K RPS Streaming). Чтение (часть 2.5M RPS Watching). Очень высокая. |
viewers_counter |
int |
Счетчик зрителей | 8Б | Частые атомарные инкременты/декременты на "горячих" stream_id. |
|
updated_at |
timestamp |
Время последнего обновления | 12Б | - |
Строка 36Б Таблица 1МБ
| Имя столбца | Описание | size | Особенности распределения нагрузки по ключам | нагрузки |
|---|---|---|---|---|
id (PK) |
Идентификатор UUID, PK | 16Б | Равномерное по id (если UUID). |
Нагрузка: Запись (250K RPS avg). Очень высокая. Чтение - низкое. |
user_id (FK) |
Идентификатор пользователя (UUID, 16 байт), FK | 16Б | - | |
stream_id (FK) |
Идентификатор стрима (UUID, 16 байт), FK (шард. ключ) | 16Б | Крайне неравномерное: Нагрузка концентрируется на "горячих" stream_id. Требует шардирования по stream_id. |
|
reaction_type |
Тип реакции (like/dislike/etc.) | 10Б | - | |
created_at |
Время создания реакции (TTL ключ?) | 12Б | Используется для TTL, если храним недолго. |
Строка 70Б Таблица 100ГБ
| Имя столбца | Описание | Размеры данных и нагрузки | Особенности распределения нагрузки по ключам | Нагрузка |
|---|---|---|---|---|
stream_id (PK) |
Идентификатор стрима (UUID, 16 байт), PK (шард. ключ) | 16Б | Крайне неравномерное: Нагрузка концентрируется на "горячих" stream_id. Требует шардирования по stream_id. |
Атомарные инкременты (250K RPS avg). Чтение (часть 2.5M RPS Watching). Очень высокая. |
counters |
Счетчики | 16Б | Частые атомарные инкременты по ключам в map на "горячих" stream_id. |
|
updated_at |
Время последнего обновления | 12Б | - |
Строка 44Б Таблица в среднем 30МБ
| Имя столбца | Описание | size | Особенности распределения нагрузки по ключам | Нагрузка |
|---|---|---|---|---|
user_id (PK) |
Идентификатор пользователя (UUID, 16 байт), PK (шард. ключ) | 16Б | Неравномерное: Ключ для быстрого доступа. Нагрузка концентрируется на "горячих" user_id. |
Запись/Удаление (300 RPS avg). Чтение (часто, >300 RPS). |
| `followers | Счетчик подписчиков user_id |
8Б | Атомарные инкременты/декременты. | |
following_count |
Счетчик подписок user_id |
12Б | Атомарные инкременты/декременты. |
Строка 36Б Таблица 100МБ
| Название | storage | Примерный размер |
Шардирование | Индексы | Репликация |
|---|---|---|---|---|---|
| user | YDB | ~1.36 ТБ | Для разделения данных на несколько серверов и масштабирования записи хэш функция для распределения по шардам, популярных вручную. ключ -- user_id |
- user_id: HASH - email : HASH - phone: HASH |
master-slave 5 реплики Полусинхронная |
| stream | YDB | ~20 ГБ | - | - stream_id: HASH - user_id: TREE - status |
master-slave 5 реплик Полусинхронная |
| category | YDB | ~8.4 КБ | - | master-slave 3 реплики |
|
| follow | YDB | ~33.5 ГБ | - | - user_id: HASH | master-slave 5 реплик Полусинхронная |
| roles | YDB | ~23 ГБ | - | -streamer_id: HASH | master-slave 5 реплик Асинхронная |
| category _search |
YDB | Переменный | - | -category_name: HASH | Асинхронная 3 реплики master-slave |
| stream_ reaction |
YDB | ~100 ГБ | Для масштабирования записи и разделения данных на несколько серверов и масштабирования записи хэш функция stream_id |
- stream_id: HASH | Полусинхронная 3 реплики master-slave |
| sessions | Tarantool | ~44.7 ГБ | - | - user_id: HASH - value: TREE |
Полусинхронная 3 реплики master-slave |
| message | YDB | ~2.5 ТБ | Для разделения данных на несколько серверов хэш функция user_id(стримера) stream_id |
(stream_id, created_at) : TREE |
Асинхронная, 5 Реплик master-slave |
| viewers | Tarantool | ~100 МБ | - | ПК (stream_id) |
Асинхронная, 5 Реплик master-slave |
| users _reactions |
Tarantool | ~100 ГБ | Для масштабирования записи и разделения данных на несколько серверов и масштабирования записи хэш функция stream_id |
- (stream_id, created_at): TREE |
Полусинхронная 3 реплики master-slave |
| reactions | Tarantool | ~1000 МБ | - | - stream_id: HASH | Полусинхронная 5 реплик master-slave |
| follow | Tarantool | ~100 МБ | - | -user_id: HASH | Полусинхронная 5 реплик master-slave |
| follow_q | YDB Topic | Переменный | хэш функцияuser_id |
- | Синхронная, 3 реплики |
| reaction_q | YDB Topic | Переменный | хэш функцияstream_id |
- | Синхронная, 3 реплики |
| stream_q | YDB Topic | Переменный | хэш функцияstream_id |
- | Синхронная, 3 реплики |
| personal_stream_rec (Tier 1) | Tarantool | ~1ТБ | хэш функцияuser_id |
(user_id, stream_id) TREE (user_id, score, stream_id) TREE |
Master-Slave, Асинхронная, 3 реплики |
| regional_category_stream_rec (Tier 2) | Tarantool | ~2ГБ | - | (region, category_id, stream_id) TREE (region, category_id, score DESC, stream_id DESC) [TREE] |
Master-Slave, Асинхронная, 3 реплики |
| user_favorite_categories (Tier 2) | Tarantool | ~50ГБ | - | (user_id, category_id): TREE (user_id, preference_score DESC, category_id DESC): TREE |
Master-Slave, Асинхронная, 3 реплики |
| message | Tarantool | Переменный | (stream_id, created_at) : TREE |
Асинхронная, 5 Реплик master-slave |
| Алгоритм | Область применения | Мотивация | Описание |
|---|---|---|---|
| 1. Построение ленты рекомендаций | Формирование главной страницы пользователя с рекомендуемыми прямыми трансляциями и категориями. | Обеспечить персонализированный контент для удержания пользователя и повышения его вовлеченности. Увеличить обнаруживаемость стримеров. Обеспечить быструю загрузку ленты для пользователя. Решить проблему отсутствия рекомендаций для новых пользователей |
Лента строится на основе предпочтений пользователя (язык, геолокация, история просмотров, лайки, данные из not_interest_category и not_interest_streamers). Для оптимизации производительности используется двухфазный подход:Offline-фаза: Предварительный расчет широкого списка кандидатов для пользователя/сегмента на основе исторических данных. Online-фаза: При запросе ленты выполняется быстрая фильтрация и доранжировка кандидатов с учетом свежих данных (текущие онлайн-стримы, недавние действия пользователя). Для новых пользователей используются популярные стримы в их регионе/языке, предложение выбрать интересующие категории при регистрации или анализ самых первых действий. |
| 2. Адаптивная трансляция видеопотока через CDN (ABR) | Доставка видеоконтента (прямые трансляции и записи) от сервера стримера до конечного зрителя. | Обеспечить плавное и бесперебойное воспроизведение видео для пользователей с разной скоростью и стабильностью интернет-соединения. Минимизировать задержки (latency) при просмотре прямых трансляций. Оптимизировать использование пропускной способности сети (сервиса и пользователя). Обеспечить масштабируемость и отказоустойчивость процесса обработки и доставки видео. | Входящий видеопоток от стримера нарезается на небольшие видео-чанки. Метаданные чанков помещаются в очередь . Несколько типов сервисов-обработчиков асинхронно читают из очереди: 1) Транскодеры: Создают версии чанка в разных качествах. 2) Загрузчики в S3: Сохраняют оригинальные и транскодированные чанки 3) Обновление манифеста: Добавляют информацию о новых чанках в манифест стрима. CDN запрашивает манифесты и чанки (из S3 или серверов раздачи) и кэширует их для доставки зрителям. |
- Шаги:
- Сбор данных: Агрегация данных об активностях пользователей и метаданных стримов .
- Формирование признаков:
- Создание векторных представлений для пользователей на основе их истории просмотров, подписок, лайков
- Создание векторных представлений для стримов/категорий на основе их метаданных (текст, теги), жанра и аудитории, которая их смотрит.
- Модель: гибрид из:
- Коллаборативная фильтрация: Поиск похожих пользователей и рекомендация того, что им нравится; или поиск похожих стримов на те, что пользователь уже смотрел.
- Контент-базированная фильтрация: Рекомендация стримов, похожих по контенту (категория, теги, описание) на те, с которыми взаимодействовал пользователь.
- Генерация кандидатов: Применение обученных моделей ко всем парам (пользователь, стрим). Результат - большой список вида (user_id, streamer_id, predicted_score).
- Сохранение кандидатов:
- Персональные (Tier 1): Сохранение топ-500 кандидатов для каждого пользователя .
- Сегментные (Tier 2): Расчет и сохранение популярных стримов для сегментов. Это важно для пользователей с малой историей.
- Предпочтения (Tier 2): Обновление таблицы user_favorite_categories (Tarantool) с оценками предпочтений категорий для пользователя на основе его истории.
- Шаги:
- Извлечение кандидатов:
- Запрос к БД для получения персональных кандидатов
- Если кандидатов мало или пользователь новый:
- Запрос к рекомендациям по категориям (Tier 2) для получения любимых категорий.
- Запрос к рекомендациям по региону на основе региона/языка пользователя и его любимых категорий для получения кандидатов.
- Фильтрация в реальном времени: Из объединенного списка кандидатов удаляются стримы, которые не активны
- Извлечение кандидатов:
- Ingest (Прием потока):
- Стример отправляет видеопоток на ближайший к нему Ingest сервер Twitch.
- Сегментация:
- Входящий непрерывный поток немедленно нарезается на короткие видео-сегменты (чанки) фиксированной длительности (1 секунда). Стандартные форматы: HLS (.ts сегменты + .m3u8 манифест) и DASH (.m4s сегменты + .mpd манифест). Создаются сегменты оригинального качества.
- Постановка в очередь на транскодинг:
- Метаданные о каждом созданном оригинальном сегменте помещаются в очередь сообщений.
- Транскодирование (Параллельные воркеры):
- Множество сервисов-транскодеров читают сообщения из очереди.
- Каждый транскодер берет один оригинальный сегмент.
- Он перекодирует этот сегмент в несколько представлений. Аудиодорожка также обрабатывается.
- Ключевой момент: Сегменты разных качеств должны иметь одинаковые временные метки начала и конца, чтобы переключение между ними было плавным.
- Хранение сегментов:
- И оригинальные, и все транскодированные сегменты загружаются в S3
- Обновление Манифеста:
- Сервис генерации манифестов отслеживает появление новых транскодированных сегментов для каждого стрима, через очередь.
- Он создает и постоянно обновляет манифест-файл для каждого стрима.
- Манифест содержит:
- Список всех доступных качеств видео.
- Для каждого качества - список URL-адресов доступных на данный момент сегментов в хронологическом порядке.
- Для Live-стримов манифест обновляется каждые 2 секунды: добавляются ссылки на новые сегменты, удаляются ссылки на самые старые.
- Для записей манифест создается один раз и содержит ссылки на все сегменты записи.
- Манифест также загружается в S3.
- Запрос Манифеста:
- Приложение/плеер Twitch на устройстве пользователя запрашивает основной манифест-файл стрима (M3U8 для HLS и MPD для DASH). Запрос направляется на ближайший к пользователю узел CDN.
- Анализ Манифеста и Начальная Буферизация:
- Плеер парсит манифест, чтобы узнать:
- Доступные качества видео (разрешения, битрейты).
- URL-адреса первых доступных сегментов для каждого качества.
- Плеер начинает загружать несколько первых сегментов (обычно среднего либо выбранного пользователем качества, если это произошло до старта) для формирования начального буфера воспроизведения. Воспроизведение не начнется, пока в буфере не накопится минимально необходимое количество данных (например, 1-3 сегмента), чтобы обеспечить плавный старт.
- Плеер парсит манифест, чтобы узнать:
- Логика Выбора Качества:
- Плеер проверяет, выбрал ли пользователь качество вручную или установлен режим "Авто".
- Если выбрано вручную:
- Плеер игнорирует автоматическую оценку сети.
- Он будет запрашивать сегменты только выбранного качества.
- Если пропускная способность сети пользователя окажется недостаточной для стабильной загрузки сегментов выбранного качества, буфер начнет опустошаться, что приведет к остановкам воспроизведения. Плеер не будет автоматически понижать качество. Задержка до стримера будет больше
- Если режим "Авто":
- Плеер постоянно оценивает текущую пропускную способность сети (измеряя скорость загрузки последних сегментов) и уровень заполнения буфера (сколько секунд видео уже загружено вперед).
- На основе этих данных алгоритм выбирает наиболее подходящее качество для следующего запрашиваемого сегмента, стараясь максимизировать качество без риска опустошения буфера.
- Запрос Сегмента:
- Плеер запрашивает URL следующего по порядку видео-сегмента этого качества.
- Управление Буфером и Воспроизведение:
- Плеер получает запрошенный сегмент и добавляет его в конец своего буфера воспроизведения.
- Воспроизведение видео продолжается, считывая данные из начала буфера.
- Динамика буфера и задержка:
- Плеер стремится поддерживать целевой размер буфера.
- В режиме "Авто" плеер постоянно балансирует: если буфер растет слишком быстро и сеть позволяет -> повышает качество; если буфер опустошается -> понижает качество, чтобы успеть загрузить следующий сегмент вовремя.
- В режиме ручного выбора качества:
- Если выбрано слишком высокое качество для сети: буфер опустошается, вызывая паузы. Чтобы это компенсировать, плеер может неявно увеличить желаемый размер буфера после паузы, что увеличивает задержку от реального времени.
- Достижение минимальной задержки: Чтобы быть максимально близко к live edge, плеер должен поддерживать минимально возможный, но стабильный буфер. Ручной выбор высокого качества почти всегда приводит к увеличению задержки по сравнению с оптимальным автоматическим режимом для данной сети.
| Технология | Область применения | Мотивационная часть |
|---|---|---|
| Бэкенд на Golang | Реализация бизнес-логики микросервисов (обработка API, взаимодействие с БД, обработка видеопотоков, чат и т.д.). | Высокая производительность, эффективная работа с параллелизмом (горутины) для обработки большого количества одновременных подключений (зрители, чат), статическая типизация, быстрое время компиляции, хорошее управление памятью. Подходит для высоконагруженных систем. |
| NGINX | Локальная балансировка L7, SSL-терминация, балансировка межсервисных запросов. | Распределение запросов на бэкенды, SSL-терминация,, балансировка трафика между микросервисами внутри ДЦ. |
| Kubernetes | Оркестрация контейнеров, проверка состояния сервисов. | Управление жизненным циклом приложений, автоматизация развертывания, масштабирования и мониторинга состояния для обеспечения отказоустойчивости на уровне приложений. |
| YDB | Основное хранилище | Обеспечение надежного, масштабируемого и транзакционно-согласованного хранения основных данных. Работает в связке с YDB Topic Service для гарантированной атомарной записи данных и публикации событий в рамках одной транзакции, обеспечивая консистентность между состоянием БД и асинхронными задачами. |
| YDB Topic Service | Асинхронная обработка задач, передача событий между сервисами | Обеспечение надежной и персистентной доставки событий и асинхронной обработки фоновых задач (обновление счетчиков, обработка видео, нотификации). В связке с YDB гарантирует, что события публикуются только при успешном коммите транзакции в БД, обеспечивая отказоустойчивость и сглаживание пиковых нагрузок. |
| Tarantool | Высокопроизводительное In-memory хранилище | Обеспечение минимальных задержек и высокой пропускной способности для операций с часто изменяющимися или требующими быстрого доступа данными |
| S3 Minio | Хранение больших бинарных объектов | Экономичное, масштабируемое и надежное хранение больших объемов неструктурированных данных с возможностью легкой интеграции с CDN для раздачи. |
| Elasticsearch | Полнотекстовый поиск | Обеспечение быстрого и релевантного поиска по текстовым данным, индексация контента для быстрого нахождения нужной информации пользователями. также является ядром ELK стека для поиска логов. |
| ClickHouse | Аналитическое хранилище. | Быстрая обработка и агрегация больших объемов данных для аналитики, построения отчетов, анализа пользовательского поведения. |
| WebRTC | Протокол для передачи видеопотока от стримера на сервер Twitch. | Стандартный протокол для стриминга, поддерживаемый большинством стримингового ПО, обеспечивает передачу видео, аудио и метаданных с низкой задержкой. |
| H.264 / AVC | кодирование видео для live-стриминга и VOD. | Множество аппаратных и программных реализаций кодеров/декодеров, низкая задержка кодирования для live |
| ELK Stack | Централизованный сбор, хранение, обработка, поиск и визуализация логов со всех компонентов системы. | Предоставляет мощный полнотекстовый поиск (Elasticsearch) по всем собранным логам, гибкие возможности обработки и обогащения логов (Logstash), удобный веб-интерфейс для анализа и визуализации (Kibana). Позволяет отлаживать распределенные системы |
| Система метрик (Prometheus+Grafana) | Сбор, хранение, визуализация и алертинг по метрикам системы | Мониторинг производительности и состояния системы в реальном времени, своевременное обнаружение аномалий и проблем, планирование мощностей, оценка влияния изменений, визуализация ключевых показателей для операционной команды. |
| Python | Оффлайн обучение моделей машинного обучения (рекомендации, анализ контента). | Огромная экосистема библиотек (Scikit-learn, TensorFlow, PyTorch), стандарт для ML-разработки, большое сообщество и количество специалистов, быстрая прототипизация моделей. |
| GitLab | Распределенное хранилище кода, непрерывная интеграция и доставка. | Автоматизация процессов сборки, тестирования, статического анализа и развертывания. Интеграция с репозиторием GitLab. Конфигурация пайплайнов как код. Обеспечение консистентного и быстрого процесса доставки изменений. Наличие Open Source версии дает гибкость и контроль. Широко распространенный инструмент |
| Kotlin (Android) | Разработка нативного клиентского приложения для платформы Android. | Cовременный и безопасный синтаксис, полная совместимость с Java и экосистемой Android, высокая производительность нативных приложений, активное сообщество. |
| Swift (iOS/macOS и др.) | Разработка нативных клиентских приложений для платформ Apple (iOS, macOS, tvOS). | Официальный язык Apple, современный и безопасный синтаксис, высокая производительность, тесная интеграция с фреймворками Apple, активное развитие языка и платформы. |
| React/TS - WEB | Разработка веб-клиента (сайт Twitch). | Популярная и мощная библиотека для создания пользовательских интерфейсов, компонентный подход, большая экосистема инструментов и библиотек, виртуальный DOM для эффективного обновления UI, подходит для создания сложных SPA. |
| Cloudflare CDN | Глобальная доставка контента (видео-чанки, манифесты, статика сайта, API), безопасность. | Снижение задержек: Доставка контента с серверов, максимально близких к пользователю. Повышение производительности: Кэширование снижает нагрузку на origin-серверы. Экономия трафика: Обслуживание части трафика через CDN. ** Возможность использовать как свои серверы, так и S3-совместимые хранилища (включая собственные) в качестве источника данных для CDN. |
- Резервирование
- Инфраструктурное:
- Размещение инфраструктуры в нескольких географически распределенных дата-центрах (Глобальная балансировка нагрузки). Это защищает от масштабных сбоев, затрагивающих целый регион (стихийные бедствия, крупные отключения электроэнергии).
- В рамках одного региона использование нескольких изолированных зон доступности. Каждая AZ имеет независимое питание, охлаждение и сетевое подключение, что защищает от сбоев на уровне отдельного здания или оборудования в нем.
- Использование нескольких независимых вводов электропитания, Источников Бесперебойного Питания, дизель-генераторов; нескольких интернет-провайдеров и резервных сетевых каналов; резервных систем охлаждения
- Регулярное создание резервных копий данных и хранение их в другом ДЦ
- Уровня приложений:
- Active/Active - держать несколько экземпляров сервиса в разных зонах, готовыми принять трафик при падении основного
- Резервирование ресурсов - выделение резервов CPU/RAM для автоскейла, в пиках нагрузки
- Автоматическое переключение на реплики при сбоях, при падении мастера (реплика становится мастером)
- Health Checks
- Инфраструктурное:
- Сгементирование
- API Clustering - группировка по сложности и важности эндпоинтов с отдельными пуллами серверов для каждой группы
- Вынос тяжелых сервисов (поиск и рекомендации)в отдельные сервисы
- Graceful
- Graceful Shutdown: перед отключеием контейнера, дожидаемся пока он обработает все запросы, которые уже пришли
- Graceful Degradation:
- при дефиците ресурсов или сбоях не‑критичных сервисов переключаться на упрощённую логику, упрощаем/выключаем ML.
- Перестал работать чат -- выключить
- упал транскодер -- сохранять напрямую в S3
- при падении поиска - выкл
- по какой-то причине не можем получить ленту (упала база или тп), получаем список активных стримов с наибольшим онлайном и отдаем пользователю.
- При падении сервиса подписок, сохраняется в очереди тыквы сервиса
- CQRS и «отбивка» статистики
- CQRS Разделение каналов записи и чтения, отдельные модели и БД для каждой. Гибкое масштабирование под разную нагрузку, но лаг между write и read моделями, усложнение синхронизации.
- Отбивка статистики (Асинхронная агрегация) Паттерн: при ключевых событиях (просмотр сегмента, отправка сообщения) пишем не только основную запись в БД, но и событие в брокер (YDB Topic Service → Kafka). Специализированные сервисы (Collect Service) асинхронно подсчитывают счётчики и пишут в ClickHouse/Tarantool для дашбордов.
- Наблюдаемость (Логи, Метрики, Трассировка, Мониторинг, Алерты, Профилирование)
- Логирование. Типы: access, error, формат JSON. собираем через Logstash в Elasticsearch; семплирование по user_id/request_id, чтобы избежать перегруза дисков.
- Метрики: системные (CPU, RAM, сеть), бизнес (RPS, latency, ошибки). Типы метрик: счётчики, измерители, гистограммы, квантильные метрики (p95–p99). Prometheus + Grafana для хранения и визуализации
- Tracing. Шина request_id → прокидывать по всем сервисам, сохранять время обработки в логах.
- Алерты. Настраивать на критичные метрики (p99 latency > X ms, error rate > Y %).
- Профилирование. Перфмониторинг (pprof), статическая профилировка (Golang pprof), регулярный снимок heap/CPU для поиска утечек
- Прочее
- ID идемпотентности, для исключения дублирования действий пользователя
- Практика контролируемых сбоев (отключение сервисов/серверов) для проверки устойчивости
- Rate Limits
- Качественное тестирование (units, integrations, e2e) =)
- Выкатки новых версий на часть пользователей, для выявленя проблем
-
Тяжелая бизнес-логика:
- CPU: 1 ядро на каждые 10 пиковых RPS
- RAM: 100 МБайт на каждые 100 пиковых RPS
-
Средняя бизнес-логика:
- CPU: 1 ядро на каждые 100 пиковых RPS
- RAM: 200 МБ на каждые 100 пиковых RPS
-
Легкая бизнес-логика:
- CPU: 1 ядро на каждые 5000 пиковых RPS
- RAM: 10 МБ на каждые 100 пиковых RPS
Сервисы
| Сервис | Категория | Пик RPS | Ядра (cores) | RAM |
|---|---|---|---|---|
| Сервис пользователя | лёгкая | 800 | ⌈800 / 5 000⌉ = 1 | 1 × 10 МБ = 0.01 ГБ |
| Поиск | средняя | 4 000 | ⌈4 000 / 100⌉ = 40 | 40 × 100 МБ = 4 ГБ |
| Лента | тяжёлая | 20 000 | ⌈20000 / 10⌉ = 2000 | 2000 × 100 МБ = 200ГБ |
| Чат | средняя | 2 000 | ⌈2 000 / 100⌉ = 20 | 20 × 100 МБ = 2 ГБ |
| Реакции | средняя | 500 000 | ⌈500 000 / 100⌉ = 5 000 | 5 000 × 100 МБ = 500 ГБ |
| Стриминг | тяжёлая | 250 000 | ⌈250 000 / 10⌉ = 25 000 | 25 000 × 100 МБ = 2.5 ТБ |
| Просмотр | тяжёлая | 5 000 000 | ⌈5 000 000 / 10⌉ = 500 000 | 500 000 × 100 МБ = 50 ТБ |
Базы Данных / Хранилища
| Компонент | Пиковый RPS (оценка) | Базовый CPU (Ядра) | Базовый RAM (ГБ) | Базовый Диск (ТБ) |
|---|---|---|---|---|
| YDB | 500 000 | 100 | 1 000 | 50 |
| Tarantool | 1 000 000 | 200 | 2 000 | 10 |
| S3 / Minio | 5 000 000 | 1 000 | 50ТБ | 500 000 |
| Итого БД | 6.5M | 1300 | ~50ТБ | ~500 060 |
| Ресурс | Без резерва |
|---|---|
| CPU, ядра | 534K |
| RAM, ГБ | 4 893 |
| Disk, ТБ | 500 060 |
| Network, Gbit/s | 34К |
Подберем конфигурацию ДЦ на 1% нагрузки, и нужно учесть резерв ресурсов в 30%
| Ресурс | Без резерва | С учетом резервов |
|---|---|---|
| CPU, ядра | 534K*0.01 = 5 340 | 5 340 * (1+0.3) = 6 942 |
| RAM, ГБ | 103 424*0.01 = 1 034.24 | 1 034.24 * (1+0.3)= 1 344.512 |
| Disk, ТБ | 500 060*0.01 = 5 000.6 | 5 000.6 * (1+0.3) = 6 500.78 |
| Network, Gbit/s | 34K*0.01 = 334.84 | 334.84 *(1+0.3) = 435.292 |
| Конфигурация | CPU (ядра) | RAM (ГБ) | Disk (ТБ) | Net (Gbit/s) |
|---|---|---|---|---|
| Intel Xeon Silver 4416+ (20 c/40 t) @2.0 GHz, 37.5 MB L3 ([Intel][5]) + 4×16 GB DDR5, Micron 7450 PRO 960GB NVMe U.3 (7mm) 2.5" SSD Drive - PCIe Gen4, 25/10GbE |
20 | 64 | 1.6 | 25 |
Цена за сервер €4 580 11.
Всего нужно 345 серверов на такой ДЦ.
Итого €1 580 100 на ДЦ принимающий нагрузку 1%. Годовая аморотизация(20% 5лет) €316 020. Месячная €26 335.
Расчитаем для остальных
| Ресурс | С учетом резервов |
|---|---|
| CPU, ядра | 5340 * (1.5+0.3) = 9 612 |
| RAM, ГБ | 1 034.24 * (1.5+0.3)= 1862 |
| Disk, ТБ | 5 000.6 * (1.5+0.3) = 9 002 |
| Network, Gbit/s | 334.84 *(1.5+0.3) = 603 |
Всего нужно 345*1.5 = 518 серверов на ДЦ.
Итого €2 372 440 на ДЦ. Годовая аморотизация(20% 5лет) €474 488. Месячная €39 541.
| Ресурс | С учетом резервов |
|---|---|
| CPU, ядра | 5340 * (2+0.3) = 12 282 |
| RAM, ГБ | 1 034.24 * (2+0.3)= 2 379 |
| Disk, ТБ | 5 000.6 * (2+0.3) = 11 502 |
| Network, Gbit/s | 334.84 *(2+0.3) = 771 |
Всего нужно 345*2 = 690 серверов на ДЦ.
Итого €3 160 200 на ДЦ. Годовая аморотизация(20% 5лет) €632 040. Месячная €52 670.
| Ресурс | С учетом резервов |
|---|---|
| CPU, ядра | 5 340 * (2.5+0.3) = 14 952 |
| RAM, ГБ | 1 034.24 * (2.5+0.3) = 2 896 |
| Disk, ТБ | 5 000.6 *(2.5+0.3) = 14 002 |
| Network, Gbit/s | 334.84 *(2.5+0.3) = 938 |
Всего нужно 345*2.5 = 863 серверов на ДЦ.
Итого €3 952 540 на ДЦ. Годовая аморотизация(20% 5лет) €790 508. Месячная €65 876.
| Ресурс | С учетом резервов |
|---|---|
| CPU, ядра | 5 340 * (3+0.3) = 17 622 |
| RAM, ГБ | 1 034.24 * (3+0.3) = 3 413 |
| Disk, ТБ | 5 000.6 *(3+0.3) = 16501.98 |
| Network, Gbit/s | 334.84 *(3+0.3) = 1104.972 |
Всего нужно 345*3 = 1035 серверов на ДЦ.
Итого €4 740 300 на ДЦ. Годовая аморотизация(20% 5лет) €948 060. Месячная €79 005.
Подберем на Azure конфигурацию на 1% 12.
При подобной конфигурации оплата в месяц 498 962€ или $5 987 544 в год. Таким образом выгоднее закупать собственное железо. Окупаемость ~4 месяца.
Footnotes
-
https://help.twitch.tv/s/article/video-on-demand?language=ru ↩
-
https://twitchtracker.com/statistics ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
-
https://help.twitch.tv/s/article/multiple-encodes?language=ru ↩ ↩2
-
https://discuss.dev.twitch.com/t/message-character-limit/7793 ↩
-
https://help.twitch.tv/s/article/guide-to-using-twitch-inspector?language=ru ↩
-
https://www.broadberry.eu/xeon-scalable-processor-gen4-rackmount-servers/cyberserve-xeon-sp1-102-nvme-g4 ↩













