Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 

Repository files navigation

HighLoad

Репозиторий курсовой работы по высоконагруженным системам от VK Education (ex. Технопарк)



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

Reddit — это крупнейшая социальная платформа и агрегатор новостей, контента и дискуссий, основанная на пользовательских сообществах.

  • Число активных пользователей

    • MAU на 3 квартал 2024: 901 млн. Динамика изменения MAU с 2017 до 20241: image

    • DAU на 2023: 70 млн. Динамика изменения DAU c 2019 до 20242:

      Год DAU (млн)
      2019 36
      2020 52
      2021 50
      2022 57
      2023 70
      2024 1013
  • Целевая аудитория4

    • По странам: image

      Страна MAU (млн)
      США 453
      Великобритания 63
      Канада 62
      Автсралия 36
      Германия 27
    • По возрасту:

      image

    • По полу:

      image

  • Требования к функционалу

    • MVP:
      • Регистрация и авторизация
      • Создание и управление сообществами
      • Подписка на сообщества
      • Публикация и редактирование постов
      • Комментарии к постам
      • Система голосования (upvote/downvote)
      • Рекомендательная лента
      • Чат

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

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

Метриика Значение
MAU 860 млн
DAU 101 млн

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

  • В среднем пользователь авторизируется 1 раз в месяц, следовательно в день получается 1 / 30 = 0.03 раза.

  • В 2022 году среднее число ежемесячно созданных сабреддитов было равно 45975 5, значит, если предположить, что в 2024 число такое же, то в день создается примерно 45975 / 30 = 1533 сабреддита, а один пользователь создает 1533 * 10^-6 / 101 = 0.00002 сабреддита в день.

  • В среднем пользователь подписан на 15 сабреддитов 6. Новые пользователи, как правило, подписываются на несколько сабреддитов сразу после регистрации. В 2024 зарегистрировалось 30.2 млн новых пользователей7, следоватлеьно в месяц 30.2:12 = 2.52 млн новых пользователей. Предположим, что новый пользователь подписывается сразу на 10 сабреддитов, тогда 2.52 * 10 = 25.2 млн подписок в месяц от новых пользователей. Число существующих (не новых) пользователей в месяц 860 - 25.2 = 834.8 млн. Предположим, что 10% этих пользователей добавляют 1 новую подписку в месяц, тогда это ещё 834.8 * 0.1 * 1 = 83.48 млн подписок в месяц. Таким образом, общее число подписок на сабреддиты в месяц составляет 25.2 + 83.48 = 108.68 млн. Тогда один пользователь в день совершает 108.68:30:101=0.04 подписок.

  • В 2022 году было опубликовано 492.3 млн постов 6. Допустим в 2024 число такое же, тогда в день 492.3:365 = 1.35 млн постов, следовательно один пользователь создает 1.35 : 101 = 0.01 пост в день.

  • В 2022 году было оставлено 2.72 млрд комментариев 8. Так же допускаем, что в 2024 году число осталось тем же, тогда в день 2720 : 365 = 7.45 млн комментариев, а один пользователь оставляет 7.45: 101 = 0.07 комментария в день.

  • Количество голосов, оставленных пользователями, не разглашается, поэтому, предположим, что каждый пользователь оставляет по 5 голосов в день.

  • Средняя продолжительность сессии пользователя составляет 12.38 минут 9, предположим, что за день пользователь проводит 3 сессии и среднем тратит 0.2 минуты на пост, тогда среднее число просмотренных постов в день составляет 12.38*3:0.2 = 185.7.

  • Среднее количество сообщений, отправляемых ежемесячно, составляет 2.61 млдр 10, соотвественно в день 2610:30=87 млн. Тогда каждый пользователь отправляет 87:101 = 0.86 сообщений ежедневно.

    Действие Количество
    Атворизация 0.03
    Создание сабреддита 0.00002
    Подписка на сабреддит 0.04
    Публикация постов 0.01
    Написание комментариев 0.07
    Оценка постов и комментариев 5
    Просмотр постов 185.7
    Отправка сообщений 0.86

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

  • В каждом профиле содержится аватрака и текстовое описание. Аватрака, загруженная пользователем, автоматически рескейлится до разрешения 256 х 256 px, занимая в срденем 10 КБ. Срденяя длина текстового описания составляет 100 символов, в кодировке utf-8 один символ может занимать от 1 до 4 байтов, предположим, что средний размер одного символа равен 2 байтам. Тогда размер одного профиля будет составлять 10 КБ + (100 * 2 / 1024) КБ = 10.19 КБ = 0.001 МБ.
  • Для хранения одной подписки требуется около 30 байт. В среднем у пользователя 20 подписок на сабреддиты, значит общий объем памяти, необходимый для их хранения 30 * 20 = 600 байт = 0.0006 МБ.
  • Будем считать, что для хранения записи о создателе сабреддита нужно столько же памяти, что и для подписки, то есть 30 байт. Так как узнать среднее количество созданных пользователем сабреддитов нельзя, будем использовать то же соотношение, что в и подписках, то есть 20 / 0.04 = 500, значит в среднем пользователь будет являться создателем 0.00002 * 500 = 0.01 сабреддита. Тогда для хранения потребуется 30 * 0.01 = 0.3 байта = 0.3 * 1024-2 МБ.
  • Посты:
    • Медиа данные:
      • В 35% опубликованных постов содержатся изображения, средний размер которых составляет 350 КБ = 0.34 МБ (для изображения 1920х1080).
      • В 15% опубликованных постов содержится видео, средняя продолжительность которого составляет 38 секунд. Одна секунда видео в разрешении 720p занимает примерно 3 Мбит, следовательно полное видео будет занимать 38 * 3 = 114 Мбит = 14.25 МБ.
    • Текстовые данные
      • В каждом посте есть заголовок, средняя длина которого составляет 50 символов, в кодировке utf-8 один символ может занимать от 1 до 4 байтов, предположим, что средний размер одного символа равен 2 байтам. Тогда размер заголовка будет составлять 50 * 2 = 100 Б = 0.0001 МБ
      • В 80% опубликованных постов есть текстовое описание, средняя длина которого составляет 900 символов, каждый из которых кодируется 2 байтами. Тогда размер описания будет составлять 900 * 2 = 1800 Б = 0.002 МБ
    • Общий размер поста будет составлять 0.34 * 0.35 + 14.25 * 0.15 + 0.0001 + 0.002 * 0.8 = 2.26 МБ. В среднем каждый пользователь имеет 5 опубликованных постов, значит объем памяти, необходимый для их хранения, составляет 2.26 * 5 = 11.3 МБ.
  • Средняя длина комментария составляет 100 символов, каждый из которых кодируется 2 байтами. Тогда размер комментария будет составлять 100 * 2 = 200 Б = 0.0002 МБ. В среднем каждый пользователь имеет 35 комментариев, значит объем памяти, необходимый для их хранения, составляет 0.0002 * 35 = 0.007 МБ.
  • Для хранения одного голоса требуется около 31 байт. В среднем у пользователя 1000 голосов, общий объем памяти, необходимый для их хранения 31 * 1000 = 3100 байт = 0.031 МБ.
  • Для медиа данных сообщений возьмем те же рассчеты, что и для поста, скорректировав проценты: предположим, что в 2% отправленных сообщений содержатся изображения и в 0.5% видео. Средний размер текста сообщения равен 100 символам, что занимают 0.0002 МБ, как было показано ранее. Тогда общий размер сообщения равен 0.34 * 0.02 + 14.25 * 0.005 + 0.0002 = 0.08 МБ. В среднем у пользователя есть 430 сообщений, тогда общий объем памяти, необходимый для их хранения 0.08 МБ * 430 = 34.4 МБ.
