- Проект по курсу "Проектирование высоконагруженных систем".
Twitch – это стриминговый сервис, предназначенный для трансляции потоковых видео на игровую тематику. Сервис специализируется на играх — пользователи могут наблюдать за геймплеем, киберспортивными турнирами. Смотреть можно как онлайн, так и в записи.
По состоянию на август 2023 года Twitch посещает 140 миллионов уникальных пользователей каждый месяц [ 1 ] .
Страна | Количество пользователей, млн | процент от общего количества |
---|---|---|
США и Канада | 93 | 36.32% |
Бразилия | 16.9 | 6.6% |
Германия | 16.8 | 6.56% |
Англия | 13.4 | 5.23% |
Франция | 11.3 | 4.41% |
Россия | 10.5 | 4.1% |
Испания | 10.5 | 4.1% |
Аргентина | 10 | 3.9% |
Мексика | 9.2 | 3.59% |
Италия | 8.3 | 3.24% |
Турция | 7.5 | 2.92% |
Южная Корея | 6.7 | 2.61% |
Польша | 4.8 | 1.87% |
Япония | 4.1 | 1.6% |
Австралия | 4.1 | 1.6% |
Большая часть аудитории приходится на Северную Америку — 39.91%. На втором месте Европа — 32.43%. На третьем месте Южная Америка — 10.5%.
- Регистрация пользователей
- Проведение/просмотр прямых трансляций
- Просмотр закончившихся трансляций
- Подписки на пользователей
- Поиск трансляций
- Чат трансляции
- Месячная аудитория(MAU) — 140 млн пользователей
- Дневная аудитория(DAU) — 31 млн пользователей
- Средняя суммарная длительность всех трансляций за один день — 2 400 000 часов
- Среднее число трансляций в день — 1 300 000
Тогда средняя продолжительность трянсляции:
По статистике пользователь тратит в день суммарно 95 минут на просмотр прямых трансляций на Twitch.
Можно предположить, что большинство пользователей не тратят все время на одну трансляцию, тогда в среднем пользовель посещает
На основе наблюдения за количеством сообщений в секунду, можно сказать, что среднее количество примерно 600 сообщений. Тогда в день —
частота, млн/день | |
---|---|
Начало трансляции | 1.1 |
Отправка сообщения в чат | 52 |
Открытие трянсляции | 2.3 |
На платформе Twitch срок хранения трансляции зависит от статуса пользователя.
Категория | срок хранения |
---|---|
Партнеры | 60 дней |
Компаньоны | 14 дней |
Остальные | 7 дней |
По статистике общее количество партнеров Twitch составляет 63 тыс, компаньонов — 2.1 млн, останльных - 14.5 млн. Каждый день проводиться около 1.3 * 10^6 трансляций. Вычислим сколько трансляций в день проводит каждая из категорий.
Партнеры:
Компаньоны:
Остальные:
Объем диска для партнеров:
Объем диска для компаньонов:
Объем диска для остальных:
Категория | Размер хранилища, ПБ |
---|---|
Партнеры | 1.45 |
Компаньоны | 11.27 |
Остальные | 39 |
Суммарный объем хранилища: 51.72 ПБ
Чтобы улучшать производительность потока для зрителей нужно буфферизировать некторый отрезок трансляции. Будем буфферизировать последние 30 секунд трансляции. Самое большое число одновременных трансляций составляет 233 935. Рассчитаем размер промежуточного хранилища, считая что трансляции ведутся в 1080p 30fps с битрейтом 4500kbps.
Получаем размер промежуточного хранилища: 4 ТБайт
-
Проведение трансляции
-
Дневная нагрузка: Как уже указывалось выше, средняя суммарная длительность всех трансляций за один день — 2 225 167 часов. Для видео в качестве 720p и частотой обновления обновления 60 fps, платформа Twitch рекомендует выставлять битрейт 4500 kbps. Поэтому входящая нагрузка составляет:
$4500 \times2\ 225\ 168 \times 60 \times 60 \approx 3.6 \times 10^{13} \ \text{кбит в сутки} \approx 4 \ 250 \ 000 \ \text{ГБайт в сутки}$ -
Пиковая нагрузка: Из данных следует, что самое большое количество одновременно активных трансляций в течении дня составляет примерно 130 000, тогда пиковая нагрузка составляет:
$130\ 000 \times 4500 \approx 557 ~ \text{Гбит в секунду}$ -
Средняя нагрузка:
$93\ 000 \times 4500 \approx 399 \ \text{Гбит/сек}$
-
-
Отправка сообщений в чат
-
Дневная нагрузка: Суточное количество сообщений в чат составляет
$\approx$ 52 млн сообщений. Допустим, символы кодируются в UTF-8, тогда на каждый символ приходится от 1 до 4 байт, возьмем средний размер — 2 байта. Пусть средняя длина сообщения составляет 20 символов, тогда нагрузка рассчитывается следующим образом:$52 \times 10^{6}\times 16 \times 20 \approx 12\ \text{Гбит в день}$ -
Средняя нагрузка:
$600 \times 16 \times 20 \approx 0.002 \ \text{Гбит/сек}$ -
Пиковая нагрузка: Для рассчета пиковой нагрузки, умножим среднюю нагрузку на отношение пикового количества зрителей к среднему.
$600 \times \frac{4\ 000\ 000}{2\ 337\ 099} \times 16 \times 20 \approx 0.0034 \ \text{Гбит/сек}$
-
-
Просмотр трансляций:
- Средняя нагрузка:
По данным на август 2023 года среднее количество зрителей, которые одновременно смотрят трансляции, составляет 2 401 236. На основе этого цифры можно вычислить среднюю сетевую наргрузку:
$4500 \ \times \ 2\ 401\ 236 \approx 10 \ \text{Тбит/сек}$ - Пиковая нагрузка:
Исходя из данных того же источника, абсолютный максимум зрителей составляет 6 647 412. Если же говорить про дневную пиковую нагрузку, то это нагрузка, которая приходится на 22:00 — 23:00 и варьируется между 3,5 млн и 4 млн. Возьмем для расчетов пиковой нагрузки верхную границу.
$4500 \times 4\ 000 \ 000 \ = 24 \times 10^{9} \approx 17 \ \text{Тбит/сек}$ - Дневная нагрузка:
Суммарное время просмотра за день составляет 56 186 956 часов. Тогда дневная нагрузка составляет:
$56 186 956 \times 60 \times 60 \times 4500 \approx 105965 \ \text{ТБайт/сутки}$
- Средняя нагрузка:
По данным на август 2023 года среднее количество зрителей, которые одновременно смотрят трансляции, составляет 2 401 236. На основе этого цифры можно вычислить среднюю сетевую наргрузку:
-
Чтение чата Рассчитаем среднее число зрителей на трансляцию
$\frac{2\ 401\ 236}{93000} \approx 26\ \text{чел. на трансляцию}$ Тогда если один человек отправляет сообщение в чат, его нужно доставить остальным зрителям, поэтому трафик для чтения чата рассчитывается следующим образом:
- Средняя нагрузка —
$26 \times 0.002 = 0.05\ \text{Гбит/сек}$ - Дневная нагрузка —
$12 \times 26 = 312\ \text{ГБайт/Сутки}$ - Пиковая нагрузка —
$\frac{4\ 000\ 000}{130\ 000} \times 0.0034 \approx 0.1 \ \text{Гбит/с}$
- Средняя нагрузка —
Cводная таблица сетевой нагрузки:
Тип запроса | Средняя нагрузка | Пиковая нагрузка | Дневная нагрузка |
---|---|---|---|
Просмотр трансляции | 10 Тбит/сек(2.4 млн зрителей) | 17 ТБит/сек (4 млн зрителей) | 105965 ТБайт/сутки |
Чтение чата | 0.05 Гбит/с | 0.1 Гбит/с | 312 ГБайт/сутки |
Проведение трансляции | 399 Гбит/с(93000 трансляций) | 557 Гбит/с (130000 трансляций) | 4 250 ТБайт/сутки |
Отправка сообщений в чат | 0.002 Гбит/с | 0.0034 Гбит/с | 312 ГБайт/сутки |
Просмотр трансляции(допустим, что 5% пользователей от общего количества не смотрят ни одной транлсяции):
Проведение трансляции, учитывая, что количество активных стримеров за день составляет примерно 1 300 000
Количество запросов на поиск достаточно сложно подсчитать, т.к. в открытых источниках не достаточно информации. Допустим, что 30% всех пользователей пользуются поиском и делают в среднем 3 поисковых запроса в день(остальные приходят только на трансляции по уведомлениям).
Количество запросов на загрузку чанка рассчитаем как отношение исходящей нагрузки на просмотр трансляций к размер чанка длиной 2 секунды.
Возьмем за пиковый RPS средний * 1.7 (отношения пика зрителей к среднему количеству)
Тип запроса | Средний RPS | Пиковый RPS |
---|---|---|
Открытие трансляции | 1023 | 1740 |
Загрузка чанка трансляции(2 сек) | ||
Отправка сообщения | 600 | 1020 |
Поиск | 323 | 550 |
Cтарт трансляции | 15 | 26 |
Определения ДЦ для обработки запроса будет осуществляться с помощью GeoDNS. DNS-сервер Bind предоставляет возможность использовать базу данных GeoIP2 для определения географического положения клиента. Таким образом, DNS сервер используя GeoIP, будет предоставлять различные IP-адреса в ответ на запросы от клиентов в зависимости от их физического местоположения.
Исходя из географии аудитории представленной в пункте 1, можно сделать вывод, что большая часть аудитории приходится на Северную Америку(39%), поэтому там необходимо разместить достаточное количество ДЦ. Датацентры будут распологаться в США, прежде всего в крупных городах.
- Нью-Йорк
- Сан-Франциско
- Сиэтл
- Даллас
Так же необходимо расположить ДЦ в Канаде. Это будет город Торонто.
На Европу приходится 32% процента пользователей, причем пользователи равномерно распределены по всей территории. Поэтому расположение будет следующим:
- Лондон (северная Европа)
- Франкфурт (средняя и восточная Европе)
- Цюрих (центральная Европе)
- Париж (западная Европы)
- Стокгольм (северная Европа и Россия)
- Мадрид (южная Европа)
В Китае платформа не пользуется популярностью, в виду политики страны. Поэтому большая часть азиатской аудитории приходится на Японию и Южную Корею. Расположим ДЦ в следующих городах:
- Токио
- Сеул
Все размещенные датацентры покрывают основную часть трафика, остались не затронутыми:
- Австралия
- Южная Америка
На Бразилию и Аргентину приходится 10% пользователей. Располагаем ДЦ в следующих местах:
- Сан-Паулу
- Буэнос-Айрос
В Австралии располагается всего 1.6% пользователей, а так же с учетом плотности населения можно расположить один ДЦ в одном из крупных городов, например в городе Сидней.
Составлено на основе https://wondernetwork.com/pings
Регион | Максимальная задержка(мс) |
---|---|
Сверная Америка(США, Канада, Мексика) | 50 |
Южная Америка (Аргентина, Бразилия) | 40 |
Центральная Европа | 47 |
Западная Европа | 15 |
Россия (Европейская часть) | 50 |
Россия (Центральная часть) | 80 |
Россия (Дальний восток) | 60 |
Азия(Япония, Южная Корея) | 20 |
Австралия | 45 |
Расположение | Нагрузка, RPS | Сетевая нагрузка(просмотр трансляции), Tб/с | Сетевая нагрузка(проведение трансляции), Гб/с |
---|---|---|---|
Нью-Йорк | 130477 | 1.3 | 52 |
Сан-Франциско | 85291 | 0.71 | 28.4 |
Сиэтл | 56207 | 0.47 | 18.8 |
Даллас | 152248 | 1.5 | 60 |
Торонто | 42258 | 0.35 | 14 |
Лондон | 57565 | 0.48 | 19.8 |
Франкфурт | 125703 | 1.46 | 58 |
Цюрих | 101036 | 0.84 | 33.6 |
Париж | 48166 | 0.4 | 16 |
Стокгольм | 56390 | 0.47 | 20 |
Мадрид | 56390 | 0.47 | 20 |
Токио | 17631 | 0.16 | 6.4 |
Сеул | 28779 | 0.26 | 10.4 |
Сан-Паулу | 726133 | 0.66 | 26.4 |
Буэнос-Айрос | 42977 | 0.39 | 15.6 |
Сидней | 17632 | 0.16 | 6.4 |
Т.к исходящаяя нагрзука в 25 раз больше входящей, необходимо определить какие из ДЦ будут Origin, а какие PoP.
- Функция Origin - обработка видеопотока от PoP и конечных пользователей.
- Функция PoP - прием видеопотока от пользователей и перенаправление его в Origin.
Для балансировки нагрузки внутри ДЦ будем использовать L7 балансировщик, например Envoy. Запросы на ведение трансляции будут распределяться с помощью consistant hash от id трансляции, так можно добиться того, чтобы все чанки уходили на один сервер. При смене источника трансляции(например с компьютера на телефон) id трансляции останется тем же, и видеопоток будет приходить на тот же сервер. Остальные запросы будут балансироваться с помощью алгоритма Weighted Round Robin.
Для оркестрации будет использоваться Kubernetes. Kubernetes предоставляет набор проб, позволяющих контролировать состояние подов, и в случае неудачных проб Kubernetes будет пытаться переподнять поды. Таким образом будет осуществляться контроль того, какие поды будут использованы в качестве бекенда для сервиса. Пока под не в статусе ready, он будет исключен из балансировщиков нагрузки сервиса.
-
liveness - позволяет отследить доступность работающего приложения, посредством отправления HTTP запроса. Запрос отправляется каждые 5 секунд. Пример конфига для включения liveness пробы.
-
readiness - позволяет отследить готовность контейнреа принимать трафик. Под считается готовым, когда готовы все его контейнеры. Пример конфига для включения readiness пробы
Также будет использоваться Service mesh архитектура. В качестве реализации - Istio. При использовании service mesh архитектуры, рядом с каждым сервисом ставится прокси сервер, который называется sidecar-proxy. В случае Istio в качестве sidecar-proxy используется Envoy.
Механизмы Istio для обеспечения надежности (примеры конфигов лежат в папке ./samples
):
-
Circuit Breaking:. С помощью прерываний можно предотвратить запросы к сервису, который испытывает проблемы.
-
Timeouts: позволяет предотвратить блокировку ресурсов на стороне отправителя и получателя. Если ответ от сервиса не поступает в течение определенного времени, Istio может прекращать ожидание и обрабатывать ситуацию
-
Retries: Istio может автоматически повторять неудачные запросы, что может улучшить надежность системы в случае временных сбоев.
-
Rate Limiting: Istio поддерживает упр��вление частотой запросов, что позволяет предотвращать перегрузки сервисов за счет ограничения количества запросов, поступающих на них.
Users
16 + 64 + 128 + 256 + 256 + 64 = 0.8 КБ
Streams
16 + 16 + 16 + 128 + 128 + 8 + 8 = 0.31 КБ
Sessions
16 + 16 + 8 + 8 = 0.05 КБ
Messages
16 + 16 + 16 + 8 + 512 = 0.55 КБ
Follows
16 + 16 + 16 = 0.05 КБ
Categories
16 + 256 = 0.27 КБ
Название таблицы | размер данных, ГБ | нагрузка на чтение | нагрузка на запись |
---|---|---|---|
users | 101 | 358 | 14571 (дневная нагрузка) |
streams | 2.6 | 4933 | 26 |
follows | 66 | 358 | 1157 |
sessions | 6.7 | 1076 | - |
messages | 192 | - | 1020 |
Нагрузка на чтение сообщений незначительная, т.к сообщения пересылаются сразу всем активным зрителям трансляции, чат доступен только с того момента, как зритель присоединился к трансляции.
Наг��узка запись в follows рассчитана на основе данных о приросте подписчиков за последние 30 дней.
Users
Ключи индекса | Тип индекса | Размер, ГБ |
---|---|---|
user_id | BTree | 0.3 |
nickname | BTree | 9.4 |
Follows
Ключи индекса | Тип индекса | Размер, ГБ |
---|---|---|
follow_id | BTree | 31 |
followed_user_id | Hash | 15 |
Categories
Ключи индекса | Тип индекса | Размер, ГБ |
---|---|---|
category_id | BTree | 0.0002 |
Messages
Ключи индекса | Тип индекса | Размер, ГБ |
---|---|---|
message_id | BTree | 8 |
stream_id | BTree | 8 |
Streams
Ключи индекса | Тип индекса | Размер, ГБ |
---|---|---|
stream_id | BTree | 0.2 |
title | BTree | 1.1 |
category_id | Hash | 0.2 |
Технология | Применение | Обоснование |
---|---|---|
Go | Основной язык бекенда | Простота написания, параллелизм из коробки, удобные инструменты для отладки и тестирования |
Typescript | Основной язык фронтенда | Типизация, отлов ошибок на этапе компилаяции |
React | Фронтенд фреймворк | Скорость написание, активное сообщество, компонентный подход |
Nginx | L7 балансировщик | Активное сообщество |
Envoy | Sidecar proxy | нативный прокси в Istio |
RTMP | Протокол стриминга | Поддержка со стороны популярных программ для потокового вещания. |
HLS | Протокол стриминга | Поддержка адаптивного битрейта. |
Ceph | Хранение видеочанков | Масштабируемость, высокая отказоустойчивость |
Clickhouse | Хранение логов | Горизонтальная масштабируемость, отказоустойчивость |
Apache Kafka | Брокер сообщений | Надежность, высокая пропускная способность |
Tarantool | Хранение сессий, чата активных трансляций | Высокая производительность, совместимость с golang |
PostgreSQL | Долговременное хранение данных | Масштабируемость, высокая надежность. |
При большой нагрузке на просмотр постепенно понижаем максимально качество исходящих видеопотоков. Вычислительные ресурсы на обработку входящего видеопотока в первую очередь отдаются партнерам и компаньонам, а потом обычным стримерам (Twitch так и поступает, иногда при просмотре трансляции не крупного стримера, можно заметить, что качество трансляции ограниченно 720p)
БД | Способ обеспечения надежности |
---|---|
PostgreSQL | асинхронная Master-Slave репликация с использованием Patroni и etcd для автоматической смены Master узла в случае его отказа |
Kafka | Репликация с фактором репликации 3. |
Tarantool | Master-Master репликация c полной ячеистой топологией |
Ceph | Репликация данных с фактором репликации 3. Минимальное число OSD для подтверждения успешного сохранения - 2(главный OSD и одна реплика) |
Сервис | Расположение | Замечания |
---|---|---|
Ceph-MON | Все датацентры | В каждом ДЦ располагается по серверу с Ceph-MON. В одном из ДЦ ставим два инстанса(например в Нью-Йорке), т.к всего ДЦ - 16. Нечетное количество нужно для избежания split-brain |
Ceph-OSD | Все датацентры | Располагается в каждом ДЦ, примерно в равном количестве серверов |
PostgreSQL | Все датацентры | Master распологается в ДЦ Нью-Йорк, в остальных ДЦ асинхронные реплики. |
Tarantool | Все датацентры | Располагается в каждом ДЦ для улучшения надежности хранения сообщений |
Transocding | Во всех Origin ДЦ | - |
Delivery | Во всех Origin ДЦ | - |
Auth | Несколько экземпляров в каждом регионе | В каждом регионе по два экземпляра в разных ДЦ |
Streams and Users | Несколько экземпляров в каждом регионе | В каждом регионе по два экземпляра в разных ДЦ |
Chat | Несколько экземпляров в каждом регионе | В каждом регионе по два экземпляра в разных ДЦ |
Edge | Все датацентры | - |
Ingest | Все датацентры | - |
Для рассчета ресурсов под сервис транскодирования возьмем данные из [10] Для рассчета ресурсов под сервис чата возьмем данные из [11]
Сервис | Целевая пиковая нагрузка приложения | CPU | RAM | Net | GPU |
---|---|---|---|---|---|
Edge(раздача видеопотока) | 1.8 * 10^6 RPS | 730 | 36 ГБ | 17 Тб/с | - |
Ingest(прием видеопотока) | 130000 Connections | 100 | 20 ГБ | 557 Гб/с | - |
API Gateway | 3392 RPS | 330 | 30 ГБ | 20 ГБ/с | - |
Transcoding | 130000 Parallel streams | 22690 | - | 557 ГБ/с | 2960 |
Streams and Users | 2316 RPS | 200 | 23 ГБ | 10 Гб/с | - |
Auth | 1076 RPS | 108 | 10 ГБ | 2 Гб/c | - |
Delivery | 130000 Parallel Streams | 5200 | 558 ГБ | 4 Тб/с | - |
Chat | 4 * 10^6 Connections | 1340 | 1178 ГБ | 3 Гб/с | - |
Сервис | Хостинг | Конфигурация | GPU | Cores | Cnt | Цена |
---|---|---|---|---|---|---|
Edge(раздача видеопотока) | own | 1x6448Y/2x32GB/2xNVMe8T/1x50Gb/s | - | 32 | 435 | €9,493 |
Ingest(прием видеопотока) | own | 1x6448Y/2x16GB/1xNVMe256GB/1x25Gb/s | - | 32 | 30 | €7,715 |
Auth | own | 1x6448Y/2x16GB/1xNVMe256GB/1x10GB/s | - | 32 | 10 | €7,688 |
Streams and Users | own | 1x6448Y/2x16GB/1xNVMe256GB/1x10GB/s | - | 32 | 8 | €7,688 |
Transcoding | own | 2x6421N/16x32GB/1xNVMe256GB/1x10Gb/s | 8 x NVIDIA Tesla L4 | 64 | 370 | €38,566 |
Delivery | own | 2x6448Y/2x32GB/1xNVMe256GB/1x50Gb/s | - | 64 | 102 | €13,263 |
Chat | own | 1x6448Y/2x16GB/1xNVMe256GB/1x10Gb/s | - | 32 | 42 | €7,688 |
API Gateway | own | 1x6448Y/2x16GB/1xNVMe256GB/1x25Gb/s | - | 32 | 12 | €7,715 |
Балансировщики | own | 1x6448Y/2x16GB/1xNVMe256GB/1x25Gb/s | - | 32 | 16 | €7,715 |
Tarantool | own | 1x6418H/8x64GB/1xNVMe512GB/1x25Gb/s | - | 24 | 16 | €7,708 |
PostgreSQL | own | 1x6418H/4x32GB/2xHDD2TB/1x10GB/s | - | 24 | 32 | €6,143 |
Kafka | own | 2x5318N/8x32GB/2xSSD1.9TB/1x10GB/s | - | 64 | 21 | €9,015 |
Ceph-MON | own | 1x6430/8x32GB/1xNVMe512GB/1x25Gb/s | - | 32 | 17 | €6,161 |
Ceph-OSD | own | 1x6338/8x32GB/1xNVMe960GB/36xHDD20TB/1x25Gb/s | - | 32 | 225 | €23,192 |
- https://twitchtracker.com/statistics
- https://www.demandsage.com/twitch-users/
- https://worldpopulationreview.com/country-rankings/twitch-users-by-country
- https://www.enterpriseappstoday.com/stats/twitch-statistics.html
- https://stats.streamelements.com/
- https://help.twitch.tv/s/article/broadcasting-guidelines?language=en_US
- https://twitchstats.net/
- https://streamscharts.com/
- https://blog.twitch.tv/en/2022/04/26/ingesting-live-video-streams-at-global-scale/
- https://www.wowza.com/docs/wowza-transcoder-performance-benchmark
- https://www.nginx.com/blog/nginx-websockets-performance/
- https://docs.ceph.com/en/reef/start/hardware-recommendations/