Skip to content

broadcast80/apple_highload

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 

Repository files navigation

Рассчетно-пояснительная записка

1. Тема и целевая аудитория

В качестве сервиса для проектирования была выбрана стриминговая площадка Apple Music, предоставляющая доступ к композициям из iTunes. 1, 2.

Регион Аудитория (млн)
Северная Америка 33
Индия 10
Великобритания 5
Канада 4

MVP функционал

  • Аутентификация и регистрация
  • Поиск музыки
  • Стриминг музыки
  • Личная библиотека и плейлисты
  • Рекомендации

Ключевые продуктовые решения

  • Интеграция с iCloud Music Library
  • ALAC/AAC
  • Интеграция текстов треков с Genius

2. Рассчет нагрузки

Продуктовые метрики

Метрика Значение метрики
Месячная аудитория 93 млн
Дневная аудитория 46.2 млн3

Средний размер харанилища на одного пользователя

Хранимые данные Размер на одного пользователя
Аватар 2 МБ
Мета информация 1 МБ

Среднее количество действий пользователя в день

Действие пользователя Количество / день
Регистрация 16.71 тыс
Авторизация 1.54 млн
Прослушивание музыки 140 минут
Создание плейлистов 185.7 тыс
Добавление в плейлист 4485,37 тыс
Открытие страницы исполнителя 15.4 млн
  • По статистике 1 в 2021 году Apple music насчитывал 78.6 млн пользователей, а в 2022 году уже 84.7 млн. Вычитаем эти числа и получаем 84.7 - 78.6 = 6.1 мл прироста пользователей за год. Делим это число на количество дней и получаем среднее количество регистраций в день

    6.1/365 = 0.01671 млн = 16 тыс в день
    

    Среднее количество авторизаций в день можно примерно вычислить зная DAU, которое равно 46.2 млн пользователей в день. Учитывая, что auth token живет месяц, делим это число на 30 и получаем примерное кол-во авториъзаций в день.

    46.2/30 = 1.54 млн в день
    
  • Так как не удалось найти информацию о том, сколько треков в день слушает пользователь Apple Music были использованы данные Spotify 4. На данной платформе пользователи в среднем в день слушают 40 треков, средняя длительность трека составляет 3.5 минут.

    40 * 3.5 = 140 минут в день
    
  • Аналогично, используя статистику Spotify, можно узнать сколько в среднем плейлистов пользователи создают за день. Это количество равняется 1.3 млн в день 5. Учитывая что аудитория Spotify превосходит аудиторию Apple Music в 7 раз, то для того чтобы узнать сколько в среднем плейлистов за день создают пользователи Apple Music можно разделить 1.3 млн на 7.

    1.3 / 7 = 0.1857 млн = 185.7 тыс в день
    

Технические метрики

Хранилище

  • Для расчета обьема хранилища, выделяемого под пользователей, умножим средний размер хранилища на одного пользователя на кол-во пользователей
    3 * 93 = 279 ТБ
    
    В Apple Music треки хранятся в стандартном качестве AAC с битрейтом до 256 кбит/с, средний вес такого трека составляет 7 МБ. Также есть возможность слушать музыку в Lossless качестве 16-бит/44.1 кГц (CD качество) и средний вес такого трека составляет 40 МБ. Соответственно примем, что треки хранятся в двух видах качества и занимают в среднем 47 МБ. Исходя из того что библиотека Apple Music насчитывает около 100 млн треков 6, можно рассчитать суммарный обьем хранилища, выделяемого под музыку.
    47 * 100 = 4700 ТБ
    
Хранилище Размер
Пользователи 279 ТБ
Музыка 4700 ТБ

Сетевой трафик и RPS

Действие пользователя RPD RPS Пиковое потребление Суммарный суточный,Гбайт/сутки
Регистрация 16.71 тыс 0.1932 7.293 Мбит/c 48.90
Авторизация 1.54 млн 18.18 0.457 Гбит/с 4596.63
Создание плейлистов 185.7 тыс 2.1490 9.81 Мбит/c 65.86
Добавление в плейлист 4485,37 тыс 51.915 196.2 Мбит/c 44.25
Открытие страницы исполнителя 15.4 млн 171.1111 0,42045 Гбит/с 4229

3. Глобальная балансировка нагрузки

Расположение ЦОДов