Тип Количество Размер, МБ
Профиль 1 0.001
Созданные сабреддиты 0.01 0.3 * 1024-2
Подписки 20 0.0006
Посты 5 11.3
Комментарии 35 0.007
Голоса 1000 0.031
Сообщения 430 34.4
Итого 1491.01 45.74

Рост объема хранилища ежегодно

В 2024 году количество новых пользователей составили 219 млн человек 7, соответственно, взяв средний размер хранилища пользователя из предыдущего пункта, получим, что ежегодно объем хранилища будет увеличиваться на 219 млн * 45.74 МБ = 10017.68 млн МБ = 10.09 ПБ.

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

Размер хранилища

  • Число всех зарегистрированных пользователей равно 1.72 млрд, соответсвенно для хранения всех профилей понадобится 1720 * 0.001 = 1.72 млн МБ = 0.0016 ПБ.

  • Общее число сабреддитов на момент 2022 года составляло 3.4 млн 5, с учетом ежемесясного роста числа сабреддитов на 45975 5, получим, что в 2024 году общее число сабреддитов составит 3.4 млн + (45975 * 12 * 2) = 4.5 млн. Тогда размер памяти для хранения записей о создании сабреддитов будет составлять 4.5 * 0.3 * 1024-2 = 1.29 * 10-6 млн МБ = 1.2 * 10-9 ПБ.

  • Общее число всех подписок неизвестно, поэтому посчитаем его исходя из общего количества зарегистрированных пользователей, равного 1.72 млрд, и предположения, сделанного ранее, что у среднего пользователя объем памяти, необходимый для хранения подписок, равен 0.0006 МБ. Тогда 1720 * 0.0006 = 1.3 млн МБ = 0.001 ПБ.

  • Аналогично предыдущему пункту для постов получим 1720 * 11.3 = 19436 млн МБ = 18.1 ПБ.

  • Для комментариев 1720 * 0.007 = 12.04 млн МБ = 0.011 ПБ.

  • Для голосов 1720 * 0.031 = 53.32 млн МБ = 0.049 ПБ.

  • Для сообщений 1720 * 34.4 = 59168 млн МБ = 51.21 ПБ.

    Тип Размер, ПБ
    Профили пользователей 0.0016
    Сабреддиты 1.2 * 10-9
    Подписки 0.001
    Посты 18.1
    Комментарии 0.011
    Голоса 0.049
    Сообщения 51.21
    Итого 69.37

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

Формула: Среднее потребление = Трафик на действие * RPS
Пиковое потребление = 1.7 * Среднее потребление
Суммарный суточный трафик = Трафик на действие * Количество запросов в день от одного пользователя * DAU

  • Авторизация:

    • Среднее потребление: 2.8 КБ * 8 * 35.07 ≈ 785.344 Кбит/с ≈ 0.000785 Гбит/с
    • Пиковое потребление: 1.7 * 0.000785 ≈ 0.001335 Гбит/с
    • Суммарный суточный трафик: 2.8 КБ * 0.03 * 101000000 ≈ 8484000 КБ ≈ 8.484 ГБ
  • Создание сабреддита:

    • Среднее потребление: 2.5 КБ * 8 * 0.02 ≈ 0.4 Кбит/с ≈ 0.0000004 Гбит/с
    • Пиковое потребление: 1.7 * 0.0000004 ≈ 0.00000068 Гбит/с
    • Суммарный суточный трафик: 2.5 КБ * 0.00002 * 101000000 ≈ 5050 КБ ≈ 0.005 ГБ
  • Подписка на сабреддит:

    • Среднее потребление: 1.8 КБ * 8 * 46.76 ≈ 673.344 Кбит/с ≈ 0.000673 Гбит/с
    • Пиковое потребление: 1.7 * 0.000673 ≈ 0.001144 Гбит/с
    • Суммарный суточный трафик: 1.8 КБ * 0.04 * 101000000 ≈ 7272000 КБ ≈ 7.272 ГБ
  • Публикация постов:

    • Среднее потребление: 28.8 КБ * 8 * 11.69 ≈ 2693.376 Кбит/с ≈ 0.002693 Гбит/с
    • Пиковое потребление: 1.7 * 0.002693 ≈ 0.004578 Гбит/с
    • Суммарный суточный трафик: 28.8 КБ * 0.01 * 101000000 ≈ 28800000 КБ ≈ 28.800 ГБ
  • Написание комментариев:

    • Среднее потребление: 5.5 КБ * 8 * 81.83 ≈ 3600.52 Кбит/с ≈ 0.003601 Гбит/с
    • Пиковое потребление: 1.7 * 0.003601 ≈ 0.006122 Гбит/с
    • Суммарный суточный трафик: 5.5 КБ * 0.07 * 101000000 ≈ 38885000 КБ ≈ 38.885 ГБ
  • Оценка постов и комментариев:

    • Среднее потребление: 2.5 КБ * 8 * 5844.91 ≈ 116898.2 Кбит/с ≈ 0.116898 Гбит/с
    • Пиковое потребление: 1.7 * 0.116898 ≈ 0.198727 Гбит/с
    • Суммарный суточный трафик: 2.5 КБ * 5 * 101000000 ≈ 1262500000 КБ ≈ 1262.500 ГБ
  • Просмотр постов:

    • Среднее потребление: 16 КБ * 8 * 14472 ≈ 1852416 Кбит/с ≈ 1.85 Гбит/с
    • Пиковое потребление: 1.7 * 1.85 ≈ 3.145 Гбит/с
    • Суммарный суточный трафик: 16 КБ * 12.38 * 101000000 ≈ 20006080000 КБ ≈ 20006.08 ГБ
  • Отправка сообщений:

    • Среднее потребление: 0.916 КБ * 8 * 1005.32 ≈ 7366.984 Кбит/с ≈ 0.007367 Гбит/с
    • Пиковое потребление: 1.7 * 0.007367 ≈ 0.012524 Гбит/с
    • Суммарный суточный трафик: 0.916 КБ * 0.86 * 101000000 ≈ 79676560 КБ ≈ 79.677 ГБ
Действие Трафик на действие Среднее потребление, Гбит/с Пиковое потребление, Гбит/с Суммарный суточный трафик, ГБ
Авторизация 2.8 КБ 0.000785 0.001335 8.484
Создание сабреддита 2.5 КБ 0.0000004 0.00000068 0.005
Подписка на сабреддит 1.8 КБ 0.000673 0.001144 7.272
Публикация постов 28.8 КБ 0.002693 0.004578 28.800
Написание комментариев 5.5 КБ 0.003601 0.006122 38.885
Оценка постов и комментариев 2.5 КБ 0.116898 0.198727 1262.500
Просмотр постов 16 КБ 1.85 3.145 20006.08
Отправка сообщений 0.916 КБ 0.007367 0.012524 79.677

