Мессенджер Telegram - кроссплатформенная система мгновенного обмена сообщениями, позволяющая обмениваться текстовыми, голосовыми и видеосообщениями, стикерами и фотографиями, файлами многих форматов.
- Авторизация, регистрация по номеру телефона
- Отправка текстовых сообщений
- Отправка голосовых сообщений
- Отправка файлов
- Реакции на сообщения
- Список чатов
- История сообщений
- Каналы
- Метрики для каналов(активность, просмотры, рост подписчиков и т.д.)
- Поиск людей по номеру телефона
- Платная подписка, дающая доступ к распознаванию голосовых сообщений, анимированным стикерам, кастомным эмодзи и эмодзи-статусам
Ниже представлена статистика исследования аудитории Telegram. В опросе приняли участие жители из более чем 70 стран. Возраст целевой аудитории варьируется в диапазоне от 18 до 64 лет [1]
Возрастная группа | Процентное соотношение |
---|---|
до 17 лет | 6,4% |
18-24 года | 18,8% |
25-34 года | 29,4% |
35-44 года | 23,8% |
45-64 года | 21,6% |
Размер целевой аудитории: 800 млн. пользователей в месяц, 55.2 млн. пользователей в день на момент конца 2023г. [2]
Общемировая география пользователей на момент 2024г [3]:
Регион | Процентное соотношение |
---|---|
Азия | 38% |
Европа | 27% |
Латинская Америка | 21% |
Страны MENA | 8% |
География русскоязычных пользователей:
Страна | Процентное соотношение |
---|---|
Россия | 60% |
Беларусь | 17% |
Украина | 13% |
Гендерное распределение аудитории Telegram:
Пол | Процентное соотношение |
---|---|
Мужской | 58% |
Женский | 42% |
Ежемесячная аудитория Telegram: 800 млн. пользователей.
Ежедневная аудитория Telegram: 55.2 млн. пользователей.
Согласно исследованию [4]:
Количество отправленных сообщений в день: 15 миллиардов
Количество регистраций в день: 8.33 млн.
Средняя длительность сессии: 6 минут.
Исходя из исследования [5]:
Количество заходов в день: 24
Посчитаем количество сообщений в день на одного пользователя : 15 млрд. / 55.2 млн. ~ 272 [сообщ/чел]
Под термином "Сообщение" также подразумевается в данном контексте пост и комментарий. Предположим, что обычные сообщения, посты и комментарии распределены следующим образом:
- 150 обычных сообщений. Из них 7 - голосовые, 10 - файлы
- 60 комментариев. Из них 0 - голосовые, 5 файлы
- 62 поста. Из них - 3 голосовые, 25 файлы.
Параметр | Число |
---|---|
Среднее количество сообщений | 272(из них 40 - файлы; 10 - голосовые) |
Средняя длина сообщения | 60 символов UTF-8[6] |
Средняя длина записи одного голосового сообщения | 30 секунд |
Средний размер голосвого сообщения при битрейте 128 kbps | 480 кБ |
Средний размер одного файла | 2 МБ |
Срок хранения сообщения | 3 года |
Среднее количество чатов у пользователя | 15 |
Среднее количество единовременно подружаемых сообщений | 6 |
Среднее количество людей, с которыми пользователь общается в день | 8 |
Среднее количество реакций на пользователя | 15 |
Отметим, что размер одной реакции равен 2 байта
Тогда общий объем сообщений, отправляемых в день, на одного пользователя равен: 222 * 0.06 (кБ) + 10 * 480 (кБ) + 40 * 2048 (кБ) + 15*0.002 (кБ) = 86733 кБ
Итого: суммарный объем данных на одного пользователя за 3 года: 86733(кБ) * 365 * 3 + 256 = 90.57 ГБ
Так как в день отправляется около 15 млрд. сообщений, то можно вычислить, какой объем данных будет занят пользователями за, например, 1 год.
Расчет для фотографий и голосовых сообщений: ((10 * 480 (кБ) + 40 * 2048 (кБ)) * 55 200 000 * 365)/(1024^4) = 1689 ПБ/год Расчет для текстовых сообщений и реакций: ((222 * 0.06 (кБ) + 15 * 0.002 (кБ)) * 55 200 000 * 365)/(1024^4) = 0.24 ПБ/год
При расчете сетевого трафика не будем учитывать запросы, связанные с регистрацией пользователей, так как они не создают ощутимую нагрузку на наш сервис. Основная нагрузка приходится на отправку сообщений, загрузку списка чатов и историю сообщений.
Посчитаем объем трафика для списка чатов на одного человека с учетом количества заходов в сутки: 24 * 15 * 101.3 кБ = 36 468 кБ Посчитаем объем трафика для истории сообщений на одного человека с учетом количества единовременно подгружаемых сообщений в диалоге(канале), среднего количества людей, с которыми общается пользователь в день(каналов, на которые пользователь подписан): 6 * 15 * 0.06 (кБ) = 5.4 кБ
Согласно графику дневной активности в телеграм[7] пиковое значение активности пользователей(соответственно RPS тоже) приблизительно в 1.66 раза выше среднего значения. Возьмем коэффициент запаса равный 2
Рассмотрим трафик по видам активностей:
Тип | Отправка (дневная аудитория 55.2 млн) | Отправка Гб/сек | Пиковое значение | Значение с коэффициентом запаса 2 |
---|---|---|---|---|
Текстовое | 222 * 55.2 млн. * 0. 06 кБ | 0.008 | 0.013 | 0.026 |
Голосовое | 10 * 55.2 млн. * 480 кБ | 2.92 | 4.85 | 9.69 |
Файл | 40 * 55.2 млн. * 2048 кБ | 50 | 83 | 166 |
Список чатов(подгрузка чатов при заходе в приложение) | 36 468 кБ * 55.2 млн. | 22.22 | 36.52 | 73.04 |
История сообщений | 4.8 кБ * 55.2 млн. | 0.004 | 0.007 | 0.13 |
Реакции | 15 * 0.002 * 55.2 млн. | Незначительно | Незначительно | Незначительно |
Итого | 75.152 | 124.752 | 249.5 |
- Отправка сообщения: 55.2 млн * 272 / 86400 = 141 833 RPS
- Регистрация: 8.33 млн / 86400 = 96 RPS
- Авторизация: 55.2 млн. / 86400 = 638.8 ~ 639 RPS
- Получение списка чатов: 55.2 млн. * 24 / 86400 = 15 333 RPS
- Получение истории сообщений: 55.2 млн. * 6 / 86400 = 3833 RPS
Действие | RPS | Пиковое значение | Пиковое значение с коэффициентом запаса 2 |
---|---|---|---|
Отправка сообщения | 173 777 | 288 469 | 576 939 |
Регистрация | 96 | 159 | 318 |
Авторизация(без подтверждения сессий) | 639 | 1061 | 2 122 |
Получение списка чатов | 15 333 | 25453 | 50 906 |
История сообщений | 3 833 | 8484 | 16 968 |
Итого | 193 678 | 321 492 | 642 984 |
Заметим, что подтверждение сессий срабатывает на каждый запрос, что говорит о том, что пик RPS на данное действие будет примерно равен 642 984, а пик трафика примерно 249.5
Общемировая география пользователей на момент 2024г:
Регион | Процентное соотношение |
---|---|
Азия | 38% |
Европа | 27% |
Латинская Америка | 21% |
Страны MENA | 8% |
Северная Америка | 3% |
Южная и Центральная Африка | 3% |
Отметим также, что 27% всех пользователей Telegram русскоязычные. То есть находятся в основном в постсоветских странах.
Соответственно, география глобальных датацентров:
Регион | Локация датацентра(-ов) |
---|---|
Азия | Токио, Сингапур |
Европа | Амстердам, Москва |
Латинская Америка | Сан-Паулу |
Страны MENA | Дубаи |
Северная Америка | Сан-Франциско |
Южная Африка | Йоханесбург |
Центральная Африка | Додома |
Примечание: В Китае запрещен Telegram и другие иностранные мессенджеры. Разрешен только WeChat
В каждом регионе предлагается распределить датацентры относительно плотности пользователей:
Регион | Процент серверов |
---|---|
Азия | 40% |
Европа | 30% |
Латинская Америка | 21% |
Страны MENA | 4% |
Северная Америка | 1% |
Южная Африка | 1% |
Центральная Африка | 1% |
- В первую очередь определяем регион с помощью Geo-Based DNS
- После чего рамках региона выбираем датацентр через BGP Anycast
L3: L3 будет использоваться в качестве первичной балансировки, чтобы распределить трафик по серверам внутри ЦОД. Балансировка будет по схеме Virtual Server via IP Tunneling
Для обеспечаения отказоустойчивости системы стоит использовать framework keepalived благодаря следующим преимуществам:
- Производительность
- Открытость
- Простота настройки
Будем использовать Virtual Router Redundancy Protocol(VRRP). Соответственно, мы получаем возможность отслеживать состояние узлов системы, а при отказе одного из них перенаправить трафик на другой узел.
L7: На отдельно взятом сервере будет проходить балансировка с помощью L7. На этом уровне для балансировщика нагрузки важна поддержка gRPC. Будем использовать балансировщик NGINX благодаря следующим преимуществам:
- Лучшая производительность
- Поддержка различных протоколов(в т.ч. gRPC и HTTP)
- Открытость
- Гибкость настройки
Также для решения проблемы отказоустойчивости на этом уровне будет использоваться k8s с использованием:
- Liveness probe
- Readiness probe
Для шифрования будем пользоваться услугами центра Let's encrypt Для оптимизации установки соединения будет пользоваться Session cache
Для хранения информации о сессиях используется база данных Redis по причине того, что она осуществляет хранение данных in-memory, имеет поддержку неблокирующей репликации master-slave и возможность организации кластера Redis cluster.
Для хранения очереди непрочитанных сообщений используется Apache Kafka. Для хранения файлов будет использоваться сервер с большим объемом памяти.
Технологии для хранения данных:
Таблица(-ы) | Технология |
---|---|
sessions | redis |
users, chats, channels, users_meta, channels_meta, users_channels, users_chats, subsribes_metric | PostgreSQL |
reactions, posts, comments, messages, attachments, subscribes_metric, post_views_per_post | MongoDB |
*_search | ElasticSearch |
Так как один сервер PostgreSQL и MongoDB не выдержит планируемую нагрузку, выполним шардинг таблицы сообщений. Для более быстрого доступа к данным будет необходимо использовать индексы.
- Для таблиц users, chats, channels инекс по полю id
- Для таблиц channels_meta, user_meta индекс по полю channel_id и user_id соответственно.
- Остальное храним в MongoDB в виде ключ-значение.
- post_reactions, comments, views_per_post получаем по полю post_id
- attachments - id
- subscribes_metric, posts по полю channel_id
- messages - chat_id
- messages_reactions - message_id
- comments_reactions - comment_id
Также необходимо выполнить шардинг
- Для шардинга сообщений необходимо сделать шардинг таблиц messages по полю chat_id
- Для шардинга постов необходимо сделать шардинг posts, subscribes_metric по полю channel_id
- Для шардинга комментариев и просмотра постов необходимо сделать шардинг comments и post_views_per_user по полю post_id
- Для шардинга реакций необходимо сделать шардинг по полю *_id
- Также имеет смысл сделать шардинг таблиц users_channels и users_chats по полю channel и chat_id соответственно
В совокупности это даст следующий результат:
На одном сервере хранятся пользователи с метаданными, прикрепелнные файлы
На шардах для чатов хранятся чаты с id в диапазоне от х до y, соответствующие им сообщения, которым соответствуют реакции, а также таблицы для связи с пользователей и чатов
На шардах для каналов хранятся каналы с id в диапазоне от х до y, соответствующие им посты, которым соответствуют комментарии, которым соответствуют реакции, а также таблицы для связи пользователей и каналов
Прирост в скорости получения данных будет сильным за счёт относительно маленьких таблиц, индексов, а также хранения в виде пар ключ-значение
Для эффективного поиска людей, поиска по постам и сообщениям будем использовать движок ElasticSearch. Это поисковый и аналитический движок, который основан на технологии поиска по тексту.
Копии таблиц users, messages, channels, posts можно положить в хранилище ElasticSearch (в логической схеме user_search, message_search, channel_search, post_search). Оно предоставляет механизм для поиска, анализа и хранения данных в реальном времени.
-
user
-
phone_number
- полное совпадение по нормализированному формату.Индекс:
phone_number
Обращение к ХД: По
phone_number
(в нормализованном формате)
-
-
message
-
content
- частичное совпадение, допускаются различные формы словИндексы(в порядке убывания важности):
timestamp
,chat_id
Обращение к ХД: По
content
, возвращаются все частичные совпадения
-
-
post
-
content
- частичное совпадение, допускаются различные формы слов -
channel_name
- частичное совпадениеИндексы(в порядке убывания важности):
timestamp
,channel_name
Обращение к ХД: по полю
content
, возвращаются все частичные совпадения, либо по полюchannel_name
, возвращаются все частичные совпадения
-
-
channel
-
name
- частичное совпадение, допускаются различные формы словИндексы(в порядке убывания важности):
subscribers_count
,name
Обращение к ХД: по полю
name
, возвращаются все частичные совпадения
-
Частичные совпадения для content
в постах и сообщениях ищутся по следующей схеме:
Создается wildcard запрос, который ищет вхождения переданной строки в текст сообщения или поста
Частичные совпадения для channel_name
и name
ищутся по следующей схеме:
Создается query_string запрос, который ищет совпадения префикса искомого имени с переданным значением
Поиск по сообщениям и постам будет отдавать приоритет наиболее новым
Поиск по номеру без приоритезации т.к. мы используем полное совпадение по номеру
Поиск канала будет отдавать приоритет каналам с наибольшим числом подписчиков. Но для случая, если искомое название канала полностью совпало с каким-либо, то этому результату дается вес 2. В случае частичного совпадения - дается вес 1. Итого: Первые в приоритете каналы с полным совпадением, отсортированные по убыванию количества подписчиков, после них - с частичным совпадением по убыванию количества подписчиков.
Модерация будет осуществляться "вручную". При подаче жалобы пользователем и рассмотрением её модератором.
TypeScript. TS позволяет отлавливать ошибки на этапе компиляции и делает работу с типами более детерминированной. При масштабировании проекта в случае использования JavaScript могут возникать ошибки, которые станет сложнее и дороже найти и исправить, чего можно избежать используя TypeScript. TypeScript поддерживает новые функции ECMAScript, что позволяет разработчикам использовать новые возможности JavaScript до того, как они станут стандартом. TS также поддерживает модульность по аналогии с JavaScript, что позволяет эффективно осуществлять поддержку, масштабирование и тестирование кода
React. Наиболее гибкий и популярный фреймворк для Frontend-разработки. С помощью него можно решить практически все необходимые задачи, а также относительно легко масштабировать проект за счёт компонентного подхода. React - наиболее популярный фреймворк, следовательно будет наиболее просто найти разработчиков, владеющих им. Также будет использоваться SCSS для более быстрой и удобной работы со стилями. Необходимо также хранить уведомления, для чего будет достаточно SQLite - персистентное хранилище на клиенте.
Для реализации Frontend на мобильных устройствах будем использовать React Native.
Необходимо также хранить уведомления, для чего будет достаточно SQLite - персистентное хранилище на клиенте.
На уровне L7 будем также использовать nginx за счёт его высокой производительности и гибкости настройки. В целом, nginx подойдёт под микросервисную архитектуру.
Для создания бизнес-логики будет использоваться Golang, за счёт многопоточности с большим количеством готовых библиотек. Telegram будет выполнен на микросервисной архитектуре
Для отслеживания проблем в микросервисной архитектуре будет использоваться Jaeger
Как на клиенте, так и на сервере для реализации Realtime-сообщений будет использоваться технология WebSocket. Данная технология позволит отправлять сообщения и уведомления без дополнительных запросов.
В качестве кеш хранилища взяли Redis. Имеет больше функциональных возможностей по сравнению с аналогами (например, memcached) - поддержку транзакций, очереди, а также поддерживает репликацию master-slave и кластеризацию с версии 3.0.
В проекте присутствуют 2 основные СУБД - MongoDB и PSQL Хранение осуществляется следующим образом
Таблицы | Технология |
---|---|
users, chats, channels, users_meta, channels_meta, users_channels, users_chats, subsribes_metric | PostgreSQL |
reactions, posts, comments, messages, attachments, subscribes_metric, post_views_per_post | MongoDB |
PostgreSQL был выбран за счёт следующих преимуществ:
- Открытость - это полностью бесплатная СУБД с открытым исходным кодом
- Масштабируемость - отлично подходит для большого объема данных, поддерживает репликацию
- Популярность - имеет большое сообщество разработчиков
- Надежность и стабильность - обладает механизмами сохранения целостности данных, транзакционной безопасности и отказоустойчивости
MongoDB был выбран за счёт следующих преимуществ:
- Скорость – специфическая структура и поддержка индексации хорошо сказываются на производительности системы, так что её имеет смысл использовать там, где скорость имеет критическое значение;
- Удобство масштабирования – можно без особых сложностей масштабировать и менять в зависимости от потребностей
- Функция работы на нескольких серверах – MongoDB использует механизмы репликации и сегментирования, позволяющие формировать функциональные копии БД, которым можно в любой момент делегировать управление, и равномерно распределять между ними нагрузку.
- Популярность - имеет большое сообщество разработчиков
Брокер сообщений представляет собой тип построения архитектуры, при котором элементы системы «общаются» друг с другом с помощью посредника. Благодаря его работе происходит снятие нагрузки с веб-сервисов, так как им не приходится заниматься пересылкой сообщений: всю сопутствующую этому процессу работу он берёт на себя.
Для этого подойдет Kafka
В качестве СУБД для сбора и анализа статистики возьмем ClickHouse. Поддерживает распределенное выполнение запросов. Использует движок MergeTree, что позволяет с высокой производительностью выполнять аналитические запросы, поддерживает индексирование, репликацию и партиционирование данных, горизонтальное масштабирование.
Для поиска используем ElasticSearch. Это - хранилище данных для поиска, анализа и хранения в реальном времени. Очень хорошо горизонтально масштабируется добавлением новых узлов в кластер.
Для сервиса-мессенджера я бы выбрал Amazon Simple Storage Service (S3) Glacier Instant Retrieval хранилище.
Amazon S3 Glacier Instant Retrieval предлагает:
- Мгновенное получение данных: Доступ к данным в течение нескольких миллисекунд, как и в случае с S3 Standard.
- Низкая стоимость: Уровень хранения Glacier Instant Retrieval дешевле, чем S3 Standard, что делает его экономичным вариантом для больших объемов неактивных данных.
- Высокая доступность: Данные хранятся в нескольких центрах обработки данных по всему миру, что обеспечивает высокую доступность и защиту от сбоев.
- Масштабируемость: S3 Glacier Instant Retrieval может масштабироваться для хранения петабайтов данных.
Для сервиса-мессенджера, который обычно содержит большие объемы сообщений, изображений и других вложений, важны мгновенное получение данных, низкая стоимость и высокая доступность. S3 Glacier Instant Retrieval соответствует всем этим требованиям, что делает его идеальным выбором для хранения данных такого сервиса.
Также для хранения сырых данных будет использоваться CEPH
Фото: Для сжатия фото будем использовать WebP. Сжатие без потерь
Видео: Будем использовать VP9. Сжатие с потерями
Аудио: Будем использовать Opus. Сжатие с потерями
Также будет использоваться адаптивное сжатие, которое регулирует уровень сжатия в зависимости от скорости соединения и типа данных. Это позволяет оптимизировать размер файла и качество передачи для различных условий сети.
Легенда:
Будет использоваться API Gateway для обеспечения изолированности логики различных клиентов и централизованной точки маршрутизации. На Gateway также будет происходить балансировка между сервисами, т.к. архитектура будет разделена на микросервисы для изоляции бизнес-логики.
- Сервис auth будет отвечать за авторизацию и аутентификацию
- Сервис user будет отвечать за бизнес-сущность пользователя: его статус, профиль, язык, данные профиля и т.д.
- Сервис messenger будет отвечать за чаты, сообщения и взаимодействия между ними. Этот сервис может отправлять данные на клиент для реализации Realtime.
- Сервис channels будет отвечать за каналы, их аналитику, управление правами и данными(аватарка, описание и т.д.) у каналов
- Сервис posts будет отвечать за посты, их аналитику, файлы и т.д. Этот сервис может отправлять данные на клиент для реализации Realtime.
- Сервис comments будет отвечать за работу с бизнес-сущностью комментария к посту. Этот сервис может отправлять данные на клиент для реализации Realtime.
- Сервис Upload Manager будет отвечать за обработку, загрузку и архивацию файлов в S3. Архивация осуществляется либо по запросу из сервиса бизнес-сущности через kafka, либо по запросу из cleaner.
- Сервис DB Manager отвечает за предобработку и запись в БД(Mongo или Postgres).
- Сервис Stats Manager отвечает за обработку и запись статистики в ClickHouse и PSQL/Mongo.
- Сервис Search Manager отвечает за обработку и запись в ElasticSearch.
- Clean Manager отвечает за периодическую архивацию файлов(То есть периодически смотрит хранилище и выбирает файлы, соответствующие критериям для архивации). Архивация происходит в случае, если пользователь удалил сообщение/комментарий(или канал удалил пост) с данным файлом или файл не читался хотя бы 30 дней. Все эти данные можно получить с помощью API Amazon S3. Осуществиялет запись в kafka при автоочистке.
- Processing отвечает за обработку файлов(EX: Из одного изображения получается уменьшенная версия, оригинал, далее - всё хешируется и сжимается). Является частью Upload Manager(как модуль)
Для чтения и записи в БД будет реализован паттерн CQRS, где мы будет разделять запись и чтение на 2 пайплайна. Запись будет производиться асинхронно через kafka, а чтение - синхронно напрямую с сервера БД. Также синхронно будут производиться пайплайны чтения и записи файлов в S3.
Будут резервироваться датацентры для того, чтобы в случае отказа одного была возможность либо перенаправить трафик, либо восстановить данные из другого
Компонент | Метод | Обоснование |
---|---|---|
nginx | резервирование ресурсов, резервирование серверов | т.к. балансировщик - это узкое место системы, то в случае высоких нагрузок понадобятся дополнительные ресурсы для обеспечения отказоустойчивости. Также отказ сервера балансировщика означает отсутствие доступа к сервису у пользователей, поэтому необходимо зарезервировать дополнительные сервера |
MongoDB | репликация | Репликация БД необходима для сохранения данных в случае отказа работы одного из серверов БД, а также для обеспечения более высокой доступности и равномерного распределения нагрузки |
PSQL | репликация | --"-- |
S3 | репликация | --"-- |
CEPH | репликация | --"-- |
Buiseness-logic(ex: User) | Резервирование компонентов, резервирование ресурсов | В случае высоких нагрузок на сервера, необходимо для обеспечения отказоустойчивости зарезервировать сервера, а также компоненты, чтобы в случае отказа чего-либо(что происходит часто) оперативно восстановить работу сервера. При высоких нагрузках серверу потребуются дополнительные ресурсы для своевременной обработки данных. |
API Gateway | Резервирование логики | Т.к. на шлюз поступает много запросов, требующих тривиальной логики, то имеет смысл реплицировать эту логику для повышения доступности системы |
Kafka | Репликация | Для Kafka очень важно использовать репликацию, чтобы обеспечить отказоустойчивость и сохранность данных в случае отказа брокера. Балансировка + репликация позволят гаранитровать, что минимум 1 брокер будет работоспособен |
ElasticSearch | Репликация(индексов) | ElasticSearch предоставляет возможности для репликации индексов, что обеспечивает отказоустойчивость и возможность восстановления данных при сбоях. |
ClickHouse | Репликация | Для обеспечения сохранности данных, а также доступности и равномерного распределения нагрузки |
Redis | Репликация | Будет использоваться репликация для обеспечения работы в случае отказа главной ноды Redis. Репликация - master-slave с 2 репликами |
Для обеспечения безопасного релиза новый версий приложения будет использоваться методика Graceful Shutdown
Для обработки отказов определенных компонентов будет использоваться Graceful Degradation.
EX:
- При отказе ElasticSearch, сервис может найти необходимые данные из PSQL/MongoDB
- При отказе ClickHouse, сервис Posts может найти необходимую статистику(просмотры) в PSQL/MongoDB
Faliover Policy:
- Frontend - будут использоваться перезапросы, а также использование оффлайн логики
- Backend - будует использоваться уменьшение посылаемых запросов на проблемный хост и circuit breaker. В случае слишком большого числа запросов мы либо игнорирем запросы(в случае если с одного IP идёт слишком много), либо намерено замедляем их обработку(если слишком большое количество запросов с разных IP адресов). Circuit Breaker будет реализован с помощью nginx.
Observability:
- Мониторинг
- Алертинг
- Логирование
Асинхронные паттерны:
- CQRS - т.к. запросы будут частые, будем использовать данный паттерн. Он поможет ограничить нагрузку на запись
- Backend for Frontend - для изоляции логики
- Outbox - для записи файлов
Сервис имеет в пике 642 984 RPS и 249.5 ГБ/сек сетевого трафика
На официально сайте nginx видно, что сервер с 16 CPU видерживает 77 427 HTTP RPS
642 984/77 427 = 8.3. С округлением до целого вверх получаем 9 серверов.
Учитывая объем сетевого трафика, посчитаем количество серверов с учетом сетевого трафика: 249.5 / 40 = 6.2. С учетом округления вверх - 7
Тогда получаем следующую конфигурацию для nginx
Параметр | Значение |
---|---|
CPU | 16 |
Network | 40 ГБит/с |
Кол-во | 9 |
Микросервисы:
Сервис | RPS | CPU | RAM | Net |
---|---|---|---|---|
Messenger | 320 522 | 1284 | 321Гб | 139 ГБ/с |
Auth | 642 984 | 643 | 64 ГБ | 249,5 ГБит/с |
Channels | 2538 | 102 | 1 ГБ | 1,1 ГБит/с |
Posts | 125 589 | 503 | 13 ГБ | 55 ГБит/с |
Comments | 125 590 | 126 | 126 ГБ | 55 ГБит/с |
Users | 318 | 2 | 1 ГБ | 512 МБит/с |
Расчёты сделаны из предположения 1 ядро CPU на 100 запросов сложной логики/1000 запросов простой логики и 1 ГБ RAM на 10000 запросов(из предположения, что 1 запрос в среднем 100 кб).
В сервисах Messenger, Posts, Channels допустим соотношение простая логика/сложная логика 1:2. Comments - только простая логика
Auth - особый случай. Т.к. auth обрабатывает каждый запрос, то его RPS потенциально достигает суммарного RPS у всего проекта, аналогично с трафиком. На Auth не предполагается сложной логики
Соотношения
- посты+комменты+каналы : сообщения+чаты = 4:5
- посты:комменты = 1:1
- каналы:посты = 1:100
Также важно отметить, что минимальное количество серверов - 9(т.к. кол-во ЦОД равно 9), а с учетом, того, что мы возьмем минимум 2 сервера на ДЦ на случай отказа одного из них, то минимальное количество серверов - 18. Аналогично - минимальное количество единиц RAM - 2
Сервис | Хостинг | Конфиг | Кол-во | Цена покупки/ед | Цена аренды/ед |
---|---|---|---|---|---|
nginx | У себя | 16 core CPU Atom; 2x8 GB RAM 2400 MHz DDR4 | 18 | 2 170,84 | 195,41 |
Auth | У себя | 16 core CPU Atom; 2х4 GB RAM 2400 MHz DDR4 | 36 | 2 000,95 | 170,76 |
Users | У себя | 2 core CPU Atom; 2х4 GB RAM 2400 MHz DDR4 | 18 (1) | 1 082,62 | 46,86 |
Channels | У себя | 4 core CPU Xeon; 2х4 GB RAM 2400 MHz DDR4 | 26 | 1 576,14 | 64,56 |
Posts | У себя | 8 core CPU Xeon; 2х8 GB RAM 2400 MHz DDR4 | 18 (16) | 2 367,67 | 124,61 |
Comments | У себя | 8 core CPU Xeon; 2х8 GB RAM 2400 MHz DDR4 | 18 (16) | 2 367,67 | 124,61 |
Messenger | У себя | 16 core CPU Xeon; 2х4 GB RAM 2400 MHz DDR4 | 81 | 4 435,98 | 170,76 |
Цены на покупку взяты с конфигуратора серверов
Цены на аренду взяты с Yandex Cloud
Цена покупки: 616 047,24$
Телеграм был основан в 2013 году. Тогда суммарная аренда: 4 022 956,08$
Соответственно, купить сервера выгоднее, чем арендовать
Контейнеры:
- nginx:
- CPU: 2 core
- RAM: 4 GB
- Auth:
- CPU: 4 core
- RAM: 8 GB
- Users:
- CPU: 1 core
- RAM: 1 GB
- Channels:
- CPU: 2 core
- RAM: 4 GB
- Posts:
- CPU: 2 core
- RAM: 4 GB
- Comments:
- CPU: 4 core
- RAM: 8 GB
- Messenger:
- CPU: 4 core
- RAM: 8 GB
На контейнер Auth необходимо выделить достаточно много ресурсов, из-за высокой нагрузки даже на отдельный контейнер. Аналогична ситуация с Messenger и Comments.
Контейнер Users не будет испытывать сильно больших нагрузок, поэтому на каждый контейнер можно выделить достаточно небольшое количество ресурсов.
Channels Будет испытывать среднее количество нагрузок(в основном из-за статистики), аналогично Posts
Amazon S3
Один бакет может хранить до 5 Тб, с учетом динамического роста данных за счет фотографий и голосовых сообщений из пункта 2, получим: 1689 ПБ / 5 ТБ = 337 848 бакетов в год для хранения новых данных.
PSQL
С учетом динамического роста данных за счет текстовых сообщений из пункта 2, придется каждый год докупать новые диски для хранения 0.24 ПБ.
PostgreSQL способен выдавать около 350 000 TPS на 4 серверах на простых запросах.
Т.к. для PSQL имеются только простые запросы на 4 сервисах, то нам хватит кластера из 20 серверов(4 master + 16 slave). Необходимо сделать реплики. Тогда количество серверов будет равно 40.
Конфигурация:
CPU | RAM | ROM | Количество |
---|---|---|---|
24 | 512 ГБ | 5 ТБ | 40 |
Цена покупки:
Redis Redis Согласно официальному сайту Redis, один сервер способен выдержать 50 000 TPS.
Является in-memory хранилищем, следовательно требуется большой объём оперативной памяти.
Ежедневный онлайн составляет около 55 200 000 пользователей. Если учесть, что все они будут одновременно пользоваться нашим сервисом, то потребуется token(64 байта) + id (4 байта) + user_id (4 байта) = 72 байта на одного пользователя. С учетом коэфициента запаса 2 на дополнительные поля, которые могут возкникнуть в нашей структуре, возьме объем в 216 байт Тогда для 55 200 000: 11.10 ГБ. Для более эффективной обработки и повышения надежности можно сделать 1 master и 2 slave сервера с репликами. Всего 6 серверов.
Конфигурация:
CPU | RAM | ROM | Количество |
---|---|---|---|
2 | 32 | 20 ГБ | 6 |
Mongo Согласно исследованию, MongoDB ~ в 10 раз медленнее, чем PSQL, тогда предположим, что Mongo выдерживает 35 000 на простой логике и 10 000 на сложной на кластере из 4 серверов.
Сложная логика: Posts, Comments. Тогда необходимо покрыть 210 647 RPS
Простая логика: Messenger. Тогда необходимо покрыть 429 875 RPS
Для Posts+Comments необходим кластер из 24 серверов(master) + 48(slave) + 72(реплика) Для Messenger необходим кластер из 12 серверов(master) + 24(slave) + 36(реплика)
CPU | RAM | ROM | Количество |
---|---|---|---|
24 | 512 | 5 ТБ | 196 |