image

  • Мейден, Северная Каролина, США. Один из крупнейших ЦОДов площадью в 500 000 кв. футов. Частично работает на солнечной энергии.
  • Уоки, Айова, США. Строительство этого ЦОДа началось в 2022 году и на данный момент его площадь составляет 398 473 квадратных фута. В общей сложности Apple планирует построить в этом месте 6 центров обработки данных площадью около 2 миллионов квадратных футов.
  • Меса, Аризона, США. Этот дата-центр площадью 1,3 миллиона квадратных футов служит ключевым логистическим и операционным центром, поддерживающим все центры обработки данных Apple по всему миру. Этот ЦОД был оборудован на основе фабрики одного из бывших поставщиков Apple, обьявившим о банкротстве. Открылся в 2017 году.
  • Прайнвиль, Орегон, США. ЦОД площадью 3 млн квадратных футов, чье строительство началось в 2014 году, а в 2021 началось значительное расширение.
  • Рино, Невада, США. ЦОД площадью 1 млн квадратных футов.
  • Выборг, Дания. Apple открыла свой дата-центр в Выборге, Дания, в 2020 году, построив помещение площадью 484 376 квадратных футов. В течение 2022 и 2023 Apple активно расширяла этот ЦОД, в частности подключила свой дата-центр в Выборге к системе централизованного теплоснабжения, чтобы использовать избыточную тепловую энергию. В конечном счете Apple планирует расширить этот ЦОД до 1.8 млн квадратных футов.
  • Ньюарк, Нью-Джерси, США. Приобретен Apple в 2006 году, с площадью 107 тыс. кв. футов.
  • Тоберро, Ирландия. Имеет площадь 324 тыс. кв. футов. Выкуплен Apple в 2014 году, планируется расширение до 1.8 млн. кв. футов.
  • Гуйян и Уланкаб, Китай. Согласно китайскому законодательству, Apple обязана размещать данные своих китайских пользователей в местных центрах обработки данных. Таким образом, у Apple есть два действующих центра обработки данных в Китае, которые работают в партнерстве с Guizhou-Cloud Big Data Industry Development Co., Ltd. (GCBD), поставщик услуг в материковом Китае, контролируемый государством. Географически Apple располагает одним дата-центром в городе Гуйян, столице провинции Гуйчжоу, и еще одним в городе Уланкаб, входящем в состав региона Внутренняя Монголия.

Схема DNS балансировки

Наиболее оптимальным решением для DNS балансировки будет Geo-based DNS. Все дело в том что DNS достаточно хорошо работает на уровне стран - континентов, т.к. айпи адреса хорошо локализованы по континентам и странам. Сервер выдаст адрес ближайшего к пользователю ДЦ.

Однако при балансировки внутри страны могут быть проблемы, т.к. внутри страны айпи адреса географически сложно отличить. Поэтому между ДЦ механизм регулировки трафика будет другой.

Механизм регулировки трафика между ДЦ

Даже когда мы уже получили айпи адрес из DNS, мы еще можем влиять куда он приземлится физически. Для этого используется технология BGP Anycast.

4. Локальная балансировка нагрузки

gigaROOSTER drawio

На уровне ДЦ устанавливаем маршрутизатор, распределяющий трафик с помощью BGP на L3 балансировщик.

L3 балансировка

Используем Linux Virtual Server via Direct Routing. При таким варианте реализации маршрутизатор отправляет запросы на виртуальные ip адреса, при этом на сетевом уровне айпи пакет остается неизменным, а в ethernet фрейме меняется мак адрес назначения на основе загрузки сервера, отправляя их на определенные L7 балансировщики. Ответы отправляются напрямую клиентам, минуя L3 балансировщик. Стоит учесть что такой вариант предполагает нахождение внутри одной физической сети.

Для управления балансировщиком и отслеживания состояния L7 балансировщика используем keepalived, который следит за состоянием кластера и посылает специальные запросы на хосты, проводит внутренний health check.

L7 балансировка

Используем HTTP Reverse Proxy в качестве которого выступает Nginx. Он будет распределять запросы от клиентов по нескольким кластерам и решать проблему медленных юзеров (когда воркер сразу отдает ответ Nginx а не ждет пока клиент его получит).

Kubernetes