RPS

Формула: RPS = (Количество запросов в день от одного пользователя * DAU) / 86400 секунд
Пиковое RPS = 1.7 * RPS

  • Авторизация:

    • RPS = (0.03 * 101000000) / 86400 ≈ 35.07
    • Пиковое RPS: 35.07 * 1.7 ≈ 59.62
  • Создание сабреддита:

    • RPS = (0.00002 * 101000000) / 86400 ≈ 0.02
    • Пиковое RPS: 0.02 * 1.7 ≈ 0.03
  • Подписка на сабреддит:

    • RPS = (0.04 * 101000000) / 86400 ≈ 46.76
    • Пиковое RPS: 46.76 * 1.7 ≈ 79.49
  • Публикация постов:

    • RPS = (0.01 * 101000000) / 86400 ≈ 11.69
    • Пиковое RPS: 11.69 * 1.7 ≈ 19.87
  • Написание комментариев:

    • RPS = (0.07 * 101000000) / 86400 ≈ 81.83
    • Пиковое RPS: 81.83 * 1.7 ≈ 139.11
  • Оценка постов и комментариев:

    • RPS = (5 * 101000000) / 86400 ≈ 5844.91
    • Пиковое RPS: 5844.91 * 1.7 ≈ 9936.35
  • Просмотр постов:

    • При каждом запросе отправляется по 15 постов, соответственно среднее количество запросов 185.7 / 15 = 12.38
    • RPS = (12.38 * 101000000) / 86400 ≈ 14472
    • Пиковое RPS: 14472 * 1.7 ≈ 24602.4
  • Отправка сообщений:

    • RPS = (0.86 * 101000000) / 86400 ≈ 1005.32
    • Пиковое RPS: 1005.32 * 1.7 ≈ 1709.04
Тип запроса Среднее RPS Пиковое RPS
Авторизация 35.07 59.62
Создание сабреддита 0.02 0.03
Подписка на сабреддит 46.76 79.49
Публикация постов 11.69 19.87
Написание комментариев 81.83 139.11
Оценка постов и комментариев 5844.91 9936.35
Просмотр постов 14472 24602.4
Отправка сообщений 1005.32 1709.04
Итого 21497.6 36545.91

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

Разбиение по доменам

  • www.reddit.com — основной домен, где находится основная часть контента
  • m.reddit.com — мобильная версия сайта
  • mod.reddit.com — инструменты для модераторов
  • api.reddit.com — API для разработчиков.
  • oauth.reddit.com — используется для OAuth-аутентификации.

Расположение датацентров

Чуть больше половины пользователей reddit (57.23%) находятся в северной америке 11, следовательно большая часть ДЦ будет располагаться там. Также большое количество пользователей (~20.14%) располагаются в Европе, а именно в Великобритании, Германии, Франции, Швеции, Испании, Нидерландах, Италии 11. Еще заметное число пользователей (5.18%) находятся в Индии. В Австралии располагается 3.54% пользоватлей. В южной америке, а именно в Бразилии и Аргентине, находится 4.75% пользоватлей 11.

Регион Страны Доля пользователей Reddit
Северная Америка США, Канада 57.23%
Европа Великобритания, Германия, Франция, Швеция, Испания, Нидерланды, Италия 20.14%
Индия Индия 5.18%
Австралия Австралия 3.54%
Южная Америка Бразилия, Аргентина 4.75%

Так как большинство пользователей находятся в США, проведем анализ численности населения по штатам 12:

image

Самые густонасленные штаты:

  • Калифорния - 39.5 млн
  • Техас - 28.7 млн
  • Флорида - 21.3 млн
  • Нью-Йорк - 19.5 млн

Для них стоит расположить ДЦ в самых населенных городах. Для менее густонаселенных участков расположим один ДЦ на несколько штатов. Таким образом спсиок городов с ДЦ в США будет иметь вид:

  • Лос-анджелес
  • Хьюстон
  • Маями
  • Нью-Йорк
  • Денвер
  • Сиэтл
  • Сент-Луис

Для остальных стран расположим по 1 ДЦ в самых густонаселенных городах:

  • Эдмонтон
  • Лондон
  • Берлин
  • Мадрид
  • Рим
  • Нью Дели
  • Сидней
  • Бразилиа

image

Интерактивная карта: https://yandex.ru/maps/?um=constructor%3Abf2ab49a37b44b80fba2b2012349a15d68757823babed98b1eb5aec839e83e00&source=constructorLink

Расчет распределения запросов

Формула: Пиковый RPS * % всех пользователей / 100

Страна % всех пользователей Суммарный RPS на страну
США 50.36 15156.60
Великобритания 9.93 2979.69
Германия 7.64 2299.46
Канада 6.9 2076.66
Франция 6.84 1964.74
Индия 5.18 1558.99
Австралия 4.07 1224.93
Бразилия 3.65 1098.53

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

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


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

Cхемы балансировки для входящих и межсервисных запросов

  • Входящий трафик будет балансироваться с помощью Virtual Server via Direct Routing, что позволит значительно снизить трафик, проходящий через балансировщик. CARP (Common Address Redundancy Protocol) объединяет несколько устройств в группу с одинм IP-адресом, определяя master устройство, которое обрабатывет трафик, поступающий на назначенный IP-адрес. Если master выходит из строя, то другое устройство из группы возьмет на себя его обязанности. Чаще всего группы состоят из двух устройств. Также каждый хост одновременно может принадлежать к нескольким группам.
  • Далее трафик поступает на Ngnix, который выступает HTTP Reverse Proxy балансировщиком. Nginx предоставляет возможность SSL-терминации, кэширования и сжатия ответов от серверов-источников, облегчая нагрузку внутренних серверов.
  • Далее трафик поступает в один из кластеров Kubernetes, где с помощью Ingress nginx направляется к соответствущим сервисам кластера.

Cхема отказоустойчивости

Для отказоустойчивости будут применяться инструменты k8s и nginx. Kubernetes с помощью readiness-проб обеспечит исключение из кластера упавших подов и добавление новых, а также сможет автоматически поднимать упавшие сервера. Kubernetes также позволит выполнять удобный auto-scaling, чтобы подстраиваться под актуальную нагрузку. Nginx умеет выполнять retry запросов после падения бэкенда, перезапускать web-сервера без downtime, равномерно распределять запросы по бэкендам, а также незаметно для пользователя перезагружать конфиг при обновлениях.

Нагрузка по терминации SSL

Среднее время выполнения SSL-рукопожатия может варьироваться от 2 мс при использовании сокращённого рукопожатия до 11 мс при полном рукопожатии 13. Для последующих расчётов будем учитывать, что SSL-рукопожатие занимает 3 мс, так как мы планируем использовать сокращённые рукопожатия в Nginx. Это означает, что сервер и клиент будут переиспользовать ранее установленную защищённую сессию с помощью механизма session tickets, что значительно сокращает время и нагрузку на процессор. Тогда, считая пиковый RPS равным 131355.32, получим, что на терминацию SSL будет затрачиваться 131355.32 * 3 = 394065,96 мс = 394.1 с процессорного времени в секунду.


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