Используем Kubernetes для оркестрации контейнеров, он занимается автоматическим запуском подов, балансирует нагрузку между ними а также выполняет масштабирование с помощью auto-scaling.

5. Логическая схема БД

image

Таблица Описание Требование к консистентности Размер
User Хранит информацию о пользователях сервиса. Каждый пользователь имеет уникальный идентификатор id, email и username. id - PK, email - UNIQUE, username - UNIQUE 4 + 20 + 30 + 8 + 50 + 20 = 132 байта
Session Хранит информацию о текущих активных сеансах пользователей. Каждая сессия имеет уникальный идентификатор session_id а также хранит идентификатор пользователя user_id и время окончания действия сеанса expiration session_id - PK 8 + 8 + 8 = 24 байта
Playlist Хранит информацию о плейлистах пользователей. Каждый плейлист имеет уникальный id. Также хранится информация о его названии, его описание, картинка и внешний ключ на пользователя которому принадлежит плейлист. playlist_id - PK 8 + 8 + 20 + 50 + 30 = 116 байт
Song Хранит информацию о треках. Каждый трек имеет уникальный id. Также хранится информация о его названии, ссылка на файл в s3, количество прослушиваний и длительность трека. Также имеется внешний ключ на альбом. id - PK 8 + 20 + 50 + 4 + 2 + 8 = 92 байтa
Playlist_Song Хранит информацию о треках в плейлистах. playlist_id, song_id - PK 8 + 8 = 16 байт
LikedSongs Хранит информацию о треках, которые лайкнул пользователь. song_id, user_id - PK 8 + 8 = 16 байт
Genre Хранит информацию о жанрах. Каждый жанр имеет уникальный id и имя. id - PK, name - UNIQUE 4 + 20 = 24 байтa
Genre_Song Хранит информацию о жанрах песен. genre_id, song_id - PK 4 + 8 = 12 байт
Album Хранит информацию об альбомах. Каждый альбом имеет уникальный id, а также хранится информация о его названии, картинке, дате публикации и внешний ключ на автора. id - PK 8 + 30 + 50 + 8 + 4 = 100 байт
Artist Хранит информацию об исполнителях. Каждый исполнитель имеет уникальный id. Также хранится информация о его имени, количестве прослушиваний в месяц, описание, дата рождения и жанр. id - PK 4 + 20 + 2 + 256 + 2 + 4 = 288 байт

6. Физическая схема БД

Разбиение по СУБД

Таблица СУБД Индексы
Session Redis session_id - поиск сессии по идентификатору
User MongoDB id - при поиске пользователя через плейлист,username - при поиске пользователем других пользователей, email - при входе
Song MongoDB + S3 id , name - при поиске пользователем трека по названию, album_id - индекс по альбому
Playlist MongoDB name - при поиске пользователем по названию, user_id - при просмотре плейлистов другого пользователя
Playlist_Song MongoDB playlist_id - поиск трека в конкретном плейлисте
LikedSongs MongoDB user_id - при просмотре добавленных треков
Genre MongoDB name - при поиске жанра по названию
Genre_Song MongoDB genre_id - при поиске песен по жанру
Album MongoDB id, name - при поиске альбома по названию, artist_id - при просмотре альбомов исполнителя
Artist MongoDB id - при поиске исполнителя альбома, name - при поиске исполнителя по имени

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

  • User - горизонтальное шардирование по id
  • Playlist - горизонтальное шардирование по user_id
  • Album - горизонтальное шардирование по id
  • Song - горизонтальное шардирование по album_id
  • Artist - горизонтальное шардирование по id

Резервное копирование

  • MongoDB - Managed Service будет обеспечивать автоматическое резервное копирование
  • Redis - Managed Service for Redis обеспечивает автоматическое и ручное резервное копирование баз данных.

Аналитика

Для аналитики данных наиболее удачным выбором будет Clickhouse из за своей большой скорости и возможности очень быстро читать запросы на больших обьемах данных.

Обработкой и передачей данных в clickhouse будет заниматься Kafka.

7. Алгоритмы

Коллаборативная фильтрация

Классическая реализация этого алгоритма основана на на принципе n ближайших соседей. Ищем для каждого пользователя n наиболее похожих на него пользователей и дополняем информацию о пользователе данными о его соседях. image В матрице выше желтым цветом обозначен пользователь, для которого необходимо найти оценки по новому контенту (знаки вопроса). Синим цветом выделены три ближайших к нему соседа. У классической реализации данного алгоритма есть явный минус - он плохо применим на практике из за квадратичной сложности. Отчасти эта проблема решается мощностью железа но также можно внести некоторые корректировки в алгоритм:

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

Implicit ALS

Явный фидбек от пользователей в сервисе прослушивания музыки недоступен, поэтому приходится ориентироваться на неявный (кол-во прослушиваний, лайков). Допустим человек не слушал песню. Значит ли это что она ему не нравится? Или просто среди миллионов треков ему еще не попался эта конкретная песня? А если человек прослушал только часть песни, значит ли это что она ему не понравилась? Может самую запоминающуюся часть он все таки прослушал? Таким образом, рассуждения переходят из дихотомии понравилось/не понравилось в пространство степени уверенности: «мы не уверены, что полсекунды прослушивания означают, что ему понравилось, но гораздо сильнее уверены, что три минуты прослушивания означают, что ему понравилось» Стандартный ALS метод преобразуется таким образом в новую функцию для оптимизации, с которой можно работать в рамках описанного выше алгоритма. image image image

8. Технологии

Технология Где применяется Мотивация
Golang Бэкенд, бизнес логика приложения Наилучший вариант для высоконагруженных распределенных систем благодаря своей эффективной параллельной обработке
MongoDB Хранение данных, OLTP Быстро развивающаяся, надежная и хорошо задокументированная БД
Redis Хранение данных сессии высокопроизводительная in-memory база данных
k8s Оркестрация контейнеров Используем kubernetes для балансировки и автомасштабирования бекенда
S3 Обьектное хранилище, хранение файлов музыки Надежность, масштабируемость
Clickhouse Хранение данных для аналитики, OLAP Огромная скорость, хранит данные очень компактно в виде одной большой таблицы
Kafka стриминговая БД, сбор большого потока событий-данных Предоставляет единообразную платформу с высокой пропускной способностью и низкой задержкой для обработки данных в режиме реального времени.

9. Схема проекта

aoplokjsdf

Пояснение к сервисам

  • Auth: Сервис авторизации пользователей. Рабтает в связке с Redis

  • User: Сервис регистрации пользователей и взаимодействия их со своим профилем. Работает в связке с MongoDB и хранит пользовательский кеш в Redis.

  • Playlist: Сервис, отвечающий за работу с плейлистами. Работает в связке с MongoDB.

  • Artist: Сервис, отвечающий за профили исполнителей. Работает в связке с MongoDB.

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

  • File Service: Сервис, работающий с файлами. Занимается их процессингом, удалением и очисткой от мусора. Работает в связке с MongoDB и S3.

  • Streaming Service: Сервис, отвечающий за стриминг музыки пользователю. Работате в связке с S3.

  • Analytics: Сервис, собирающий данные для аналитики через Кафку. Работает в связке с Clickhouse.

  • Logs: Собирает логи. Работает в связке с MongoDB.

10. Обеспечение надежности

MongoDB

  • Репликация в MongoDB осуществляется через наборы реплик (replica sets). Набор реплик состоит из нескольких экземпляров MongoDB, которые хранят одинаковые наборы данных. Один из узлов выступает в роли мастера, принимающего записи, в то время как остальные узлы являются слейвами, которые получают обновления от мастера. В случае сбоя мастера, один из слейвов может быть автоматически переведен в режим мастера.

  • MongoDB поддерживает автоматическое переключение (failover) в рамках наборов реплик. Если основной узел выходит из строя, система автоматически выбирает нового мастера из доступных слейвов.

Redis

  • Redis Sentinel — это система мониторинга и управления, которая обеспечивает автоматическое переключение на резервный узел в случае сбоя мастера. Sentinel следит за состоянием узлов и может автоматически перенастроить систему, чтобы обеспечить непрерывность работы.

  • Redis поддерживает различные механизмы сохранения данных, такие как RDB (Redis Database Backup) и AOF (Append Only File). RDB создает снимки базы данных через заданные интервалы времени, а AOF не изменяет уже записанные данные, а лишь добавляет новые в конец.

Nginx

Используем механизмы keepalived и health checks.