Схема

imgae

Размеры данных и консистентность

Таблица Размеры данных Консистентность
session (16 token + 16 user_id + 8 expiration_datetime) * 860 млн. MAU = 32.04 ГБ -
users (16 id + 64 username + 256 email + 128 password_hash + 64 password_salt + 8 created_at + 8 updated_at) * 1720 млн. пользователей = 871.42 ТБ При удалении пользователя удаляются все его данные: сессии, посты, комментарии, голоса, подписки, сообщения.
communities (16 id + 32 name + 256 description + 16 creator_id + 8 created_at + 8 updated_at) * 4.5 млн сабреддитов = 1.41 ГБ При удалении сообщества удаляются все связанные посты и подписки.
subscriptions (16 user_id + 16 community_id + 8 created_at) * 1720 млн. пользователей * 20 подписок на пользователя = 1.25 ТБ -
posts (16 id + 32 title + 1024 content + 16 author_id + 16 community_id + 8 created_at + 8 updated_at) * 1720 млн. пользователей * 5 постов на пользователя = 8.76 ТБ При удалении поста удаляются его комментарии, голосаи медиафайлы.
media (16 id + 16 post_id + 128 file_url + 8 file_type + 8 created_at) * 8600 млн. постов * 0.5 медиафайла на пост = 704.82 ГБ -
comments (16 id + 512 content + 16 author_id + 16 post_id + 16 parent_comment_id + 8 created_at + 8 updated_at) * 1720 млн. пользователей * 35 комментария на пользователя = 32.41 ТБ При удалении комментария удаляются все его голоса.
votes_comments (16 id + 16 user_id + 16 comment_id + 8 vote_type + 8 created_at) * 1720 млн. пользователей * 100 голосов = 8.9 ТБ -
votes_posts (16 id + 16 user_id + 16 post_id + 8 vote_type + 8 created_at) * 1720 млн. пользователей * 200 голосов = 17.8 ТБ -
messages (16 id + 16 sender_id + 16 receiver_id + 512 content + 8 created_at) * 1720 млн. пользователей * 430 сообщения на пользователя = 382.07 ТБ -

Нагрузка на чтение/запись

Таблица Тип операции Пиковый QPS
posts Чтение 24602
Запись 19.87
comments Чтение 12301
Запись 139.11
votes_ Запись 9936
messages Чтение 854.52
Запись 1709
subscriptions Запись 79.49
users Чтение 173.12

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

Схема

Индексы

Таблица Индексы Пояснение
posts (community_id, created_at, is_deleted), (created_at, is_deleted) Поиск постов сообщества. Сортировка постов сообщества по рейтингу. Глобальная лента новых постов.
subscriptions (user_id, community_id), community_id Быстрое получение сообществ, на которые подписан пользователь. Быстрый подсчет подписок сообщества.
comments (post_id, created_at, is_deleted), (user_id, is_deleted) Сортировка комментариев к посту по дате создания, рейтингу. Быстрое получение коменнтариев пользователя.
votes_comments (comment_id, is_deleted) Подсчет голосов для комментария
votes_posts (post_id, is_deleted) Подсчет голосов для поста
messages (sender_id, receiver_id, created_at, is_deleted), (receiver_id, created_at, is_deleted) Получение переписки между пользователями, входящих сообщений
posts/comments_total_votes (post/comment_id) Получение количества голосов поста/комментария

Денормализация

Таблица Денормализованное поле/таблица Источник Пояснение Размер
posts author_username users.username Для избегания JOIN c users при отображении автора поста 64 Б * 8.6 млрд. постов = 550 ГБ
community_name communities.name Для избегания JOIN c communities при отображении cообщества, в котором опубликован пост 32 Б * 8.6 млрд. постов = 225 ГБ
media media.file_url Для избегания JOIN c media при отправке ссылки на медиа файлы 128 Б * 4.3 млрд. постов с медиа = 550 ГБ
comments author_username users.username Для избегания JOIN c users при отображении автора комментария 64 Б * 17.2 млрд. комментариев = 1100 ГБ
subscriptions communtiy_name communities.name Для избегания JOIN c communities при отображении cообществ, на которые подписан пользователь 32 Б * 34.4 млрд. подписок = 1100 ГБ
communities communities_member_count subscriptions Для избегания сложного COUNT в subscriptions (16 + 8) Б * 4.5 млн. сообществ = 0.1 ГБ
post/comments posts/comments_total_votes votes_posts/comments Для избегания сложного COUNT в votes (16 + 8) Б * (8.6 + 17.2) млрд. постов и комментариев = 577 ГБ

Выбор СУБД

  • posts, communities, users, meassages, subscriptions, votes_comments, votes_posts, comments: Данные с очень частой записью/чтением и большим объемом, соответственно, они требуют большой пропускной способности и легкого горизонтального масштабирования, что предоставляет Apache Cassandra.
  • session: Очень большая частота обращения к данным для проверки сессии. Необходимо обеспечить минимальную задержку для проверки сессии, желательно иметь механизм автоматического удаления просроченных сессий, под такие тербования идеально подходит Redis.
  • search_communities, search_comments, search_users, search_posts: Elasticsearch является стандартом для полнотекствого поиска в виду быстрого и морфологического поиска, удобства масшатибрования.

Шардирование и резервирование СУБД

Таблица Шардирование Резервирование Пояснение
posts По community_id (хеш) Cassandra RF=3 Шардирование по сообществам для локализации данных.
votes_posts По post_id (хеш) Cassandra RF=3 Шардирование по постам для локализации данных.
votes_comments По comment_id (хеш) Cassandra RF=3 Аналогично votes_posts.
comments По post_id (хеш) Cassandra RF=3 Шардирование по постам для локализации данных.

Клиентские библиотеки / интеграции

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

  • Cassandra – gocql (Go)
  • Redis – go-redis

Балансировка запросов / мультиплексирование подключений

Для оптимизации нагрузки на БД реализуются следующие механизмы балансировки:

  • Cassandra – балансировка на уровне драйвера (Token-aware routing), встроенные механизмы распределения нагрузки
  • Redis – Redis Cluster с автоматической маршрутизацией запросов, балансировка через Sentinel

Схема резервного копирования

Резервное копирование данных выполняется с учетом особенностей каждой СУБД:

  • Cassandra – snapshot-based бэкапы, incremental SSTable бэкапы, резервное копирование commitlog
  • Redis – кластерное резервирование

7. Алгоритмы

"Hot" Сортировка постов

Этот алгоритм позволяет:

  • Поднять свежее, пока его не «перелистали»
  • Удержать то, что понравилось многим
  • Затухать интерес к старому
  • Дать шанс нишевому посту обойти шумный, если тот собирает и апвоуты, и даунвоуты

Сам алгоритм работает так:

  1. Берется разница между врменем публикации поста A и B - "нулевым" днем 8.12.2005 7:46:43 (1134028003 в секундах) $$t_s = A - B$$
  2. Также находится разница между апвоутами U и даунвоутами D $$x = U - D$$
  3. "Нормируем" оценку x $$z= |x|, если |x| \geq 1; z = 0, если |x|=0$$
  4. Итоговый рейтинг вычисляется как $$R = \log_{10}z + \frac{sign(x)t_s}{45000}$$

Анализируя данный алгоритм, можно выделить несколько особенностей:

  • Время публикации имеет большое влияние на рейтинг и алгоритм будет ставить выше новые посты, а не старые
  • При этом рейтинг не уменьшается при течении времени, но новые посты получат более высокий рейтинг, чем старые. Данный подход отличается от множества алгоритмов, где рейтинг уменьшается при течении времени.

Вот визуализация ретйинга для постов с одинаковыми голосами, но разным временем публикации:

Также в алгоритме используется десятичный логарифм, что приводит к тому, что первые 10 голосов будут иметь тот же вес, что и следующие 100, которые будут иметь тот же вес, что и следущие 1000 и тд. Без испольования логарифмичесокго масштаба рейтинг рассчитывался бы как:

А с использованием логарифма:

Такой подход позволяет не самым популярным постам все равно попадать в ленту, при этом сохраняя наивысший рейтинг у самых популярных постов. Также можно визуализировать влияние даунвоутов:

То есть на итоговый рейтинг влияет только разница апвоутов и даунвоутов, что делает популярные посты, понравившиеся далеко не всем пользователям, менее рейтинговыми. Соответственно лучше публиковать безобидные посты, которые, теоритически, не получат много отрицательных оценок.

"Best" Сортировка комментариев

Данная сортировка отличается от Hot для постов, так как ее создатель считал, что время публикации комментария не должно сильно влиять на его ранг. Рассмотрим действия алгоритма:

  1. Для начала находим общее число голосов, складывая апвоуты U и даунвоуты D: $$n = U + D$$
  2. Если n = 0, то сразу возвращаем рейтинг 0. Иначе переходим к следующему шагу
  3. Далее определяем отношения числа апвоутов к общему числу голосов: $$\hat{p} = \frac{U}{n}$$
  4. Обозначаем квантиль стандартного нормального распределения с уровнем 90% за z: $$z=U_{0.9}=1.282$$
  5. Итоговый ретйинг будет считаться по формуле: $$R = \frac{\hat{p} + \frac{1}{2n}z^2 - z\sqrt{\frac{\hat{p}(1-\hat{p})}{n} + \frac{z^2}{4n^2}}}{1+\frac{1}{n}z^2}$$

Данный алгоритм использует доверительный интервал Вилсона, который:

  1. Наказывает «тонкие выборки». Один лайк из 1 → 100 % апвоутов, но при n=1 интервал настолько широкий, что нижняя граница ≈0.20 — и комментарий не вылетает в топ. Но если у комментария 10 апвоутов и только 1 даунвоут, алгоритм может быть достаточно уверен в том, что его можно поставить выше комментария с 40 апвоутами и 20 даунвоутами - полагая, что к тому времени, когда он также получит 40 апвоутов, почти наверняка у него будет меньше 20 даунвоутами. И самое приятное, что если он неверен (а это случается в 10% случаев), он быстро получит больше данных, поскольку комментарий с меньшим количеством данных находится ближе к топу.
  2. Не завязан на время. В отличие от Hot, возраст комментария в рейтинг не входит: в ветке все одинаково «свежие».
  3. Просто считает, нет внешнего состояния, кроме ups/downs; формула O(1).

Можно также визуализировать рейтинг комментариев с разным соотношением голосов:

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


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

Технология Область применения Мотивация
Фронтенд
TypeScript Язык программирования Строгая типизация, расширенный фугкционал по сравнению с JS
React Веб-интерфейс Компонентный подход, высокая производительность, поддержка SSR для SEO
React Native Мобильные приложения Кроссплатформенность, повторное использование кода, нативная производительность
GraphQL Запросы данных Оптимизация запросов, уменьшение перегрузки сети, строгая типизация
Бэкенд
Go (Golang) Основной язык сервисов Высокая производительность, низкое потребление памяти, встроенная поддержка многопоточности
Apache Cassandra Основное хранилище данных Горизонтальное масштабирование, отказоустойчивость, высокая пропускная способность записи
Redis Кеш/сессии Низкая задержка, поддержка структур данных, автоматическое удаление TTL-записей
Elasticsearch Поиск и аналитика Полнотекстовый поиск, агрегации данных, горизонтальное масштабирование
Инфраструктура
Docker Контейнеризация Изоляция сервисов, переносимость, интеграция с оркестраторами
Kubernetes Оркестрация контейнеров Автомасштабирование, self-healing, управление распределенными системами
Nginx Reverse Proxy / Load Balancer Терминация SSL, кеширование, балансировка L7-трафика
Jenkins CI/CD пайплайны Автоматизация сборки и деплоя, поддержка плагинов, распределенные сборки
Terraform IaC Декларативное управление инфраструктурой, поддержка multi-cloud
Ansible Конфигурация серверов Идемпотентность, автоматизация рутинных задач
Мониторинг
Prometheus Сбор метрик Многоразмерные данные, интеграция с Grafana, pull-модель
Grafana Визуализация метрик Гибкие дашборды, поддержка множества источников данных

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

Физический уровень

Сфера Меры обеспечения надежности
Уровень ДЦ Tier IV
Серверы • Горячая замена компонентов (диски, БП, вентиляторы)
• RAID 10 для хранилищ
• Размещение в разных стойках/зонах ДЦ
Сеть • Двойные маршрутизаторы (VRRP/HSRP)
• BGP multihoming (≥2 провайдера)
• Раздельные физические кабельные трассы
Электропитание • Источники бесперебойного питания (5-15 мин автономии)
• Дизель-генераторы (24+ ч топлива)
• ATS для автоматического переключения
Охлаждение • Системы CRAC
• Горячие/холодные коридоры
• Фальшполы с вентиляцией
Безопасность • Биометрический доступ + видеонаблюдение
• Газовое пожаротушение
• Датчики задымленности/протечек
Мониторинг • DCIM-системы в реальном времени
• Автоскрипты переключения при отказах

Уровень сервисов

Слой / компонент Способ резервирования / отказоустойчивости Примечание
Kubernetes control‑plane 3 master‑ноды в разных AZ, etcd RF = 3, регулярные snapshots → S3 Кворум 2/3; потеря узла/AZ без простоя
Kubernetes worker‑nodes Auto‑Scaling Groups по 3 AZ, HPA, pod‑anti‑affinity Замещение узла + автоматическое масштабирование
Cassandra cluster Multi‑DC, Replication Factor = 3, LOCAL_QUORUM, incremental SSTable‑backups Потеря узла/целого DC — данные и сервис доступны
Redis Cluster / сессии 3 masters + 3 replicas, Sentinel‑quorum = 3, AOF + RDB, anti‑affinity Авто‑фейловер ≤ 3 s, сохранность данных
Elasticsearch 3 master‑eligible + N data‑nodes, Replica = 1, ежедневные snapshots → S3 Шарды пересинхронизируются, поиск непрерывен
Object‑storage Erasure coding 8/4, versioning, cross‑region replication Потеря диска/узла/региона без утраты объектов
Message broker (Kafka) RF = 3, ISR‑контроль, daily topic‑level backups → S3 Exactly‑once semantics + DR‑восстановление
CI/CD (Jenkins) 2 controllers (active/passive), агенты в k8s, nightly backup $JENKINS_HOME Переключение ≤ 1 min, сохранность history