Kubernetes

  1. Self-Healing (Самовосстановление) Kubernetes автоматически обнаруживает и устраняет проблемы с объектами в кластере: Проверка состояния (Health Checks): Liveness Probe — проверяет, работает ли приложение. Если нет, Kubernetes перезапускает контейнер. Readiness Probe — проверяет, готово ли приложение принимать трафик. Если оно не готово, Kubernetes исключает его из балансировки. Автоматический перезапуск Pod-ов: Если Pod выходит из строя, контроллеры (например, Deployment) автоматически перезапускают его.
  2. Репликация и масштабирование ReplicaSets: Кластеры поддерживают заданное число экземпляров (реплик) Pod-ов. Если какой-то Pod выходит из строя, ReplicaSet автоматически создаёт новый. Автоматическое масштабирование (Horizontal Pod Autoscaler): Kubernetes может автоматически увеличивать или уменьшать количество Pod-ов в зависимости от нагрузки (CPU, RAM и других метрик). Cluster Autoscaler: Автоматическое добавление или удаление узлов кластера в зависимости от потребностей.
  3. Балансировка нагрузки Service Discovery и Load Balancing: Kubernetes автоматически распределяет трафик между Pod-ами через абстракцию Service. ClusterIP: Для внутренней балансировки трафика. NodePort и LoadBalancer: Для внешнего доступа. Ingress: Предоставляет более сложные правила маршрутизации и балансировки.

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

Graceful shutdown:

Будет обрабатываться сигнал остановки сервиса. Приём новых запросов будет приостановлен. Только после того как выполнятся запросы, которые уже успели дойти, только после этого отключаем сервис.

  • При получении сигнала SIGTERM от Kubernetes, наше приложение должно начать процесс Graceful Shutdown. Это включает в себя завершение обработки текущих запросов, закрытие соединений с БД и другие задачи по очистке.
  • Kubernetes предоставляет период завершения, в течение которого приложение может завершить свою работу перед тем, как будет принудительно остановлено с помощью SIGKILL. Этот период можно настроить.
  • Kubernetes предоставляет хуки жизненного цикла, которые позволяют запускать определенные команды на различных этапах жизненного цикла пода. Мы можем использовать хук preStop для запуска скрипта или команды, которая начнет процесс Graceful Shutdown.
  • При начале процесса Graceful Shutdown, под должен быть удален из балансировщика нагрузки, чтобы новые запросы не были направлены на него. Kubernetes автоматически удаляет под из Endpoint'ов службы при получении сигнала SIGTERM.

Graceful degradation:

Основное назначение Apple music - всегда иметь возможность к прослушиванию музыки.

Следующие сервисы должны работать для обеспечения надёжности продукта:

  • Auth
  • User
  • Playlists
  • Artist
  • Streaming

Допускается потеря части функционала:

  • Recommendations: в случае отказа сервиса использовать старые рекомендации
  • Analytics

Логгирование и Мониторинг:

Для того чтобы быстро отслеживать запросы будем использовать паттерн RequestId. Сами логи будут храниться в MongoDB в виде JSON.

11. Список серверов

Базовый расчёт аппаратных ресурсов

Service RPS CPU RAM NET
Auth 18.3732 2 3 ГБ 0.464 ГБ/c
User 1.2 1 1 ГБ 0.16 ГБ/с
Playlist 54.063 2 4 ГБ 0.206 ГБ/с
Artist 171.1 4 6 ГБ 0.42045 ГБ/с
Recommendations 534.72 10 16 ГБ 0.14 ГБ/с
Streaming 21 388.9 250 300 ГБ 55.13 ГБ/с
Transcoding 0.57 2 2 ГБ 0.1368 МБ/с

Контейнеры и виртуализация

Service CPU/r CPU/l RAM/r RAM/l Cnt
Auth 1 1 1000 1500 3
User 1 1 600 900 3
Playlist 1 1 1100 1500 3
Artist 1 2 1500 2000 3
Recommendation 3 4 4700 5400 3
Streaming 17 20 15 000 20 000 15
Transcoding 1 1 500 700 3

Источники:

Footnotes

  1. Apple Music Statistics 2024 2

  2. Form 10-K

  3. Hypestat

  4. Insights into Spotify Listening Statistics

  5. Exploring Eye-Opening Spotify Playlist Statistics: 4 Billion Playlists Created

  6. Celebrating 100 million songs

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published