Graceful Shutdown/Degradation

Graceful Shutdown: механизм корректного завершения работы сервиса, при котором:

  • Прекращается прием новых запросов, но уже обрабатываемые завершаются.
  • Сохраняются данные (кеш, сессии, транзакции).
  • Закрываются соединения с БД, очередями и другими сервисами.

Graceful Degradation: механизм перехода к более простой бизнес-логике или делегирования запросов при отвале сервиса или его части (БД, очереди и тд)

  • Поиск - даем пользователю выбрать, что именно будем искать: сообщества, посты, пользователей и тд, далее идем напрямую в нужную БД и используем встроенный поиск.
  • Сообщества - в отображении постов используем заглушку (например r/community), при попытке перейти в сообщество сообщаем об ошибке и просим подождать.
  • Посты - выдаем везде одни и те же посты (с пометкой о том, что другие посты сейчас недоступны), хранящиеся в специальной БД base_posts, в которую иногда добавляем посты от имени reddit. Если и она недоступна, сообщаем пользователю об ошибке и просим подождать.
  • Комментарии - в отображении постов счетчик комментариев показывает 0, отключаем возможность писать комментарии.
  • Голоса - тоже в отображении постов счетчик голосов обнуляем, при этом если пользователь создает голос, пишем об этом в LocalStorage, откуда, при восстановлении сервиса, отпрпавляем запросы.
  • Пользователи - при отображении постов, комментариев и сообществ заменяем пользователей заглушкой, при попытке зайти в профиль сообщаем об ошибке.
  • Рекомендации - отдаем посты сообществ и пользователей, на которые подписан пользователь.

Также опишем работу некоторых сервисов для снижения нагрузки:

  • Посты - вместо моментальной подгрузки информации об авторе и сообществе, которая требует получения соответствующей инфорамции с сервера, используем технику lazy-loading, согласно которой запрос информации происходит только тогда, когда это действительно нужно, в нашем случае при наведении пользователем курсора на поле автора или сообщества. Изначально будут показываться только денормализованные поля названия сообщества и имени пользователя, которые хранятся в табличке постов. Такой подход позволит существенно снизить нагрузку на сервер и улучшит пользовательский опыт и SEO за счет снижения времени загрузки отедльных постов и, соответственно, ленты.
  • Комментарии - аналогичный подход с использованием lazy-loading, где изначально информация об авторе комментария будет ограничена его именем - денормализованном полем, хранящемся в табличке комментариев, так же позволит значительно уменьшить объем потока запросов на сервер, что усовершенствует UX и SEO.

Асинхронные паттерны

CQRS (Command Query Responsibility Segregation) - архитектурный паттерн, который разделяет пайплайны для чтения и записи в БД. Дает возможность управлять нагрузкой на запись в БД, а также обеспечивает независимость запросов чтения от записывающих команд. Исопльзуется в таких микросервисах, как сообщества, комменатрии и голоса для выдерживания огромного RPS, поступающего на соответствующие БД каждого микросервиса.

Отбивка статистики - каждый сервис асинхронно пишет события в prometheus

Outbox - гарантия доставки всех событий в соответствующую очередь для дальнейшей записи в БД событий, используемую для создания рекомендаций с помощью ML модели.


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


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

Сервисы

Посчитаем RPS каждого сервиса:

  • Поиск:
    • RPS = (5 * 101000000) / 86400 = 5844.9
    • Пиковый RPS = 5844.9 * 1.7 = 9936.3
  • Авторизация:
    • Запросы от других сервисов на валидацию сессии = Создание сабреддита (0.03) + подписка на сабреддит (79.49) + публикация поста (19.87) + написание комментария (139.11) + оценка постов и комментариев (9936.35) + отправка сообщений (1709.04) = 11883.89
    • Общий пиковый RPS сервиса = Запросы от других сервисов на валидацию сессии + Авторизация = 11883.89 + 59.62 = 11943.51
  • Сообщества:
    • пиковый RPS = Создание сабреддита + подписка на сабреддит = 0.03 + 79.49 = 79.52
  • Посты:
    • пиковый RPS = Публикация постов + просмотр постов = 19.87 + 24602.4 = 24622.27
  • Комментарии:
    • пиковый RPS = запрос комментариев + написание комментариев = 12301.2 + 139.11 = 12440.31
  • Голоса:
    • пиковый RPS = Запросы на получение количества лайков на посте/комментарии + создание голоса = 24602.4 + 12301.2 + 9936.35 = 46839.95
  • Пользователи:
    • пиковый RPS = проверка существования пользователя от сервиса Авторизации при авторизации + просмотр профиля = 59.62 + 173.12 = 232.74
  • Сообщения:
    • пиковый RPS = отправка + получение сообщений = 1709.04 + 854.52 = 2563.56
  • Рекомендации:
    • RPS = DAU / 86400 = 101000000 / 86400 = 1168.98
    • Пиковый RPS = 1168.98 * 1.7 = 1987.26

Оценка потребления ресурсов со степенью сложности на одно ядро:

Сложность сервиса RPS RAM
Тяжелая 10 100 Mb
Средняя 100 100 Mb
Легкая 5000 10 Mb
Сервис Пиковый RPS Сложность CPU (vCPU) RAM (ГБ) Трафик (Гбит/с)
Поиск 9936.3 Средняя 100 9.9 0.49
Авторизация 11943.51 Легкая 24 1.2 0.266
Сообщества 79.52 Средняя 1 0.08 0.001
Посты 24622.27 Легкая 50 2.5 3.149
Комментарии 12440.31 Легкая 25 1.2 1.59
Голоса 46839.95 Легкая 94 3.5 0.89
Пользователи 232.74 Легкая 1 0.02 0.002
Сообщения 2563.56 Легкая 1 0.26 0.001
Рекомендации 1987.26 Тяжелая 199 198.7 19.87

БД

Индексы:

Таблица posts (11.06 ТБ данных)

  1. (community_id, created_at, is_deleted)

    • Размер ключа: 16 (community_id) + 8 (created_at) + 1 (is_deleted) = 25 байт.
    • Размер индекса: (25 + 16) × 8.6 млрд × 1.1 ≈ 361 ГБ.
  2. (created_at, is_deleted)

    • Размер ключа: 8 + 1 = 9 байт.
    • Размер индекса: (9 + 16) × 8.6 млрд × 1.1 ≈ 220 ГБ.

Итого: 581 ГБ

Таблица subscriptions (2.35 ТБ данных)

  1. (user_id, community_id)

    • Размер ключа: 16 + 16 = 32 байта.
    • Размер индекса: (32 + 16) × 17.7 млрд × 1.1 ≈ 870 ГБ.
  2. community_id

    • Размер ключа: 16 байт.
    • Размер индекса: (16 + 16) × 17.7 млрд × 1.1 ≈ 580 ГБ.

Итого: 1.45 ТБ

Таблица comments (33.51 ТБ данных)

  1. (post_id, created_at, is_deleted)

    • Размер ключа: 16 + 8 + 1 = 25 байт.
    • Размер индекса: (25 + 16) × 17.2 млрд × 1.1 ≈ 832 ТБ.
  2. (user_id, is_deleted)

    • Размер ключа: 16 + 1 = 17 байт.
    • Размер индекса: (17 + 16) × 17.2 млрд × 1.1 ≈ 581 ТБ.

Итого: 1.41 ТБ

Таблица votes_comments (8.9 ТБ данных)

  • (comment_id, is_deleted)

    • Размер ключа: 16 + 1 = 17 байт.
    • Размер индекса: (17 + 16) × 172 млрд × 1.1 ≈ 5.84 ТБ.

    Итого: 5.84 ТБ

Таблица votes_posts (17.8 ТБ данных)

  • (post_id, is_deleted)

    • Размер ключа: 16 + 1 = 17 байт.
    • Размер индекса: (17 + 16) × 344 млрд × 1.1 ≈ 11.63 ТБ.

    Итого: 11.63 ТБ

Таблица messages (382.07 ТБ данных)

  1. (sender_id, receiver_id, created_at, is_deleted)

    • Размер ключа: 16 + 16 + 8 + 1 = 41 байт.
    • Размер индекса: (41 + 16) × 740 млрд × 1.1 ≈ 46.43 ТБ.
  2. (receiver_id, created_at, is_deleted)

    • Размер ключа: 16 + 8 + 1 = 25 байт.
    • Размер индекса: (25 + 16) × 740 млрд × 1.1 ≈ 33.37 ТБ.

Итого: 79.8 ТБ

Общий размер индексов: ~100.7 ТБ.

Резервирование:

Cassandra: С учетом перечисленных в пункте 9 средств обеспечения надежности для cassandra, получим, что общий размер хранения увеличится в ~3.2 раза (3 реплики + overhead ~20%), то есть общий размер для одного ДЦ составит

  • RAM: 100.7 ТБ * 3.2 = 322.2 ТБ
  • Disk: 1313.71 ТБ * 3.2 = 4203.87 ТБ

Redis: 3 мастера и 3 реплики, значит объем RAM увеличивается в 6 раз. RDB (снапшот) и AOF (лог операций) хранятся в постоянной памяти и занимают примерно 2.5 * RAM. В итоге получаем

  • RAM: 32.04 ГБ * 6 = 192.24 ГБ
  • Disk: 192.24 ГБ * 2.5 = 480.6 ГБ

Elasticsearch: В этом случае посчитаем объем каждой таблицы с учетом реплик

Таблица Оценка размера текстов Оценка индекса (×3) С репликами (×2)
search_posts ~6 ТБ 18 ТБ 36 ТБ
search_comments ~25 ТБ 75 ТБ 150 ТБ
search_users ~100 ТБ 300 ТБ 600 ТБ
search_communities ~0.5 ГБ 1.5 ГБ 3 ГБ

В сумме - 787 ТБ постоянной памяти + 105.3 ТБ RAM

ClickHouse: Если считать, что почти все запросы это события, то их получается около 99000 в секунду. Допустим, размер одного события равен 350 байт, тогда

  1. Событий в день: 99000 * 60 * 60 * 24 = 8.55 млрд
  2. Исходный объем без сжатия: 8.55 млрд * 350 Б = 3.12 ТБ/день
  3. Сжатый объем: 3.12 / 5 = 624 ГБ/день
  4. За 30 дней хранения: 624 ГБ * 30 = 18.72 ТБ
  5. С учетом репликации: 18.72 ТБ * 2 = 37.44 ТБ
  6. Необходимое количество RAM ~312 ГБ

Для расчета QPS примем размер входящих батчей равным 1000 событиям, тогда QPS получается 99000 / 1000 = 99.

S3: Из расчетов, что в каждом втором посте есть изображение и в каждом седьмом посте есть видео со средними размерами 0.35 МБ и 14.25 МБ соответственно, также в 2% сообщений есть изображения и в 0.5% видео, тогда получим, что объем S3 должен быть: 8.6 млрд постов * (0.5 * 0.35 + 0.15 * 14.25) + 1.72 млрд пользователей * 430 сообщений/пользователя * (0.02 * 0.35 + 0.005 * 14.25) = 65.66 ПБ

Итоговая таблица БД

CPU возьмем из расчета 1000 QPS/CPU

БД Пиковый QPS CPU RAM Disk
Cassandra 88765.6 89 322.2 ТБ 4203.87 ТБ
Elasticsearch 9936.3 10 105.3 ТБ 787 ТБ
Redis 3212.1 4 195.24 ГБ 480.6 ГБ
ClickHouse 99 1 312 ГБ 37.44 ТБ

С учетом роста размера хранилища за год на 10.09 ПБ, получим прирост за год 10.09 / 69.37 = 0.145. Предположим, что такой темп роста сохранится, тогда за 5 лет каждая БД увеличится в (1 + 0.145)5 = 1.97 раз. Также нужно выбирать ресурсы с запасом в 40%, чтобы не возникало проблемных ситуаций.

Таким образом итоговая таблица БД выглядит как

БД Пиковый QPS CPU с запасом RAM с запасом Disk с запасом
Cassandra 174868.2 245 888.63 ТБ 11602.68 ТБ
Elasticsearch 19574.5 28 290.62 ТБ 2172.12 ТБ
Redis 6327.8 12 538.86 ГБ 1326.45 ГБ
ClickHouse 195.03 1 861.11 ГБ 103.33 ТБ

Для S3 получаем 65.66 ПБ * 1.97 * 1.4 = 181.1 ПБ

Рассчет ресурсов для ДЦ

В пункте 3 был проведен расчет рапсределения нагрузки по странам, приведем таблицу с распределением нагрузки по ДЦ:

Страна Количество ДЦ % общей нагрузки
США 7 7.19
Великобритания 1 9.93
Германия 1 7.64
Канада 1 6.9
Франция 1 6.84
Индия 1 5.18
Австралия 1 4.07
Бразилия 1 3.65

Сгруппируем страны по типу нагрузки для расчета определенных конфигураций для каждой группы:

Тип нагрузки на ДЦ % общей нагрузки на ДЦ Страны
Высокая ~10 Великобритания
Средняя 7-8 Германия, Канада, США
Средне-низкая 6-7 Франция, Индия
Низкая 4-5 Австралия, Бразилия

Таикм образом таблицы ресурсов для каждого типа нагрузки под k8s и БД примут вид

Высокая:

k8s:

Сервис CPU/r CPU/l RAM/r RAM/l
Поиск 14 28 1.4 ГБ 2.74 ГБ
Авторизация 3 6 0.14 ГБ 0.20 ГБ
Сообщества 2 2 0.01 ГБ 0.02 ГБ
Посты 7 14 0.42 ГБ 0.78 ГБ
Комментарии 5 8 0.14 ГБ 0.20 ГБ
Голоса 13 26 0.56 ГБ 1.18 ГБ
Пользователи 2 2 0.01 ГБ 0.02 ГБ
Сообщения 2 2 0.04 ГБ 0.08 ГБ
Рекомендации 28 55 27.86 ГБ 54.68 ГБ

БД:

БД Пиковый QPS CPU с запасом RAM с запасом Disk с запасом
Cassandra 17486.82 25 888.63 ТБ 11602.68 ТБ
Elasticsearch 1957.45 3 290.62 ТБ 2172.12 ТБ
Redis 632.78 2 538.86 ГБ 1326.45 ГБ
ClickHouse 19.5 1 861.11 ГБ 103.33 ТБ

Средняя:

k8s:

Сервис CPU/r CPU/l RAM/r RAM/l
Поиск 12 22 0.98 ГБ 1.96 ГБ
Авторизация 3 6 0.14 ГБ 0.20 ГБ
Сообщества 2 2 0.01 ГБ 0.02 ГБ
Посты 6 12 0.28 ГБ 0.59 ГБ
Комментарии 3 6 0.14 ГБ 0.20 ГБ
Голоса 10 20 0.42 ГБ 0.78 ГБ
Пользователи 2 2 0.01 ГБ 0.02 ГБ
Сообщения 2 2 0.03 ГБ 0.06 ГБ
Рекомендации 21 42 20.86 ГБ 40.96 ГБ

БД:

БД Пиковый QPS CPU с запасом RAM с запасом Disk с запасом
Cassandra 13115.12 20 888.63 ТБ 11602.68 ТБ
Elasticsearch 1468.09 3 290.62 ТБ 2172.12 ТБ
Redis 474.59 1 538.86 ГБ 1326.45 ГБ
ClickHouse 14.63 1 861.11 ГБ 103.33 ТБ

Средне-низкая:

k8s:

Сервис CPU/r CPU/l RAM/r RAM/l
Поиск 10 20 0.84 ГБ 1.57 ГБ
Авторизация 3 6 0.14 ГБ 0.20 ГБ
Сообщества 2 2 0.01 ГБ 0.02 ГБ
Посты 5 8 0.28 ГБ 0.59 ГБ
Комментарии 3 6 0.14 ГБ 0.20 ГБ
Голоса 9 16 0.28 ГБ 0.59 ГБ
Пользователи 2 2 0.01 ГБ 0.02 ГБ
Сообщения 2 2 0.03 ГБ 0.06 ГБ
Рекомендации 19 36 18.06 ГБ 35.48 ГБ

БД:

БД Пиковый QPS CPU с запасом RAM с запасом Disk с запасом
Cassandra 11366.43 17 888.63 ТБ 11602.68 ТБ
Elasticsearch 1272.34 2 290.62 ТБ 2172.12 ТБ
Redis 411.31 1 538.86 ГБ 1326.45 ГБ
ClickHouse 12.68 1 861.11 ГБ 103.33 ТБ

Низкая:

k8s:

Сервис CPU/r CPU/l RAM/r RAM/l
Поиск 7 14 0.70 ГБ 1.37 ГБ
Авторизация 2 2 0.14 ГБ 0.20 ГБ
Сообщества 2 2 0.01 ГБ 0.02 ГБ
Посты 3 6 0.14 ГБ 0.20 ГБ
Комментарии 2 2 0.14 ГБ 0.20 ГБ
Голоса 7 14 0.28 ГБ 0.59 ГБ
Пользователи 2 2 0.01 ГБ 0.02 ГБ
Сообщения 2 2 0.01 ГБ 0.02 ГБ
Рекомендации 13 26 12.46 ГБ 24.50 ГБ

БД:

БД Пиковый QPS CPU с запасом RAM с запасом Disk с запасом
Cassandra 7869.07 12 888.63 ТБ 11602.68 ТБ
Elasticsearch 881.85 2 290.62 ТБ 2172.12 ТБ
Redis 285.75 1 538.86 ГБ 1326.45 ГБ
ClickHouse 8.78 1 861.11 ГБ 103.33 ТБ

Спецификация серверов

Для всех типов нагрузки будем использовать одни и те же спецификации, отличия будут только в их количестве

Конфигурация серверов для k8s:

Node-pool Процессор CPU RAM Disk Аренда $/мес Покупка $
general-64G AMD EPYC 7452 32 64 GB 960 GB 168 5127 источник
memory-128G AMD EPYC 9535 64 128 GB 960 GB 450 13300 источник
Кластер БД Ключевые узловые ресурсы Покупка «на землю»
≈ стоимость комплекта
Типовой-«облачный» эквивалент Аренда / месяц
Cassandra 2 × Xeon 6-6980P, 4 ТБ DDR5, 12 ТБ CXL, 8 × 30,7 ТБ NVMe CPU $24,9 k (TechPowerUp) + DDR5 $37 k (ServerSupply.com) + CXL ≈ $120 k ((TechRadar)) + NVMe $35,9 k (Sabrent) + прочее $5 k ⇒ ≈ $223 k AWS u-18tb1.112xlarge (18 ТиБ RAM) ≈ $119,6 k / мес (Economize Cloud)
Elasticsearch 2 × EPYC 9754, 12 ТБ DDR5, 4 × 30,7 ТБ NVMe CPU $23,8 k (AMD) + DDR5 $110,9 k (ServerSupply.com) + NVMe $18 k (Sabrent) + прочее $5 k ⇒ ≈ $158 k AWS u-12tb1.112xlarge (12 ТиБ RAM) ≈ $79,7 k / мес (Vantage)
Redis Hi-Freq 1 × Xeon Gold 6448Y, 128 ГБ DDR5, 1,92 ТБ NVMe CPU $3,6 k (TechPowerUp) + DDR5 $1,2 k (ServerSupply.com) + NVMe $0,35 k (Sabrent) + прочее $2 k ⇒ ≈ $7 k Tier-Net «AMD Titanium Plus» (EPYC 9754 / 512 ГБ RAM)** $629 / мес (Tier)
ClickHouse 2 × EPYC 9354, 256 ГБ DDR5, 8 × 15,4 ТБ NVMe CPU $6,8 k (AMD) + DDR5 $2,3 k (ServerSupply.com) + NVMe $19,5 k (Sabrent) + прочее $5 k ⇒ ≈ $34 k AWS i4i.32xlarge (≈ 60 ТБ NVMe, 1 ТБ RAM) ≈ $8,0 k / мес (Economize Cloud)
Cassandra ES Redis ClickHouse
Купив железо (развёртывание on-prem) окупаемость против AWS (On-Demand) < 2 месяцев ≈ 2 мес > 9 лет ≈ 4 мес

Список использованных источников

Footnotes

  1. https://www.businessofapps.com/data/reddit-statistics/

  2. https://jobera.com/reddit-statistics/

  3. https://redditinc.com/press

  4. https://www.similarweb.com/website/reddit.com/

  5. https://www.businessdasher.com/how-many-subreddits-are-there/ 2 3

  6. https://www.demandsage.com/reddit-statistics/ 2

  7. https://www.statista.com/forecasts/1143622/reddit-users-in-the-world 2

  8. https://www.statista.com/forecasts/1309805/reddit-users-comments-votes

  9. https://www.semrush.com/website/reddit.com/overview/

  10. https://passport-photo.online/blog/reddit-statistics/

  11. https://worldpopulationreview.com/country-rankings/reddit-users-by-country 2 3

  12. https://nottio.com

  13. https://www.ibm.com/docs/en/cics-ts/6.x?topic=performance-ssl-handshake-overhead

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors