Расчетно-пояснительная записка к курсовой работе по дисциплине "Проектирование высоконагруженных систем" Образовательный центр VK x МГТУ им.Н.Э.Баумана (ex. "Технопарк")
7. Алгоритмы
8. Технологии
10. Схема проекта
11. Список серверов
Маркетплейс Ozon - платформа, на которой продавцы могут размещать свои товары для продажи, а покупатели — приобретать их. Маркетплейс имеет широкий ассортимент товаров и предлагают удобные условия для покупки.
- Регистрация и авторизация пользователей.
- Поиск товаров по ключевым словам.
- Просмотр информации о товарах, включая описание, характеристики, цены и отзывы.
- Комментарий приобретённых товарах.
- Добавление товара в корзину
- Редактирование списка в корзине товаров.
- Выбор пункта доставки
- Оформление заказа
- Выложить товар на продажу (продавец)
- Трэккинг посылок
Аудитория сайта достаточно широкая и разнообразная, но, преобладающее большинство мужчины. [1]
Размер целевой аудитории: 58.6 млн. пользователей в месяц, 21.0 млн. пользователей в день на момент февраля 2024г. [2]
Гендерное распределение

География аудитории иаркетплейс Ozon
Можно сделать следующие выводы:
- Преобладающее большинство пользователей мужчины
- Доминирующий возраст 25-34 года
- 95% пользователей из России
| Метрика | Значение |
|---|---|
| Месячная аудитория MAU | 58.6 млн. пользователей |
| Дневная аудитория DAU | 21.0 млн. пользователей |
| Количество регистраций в день [3] | 40 тыс. пользователей |
| Средняя длительность сессии [4] | 11 минут |
Так как общее количество заказов около 966 млн. [5] товаров, то можно вычислить сколько в среднем один пользователь делает заказов в день: (966 млн / 365 дней) / 21 млн = 0.13 заказа/день Так как общее число запросов на поисковая активность в месяц около 1,007 млрд. [6], то можно вычислить сколько в среднем один пользователь делает поисковых запросов в день: (1,007 млрд / 30 дней) / 21 млн = 1.6 запросов/день
| Параметр | Число |
|---|---|
| Поиск товаров по ключевым словам | 1.6 запросов/день |
| Просмотр информации о товарах | 12 [7] запросов/день |
| Оставление отзывов | 2 отзывов/день |
| Добавление товаров в корзину | 3.1 товаров/день |
| Редактирование списка в корзине товаров | 0.1 запросов/день |
| Выбор пункта доставки | 0.13 запрос/день |
| Оформление заказа | 0.13 заказов/день |
| Среднее количество товаров в заказе | 3 товаров |
| Добавление товаров продавцом | 0.5 товаров/день |
| Средний размер товара без учета фотографии | 6.3 кБ |
| Средний количество фотографий у товара | 7 шт. |
| Средний размер фотографии товара | 86 кБ |
| Открытие карточки товара | 10 товаров/день |
| Трэккинг посылок | 0.5 запросов/день |
Объём данных на одного пользователя в день:
- Добавление товаров в корзину: 3.1 товара * (6.3 кБ + 7 * 86 кБ) = 1885.7 кБ
- Оставление отзывов: 2 отзыва * (0.06 кБ + 3 * 86 кБ) = 467.72 кБ
- Оформление заказа: 3 товара * (6.3 кБ + 7 * 86 кБ) = 1824.9 кБ
- Трэккинг посылок: 0.5 запрос/день * (6.3 кБ + 86 кБ) = 46.15 кБ
- Открытие карточки товара: 10 товаров * (6.3 кБ + 17 отзывов * 0.06 кБ) = 10 товаров * 7.32 кБ = 73.2 кБ
Тогда общий объем товаров в день, добавляемых в корзину, оформленых в заказе, трэкинг посылок, на одного пользователя равен: 3.1 * (6.3 (кБ) + 7 * 86 (кБ)) + 2 * (0.06 (кБ) + 3 * 86 (кБ)) + 3 * (6.3 (кБ) + 7 * 86 (кБ)) + 0.5 * (6.3 (кБ) + 86 (кБ)) = 3756.8 кБ = 4.2МБ
Объём данных на одного продавца в день:
- Добавление товаров продавцом: 0.5 товаров/день * (6.3 кБ + 7 * 86 кБ) = 304.2 кБ
Так как общее количество заказов около 966 млн. товаров, то можно вычислить, какой объем данных будет занят пользователями:
- Расчёт данных на товары (всего): (6.3 (кБ) + 7 * 86 (кБ)) * 966 млн. = 587.62 ТБ
- Расчёт данных только на фотографии товаров: 7 * 86 (кБ) * 966 млн. = 581.53 ТБ
При расчете сетевого трафика не будем учитывать запросы, связанные с регистрацией пользователей, так как они не создают ощутимую нагрузку на наш сервис. Основная нагрузка приходится на оформление заказа, добавление в корзину, добавление товаров продавцом и трэкинг посылок.
- Поиск товаров:
- 1.6 запроса/день. Примерный объем одного запроса можно оценить в 10 кБ (запрос + ответ от сервера). Итого: 1.6 ∗ 10 кБ = 16 кБ
- Оставление отзывов:
- 2 отзыва/день, 467.72 кБ (как рассчитано ранее). Итого: 467.72 кБ
- Добавление товаров в корзину:
- 3.1 товара/день. Объем данных на один товар — 3.1 * (6.3 кБ + 7 фото * 86 кБ) = 1885.7 кБ (как уже рассчитано). Итого: 1885.7 кБ
- Оформление заказа:
- 0.13 заказ в день с 3 товарами. Итого: 3 товара * 0.13 * (6.3 кБ + 7 * 86 кБ) = 237.24 кБ. Итого: 237.24 кБ
- Трэккинг посылок:
- 0.5 запрос/день. Примерный объем одного запроса можно оценить в 10 кБ (запрос + ответ от сервера). Итого: 0.5 * 10 = 5 кБ
- Добавление товаров продавцом:
- 0.5 товаров/день. Примерный объем одного запроса можно оценить в 0.5 товаров/день * (6.3 кБ + 7 * 86 кБ) = 304.2 кБ. Итого: 304.2 кБ
- Трафик на одного пользователя в день:
- 16 кБ + 1885.7 кБ + 237.24 кБ + 5 кБ = 2143.9 кБ ≈ 2.1 МБ
- Открытие карточки товара:
- 10 товаров/день и 17 отзывов для каждого товара, 73.2 кБ (как рассчитано ранее). Итого: 73.2 кБ
Пиковое значение активности пользователей(соответственно RPS тоже) приблизительно в 3 раза выше среднего значения. Возьмем коэффициент запаса равный 4
| Тип | Отправка (дневная аудитория 21.0 млн ппокупателей и 400 тыс продавцов [6]) | Отправка Гб/сек | Пиковое значение | Значение с коэффициентом запаса 4 |
|---|---|---|---|---|
| Поиск товаров | 21.0 млн * 16 кБ = 336 ГБ | 0.0039 | 0.0117 | 0.0156 |
| Добавление товаров в корзину | 21.0 млн * 1885.7 кБ = 39 600 ГБ | 0.458 | 1.374 | 1.832 |
| Оставление отзывов | 21.0 млн * 467.72 кБ = 9 400 ГБ | 0.108 | 0.324 | 0.432 |
| Оформление заказа | 21.0 млн * 237.24 кБ = 4 982 ГБ | 0.058 | 0.174 | 0.232 |
| Трэккинг посылок | 21.0 млн * 5 кБ = 105 ГБ | 0.0012 | 0.0036 | 0.0048 |
| Добавление товаров продавцом | 0.4 млн * 304.2 кБ = 121.7 ГБ | 0.0014 | 0.0042 | 0.0056 |
| Открытие карточки товара | 21.0 млн * 73.2 кБ = 1 431,6 ГБ | 0.0017 | 0.0051 | 0.0068 |
| Итого | Покупатель: 45 023 ГБ ≈ 45 ТБ Продавец: 121.7 ГБ |
0.629 0.0014 |
1.89 0.0042 |
2.51 0.0056 |
- Регистрация и авторизация пользователей: 40 тыс / 86400 = 0.5 RPS
- Поиск товаров: 21.0 млн * 1.6 / 86400 = 388.9 RPS
- Просмотр информации о товарах: 21.0 млн * 12 / 86400 = 2 917 RPS
- Оставление отзывов: 21.0 млн. * 2 / 86400 = 486 RPS
- Добавление товаров в корзину: 21.0 млн * 3.1 / 86400 = 753.5 RPS
- Редактирование списка в корзине товаров: 21.0 млн * 0.1 / 86400 = 24.3 RPS
- Выбор пункта доставки: 21.0 млн * 0.13 / 86400 = 31.6 RPS
- Оформление заказов: 21.0 млн. * 0.13 / 86400 = 31.6 RPS
- Трэккинг посылок: 21.0 млн. * 0.5 / 86400 = 121.5 RPS
- Добавление товаров продавцом: 21.0 млн. * 0.5 / 86400 = 121.5 RPS
| Действие | RPS | Пиковое значение | Пиковое значение с коэффициентом запаса 4 |
|---|---|---|---|
| Регистрация и авторизация пользователей | 1 | 3 | 4 |
| Поиск товаров | 388.9 | 1 166.7 | 1 555.6 |
| Просмотр информации о товарах | 2 917 | 8 751 | 11 668 |
| Оставление отзывов | 486 | 1 458 | 1 944 |
| Добавление товаров в корзину | 753.5 | 2 260.5 | 3 014 |
| Редактирование списка в корзине товаров | 24.3 | 72.9 | 97.2 |
| Выбор пункта доставки | 31.6 | 94.8 | 126.4 |
| Оформление заказов | 31.6 | 94.8 | 126.4 |
| Трэкинг посылок | 121.5 | 364.5 | 486 |
| Добавление товаров продавцом | 121.5 | 364.5 | 486 |
| Итого | 4876 | 14 629 | 19 505 |
Будем считать, что домены по типу www.ozon.com работает на раздачу фронтенда, а бекенд распределён по поддоменам, которые будут рассмотрены далее.
- ozon.ru
Основной домен для российского сегмента Ozon, предоставляющий доступ к основному функционалу платформы.

- ozon.com
Домен для международной версии Ozon, ориентированной на аудиторию за пределами России.

- ozon.kz
Домен для казахстанского сегмента Ozon, адаптированный под особенности местного рынка.

- ozon.by
Домен для белорусского сегмента Ozon, адаптированный под потребности белорусского рынка.

Ozon работает в несккольких странах, поэтому ЦОДы не следует сосредотачивать в одной стране. Тем не менее, объём трафика из разных регионов сильно различается. Чтобы определить основных потребителей трафика, стоит обратиться с скриншотам выше. Большой объём трафика приходится на домен ozon.ru, это около 412.7 / (412.7 + 1.103 + 14.18 + 6.611) * 100% = 95%. Следовательно расположение ЦОДов будем определять преимущественно в России.
Таким образом получаем, что ЦОДы можно расположить в следующих локациях:
- Москва
- Санкт-Петербург
- Ростов-на-Дону
- Иркутск
Посмотреть на интерактивной карте: https://yandex.ru/maps/?um=constructor%3Ad1104bd74ccac98183303bb820f37407d2142a6cde52aefb09563453659e8e32&source=constructorLink Крат магистральных путей России: https://www.comnews.ru/content/211042/2020-10-21/2020-w43/magistralnye-seti-svyazi-rossii Карта население России: https://worldpopulationreview.com/countries/russia Список был составлен на основе не только основных потребителей трафика, но и основных точек присутствия провайдеров и подводных магистральных сетей. Нужно понимать, что разные сервера могут держать на себе различные сервисы. Так, список выше подходит для размещения серверов с основной логикой платформы; для CDN же этот список стоит значительно расширить, но в рамках работы будем считать, что CDN расположены там же. Таким образом, при таком списке мы получим снижение латентности и улучшим доступность платформы.
Так как сервис находится преимущественно в рамках одной страны, то в качетсве балансировки будет использоваться роутинг. За счёт географических масштабов проекта здесь будет применяться GeoDNS В итоге, клиентский трафик заводится в 4 ЦОД через BGP Anycast. Далее посредством Equal-cost multi-path routing (ECMP) попадает на несколько LoadBalancer c защитой от DNS- и DoS-атак. ECMP роутинг может использоваться в сочетании с BGP, использования этой стратегии маршрутизации, при которой пакеты пересылаются по нескольким «лучшим путям», увеличивает пропускную способность сети.
Рассмотрим настоящую архитектуру Ozon [13]:
Согласно докладу разработчиков из Ozon, их система балансировки нагрузки устроена следующим образом:
- Уровень GeoDNS-балансировки - используется для распределения трафика между несколькими дата-центрами
- Уровень L4-балансировки - используется внутри каждого дата-центра для распределения трафика между серверами. Основано на использовании программных балансировщиков на базе NGINX.
- Уровень L7-балансировки - применяется для распределения трафика между различными сервисами внутри Ozon. Реализовано на базе программных балансировщиков NGINX. Для системы, в которой все построенно на микросервисах, такой подход более чем оправдан. В итоге получается такая схема работы:
Рассмотрим несколько балансировок [14]
- DNS-балансировка: имеет низкую нагрузку на сеть, но не подходит из-за высокой вероятности длительных соединений и необходимости быстрой реакции на изменения в инфраструктуре
- L4-балансировка: может использоваться для базовой балансировки, но не подходит для сложных сценариев, так как имеет ограниченные возможности по управлению сессиями, также нет поддержки сложных протоколов
- L7-балансировка: наиболее подходящий вариант для маркетплейма Ozon. Позволяет эффективно распределять нагрузку, управлять сессиями пользователей, оптимизировать трафик и реализовать дополнительные функциональные возможности, однако из минусов есть высокая сложность настройки и потенциально более низкая производительность.
На уровне локальной балансировки будем использовать только L7 балансировку. В архитектуре не будет использоваться L4, так как в данном сценарии этот уровень избыточен. L7 балансировку будем использовать два веб-сервера Nginx для отказоустойчивости (паттерн Active-Passive).
Вывод: L7-балансировка. Для Ozon, как крупного маркетплейса с высокой нагрузкой и сложной архитектурой приложения, наиболее подходящим вариантом будет L7-балансировка. Она предоставляет необходимую гибкость, возможность учета особенностей приложения и реализации сложных сценариев маршрутизации трафика. L7-балансировщик позволяет привязывать пользователя к определенному серверу, обеспечивая более стабильное соединение и упрощая обработку контекста пользователя. Также часто используемые данные могут быть кэшированы на уровне балансировщика, что снижает нагрузку на бэкенд-серверы и ускоряет ответ. К тому же L7 балансировщики хорошо интегрируются с Kubernetes.
Методы балансировки нагрузки [15]
Популярные алгоритмы распределения трафика:
Выбор: Round Robin. Так как это простой и легковесный алгоритм + легко масштабируется.
Существует довольно много методов балансировки. Nginx по умолчанию использует алгоритм Round Robin. Он довольно прост. Допустим, у нас есть приложения 1, 2 и 3. Балансировщик нагрузки отправит первый запрос на первое приложение, потом на второе, на третье и опять на первое
| 1 запрос | 2 запрос | 3 запрос | 4 запрос |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Чтобы избежать простоя серверов, можно использовать некоторый числовой приоритет. У каждого сервера появляется свой вес, который определяет, как много трафика распределяется на конкретный экземпляр приложения. Таким образом мы гарантируем, что более мощные серверы получат больше трафика.
Для отказоустойчивости будут применяться инструменты k8s и nginx. Kubernetes с помощью readiness-проб обеспечит исключение из кластера упавших подов и добавление новых, а также сможет автоматически поднимать упавшие сервера. Если предположить, что ЦОДы будут не нашими, а арендованными, то kubernetes также позволит выполнять удобный auto-scaling, чтобы подстраиваться под актуальную нагрузку. Nginx умеет выполнять retry запросов после падения бэкенда, перезапускать web-сервера без downtime (хотя при использовании k8s это избыточно), равномерно распределять запросы по бэкендам, а также незаметно для пользователя перезагружать конфиг при обновлениях.
Нагрузка по терминации SSL [16]
На современных серверах ssl handshake может занимать от 2 мс при сокращённом рукопожатии до 20 мс при полном рукопожатии 13, при этом это время полного ответа, в то время как сами вычисления на процессоре занимают 0.5 - 0.6 мс. При последующих расчётах будем считать, что ssl handshake занимает 3 мс, т.к. мы будет использовать сокращённые рукопожатия в nginx, то есть сервер и клиент будут согласны на переиспользование защищённой сессии, которую использовали ранее (session tickets).
В таком случае, исходя из пикового RPS по всем основным ручкам (4390 RPS) получаем, что на обработку SSL каждую секунду потребуется 4390 * 3 = 13 170 мс = 13 секунд вычислительного времени.
Вы можете перейти по ссылке чтобы подробнее изучить схему бд: https://drawsql.app/teams/sergey-20/diagrams/highload-ozon-db
| Type | Byte size |
|---|---|
| UUID | 16 |
| INT | 4 |
| SMALLINT | 2 |
| TIMESTAMP | 4 |
| DECIMAL | 17 |
| TEXT | [0, 65 535] |
| BOOLEAN | 1 |
Profile
id(16) + name(32) + surname(64) + photo_profile(64) + phone_number(19) + email(32) + gender(2) + date_of_birth(4) + password_hash(64) + creating(4) + seller(1) + creating_seller(4) = 306
Session
token(32) + profile_id(16) + creating(4) + last_access(4) + user_agent(16) + ip_address(4)= 76
Seller_Product
id(16) + profile_id(16) + product_id(16) + creating(4) = 52
Rating_Seller
id(16) + profile_sender(16) + profile_recipient(16) + rating(2) = 50
Comment
id(16) + profile_id(16) + product_id(16) + comment(256) + rating(2) + photo(64) + creating(4) = 374
id(16) + profile_id(16) + product_id(16) + comment(0) + rating(2) + photo(0) + creating(4)= 54
Product
id(16) + title(128) + description(1024) + producr_size(4) + amount(4) + price(17) + imgsrc(16) + category(32) + creating(4) + rating_number(4) + rating_sum(4) = 1 253
Elastic_Search
id(16) + product_id(16) + title(128) + description(1024) + category(32) = 1 216
File_Product
id(16) + product_id(16) + imgsrc(64) + creating(4) = 100
Shopping_Cart
id(16) + profile_id(16) + product_id(16) + creating(4) = 52
Order_Item
id(16) + profile_id(16) + track_id(16) + creating(4) + product_id(16) + cost(17) + status(1)= 86
Tracking
id(16) + track_number(64) + date_start(8) + date_finish(8) + price(10) + quantity(4) + address(16) + status(256) + creating(8) = 390
List_Pick-up
id(16) + city(16) + street(16) + house(16) + creating(4) = 68
- Количество уникальных пользователей около 100 млн. [17]
- Количество товаров около 250 млн [18]
- Общее число количества заказов на Ozon составляет около 32 + 74 + 223,3 + 465,4 + 965,7 + 1217,5 = 3 млрд [19]
- Согласно источникам [19] около 15% молча поставят оценку, 9% всегда пишут отзывы с целью помочь другим а 6% еще и фотографией поделятся. Будем считать что 7% пишут отзыв с фотографией.
- Так как в год заказывают около 966 млн. товаров, то в месяц заказывают около 80.5 млн. (комментарий к товару может оставить только заказчик)
- Так как в среднем на добавление товара продавцом выходит 0.5 RPS то в месяц выкладывается около 0.5 * 60 * 60 * 24 * 30 = 1.3 млн. товаров
- В ozon насчитывается 24 товарных раздела [20]
- Товар в корзине на Ozon хранится 30 дней. После этого срока товар пропадёт из корзины. [21]. Будем считать что товар хранится в корзине 14 дней
- В среднем доставка заказа со склада Ozon занимает до 4 рабочих дней.
- По данным на конец первого квартала 2024 года, в России было 16 тысяч пунктов выдачи заказов и постаматов, брендированных Ozon.[22]
| Table | Row size [byte] | Number of row | Total |
|---|---|---|---|
| Profile | 306 | 100 * 10^6 | 28.5 Гб |
| Session | 76 | 56 * 10^6 | 4 Гб |
| Seller_Product | 52 | 250 * 10^6 | 12.1 Гб |
| Rating_Seller | 50 | 50 * 10^6 | 2.3 Гб |
| Comment | 374; 54 | 3 * 10^9 * 0,07; 3 * 10^9 * 0,15 | 73.2 Гб; 22.6 Гб |
| Product | 1253 | 250 * 10^6 | 291.7 Гб |
| Elastic_Search | 1216 | 250 * 10^6 | 283.1 Гб |
| File_Product | 100 | 250 * 10^6 * 7 | 163 Гб |
| Shopping_Cart | 52 | 3.1 * 21 * 10^6 (DAU) * 14 | 44.1 Гб |
| Order_Item | 86 | 3 * 10^9 | 240.3 Гб |
| Tracking | 390 | 966 * 10^6 / 365 * 4 дня | 3.9 Гб |
| List_Pick-up | 68 | 16 000 | 1.04 Mб |
Всего занятой памяти 1,14 Тб
Для хранения данных будем использовать 4 базы данных
- Redis. Redis подходит для хранения сессий благодаря in-memory хранению данных и высокой производительности при работе с временными данными (TTL). Также есть поддержка организации кластера Redis cluster и неблокирующей репликации master-slave.
- MongoDB. MongoDB используется для хранения JSON-документов в “коллекциях” и осуществления запросов по нужным полям. Эта база данных отлично подходит для создания приложений, в которых не будет содержаться слишком много количества связей. Кроме того эта СУБД отлично масштабируется, и по сравнению с традиционными SQL-системами, гораздо быстрее осуществляет чтение и запись
- Elasticsearch. Для полнотекстового поиска по товарам используем Elasticsearch. Он поддерживает высокоэффективный поиск по ключевым словам и легко интегрируется с системой благодаря API.
- AWS S3. Хранение больших файлов (фотографий и других медиа) будет производиться в облачном хранилище. AWS S3 предоставляет высокую доступность, репликацию данных и простое управление большими объемами файлов.
| Таблица | Технология |
|---|---|
| Session | Redis |
| Profile, Session, Seller_Product, Rating_Seller, Comment, Product, Shopping_Cart, Order_Item, Tracking, List_Pick-up, Profile_Comment_Shard | MongoDB |
| Elastic_Search | Elasticsearch |
| File_Product | AWS S3 |
Добавим индексы на часто используемые поля:
| Таблица | Индексы | Описание |
|---|---|---|
| Profile | id phone_number |
ускорить поиск пользователей по id ускорить поиск пользователей по номеру телефона ускорить поиск пользователей по номеру адресу электронной почты |
| Session | token profile_id last_access |
так как оно является основным для идентификации сессии для быстрого доступа к профилю пользователя для удаления или поиска неактивных сессий |
| Seller_Product | profile_id product_id |
для быстрого доступа к профилю продавца для быстрого доступа ко всем товарам продавца |
| Profile_To_Profile | profile_recipient | для быстрого получения всесх id пользователей, которые оценили продавца |
| Rating_Seller | profile_id | для быстрого получения рейтинга продавца |
| Comment | product_id profile_id |
для получения всех комментариев к продукту. для отслеживания комментариев от конкретного пользователя В таблице Profile_Comment_Shard будут лежать profile_id и номера шардов, в которых лежат комментарии данного пользователя. Это может с оптимизировать запросы. |
| Product | id | для поиска товаров по идентификатору |
| Elastic_Search | title description category |
для быстрого полнотекстового поиска по товарам |
| Rating_Product | profile_id | для быстрого получения рейтинга товара |
| File_Product | imgsrc | для быстрого доступа к файлам по их ссылкам |
| Shopping_Cart | profile_id | для поиска всех товаров в корзине пользователя |
| Order_Item | profile_id track_number |
для поиска всех заказов пользователя для поиска заказа по трэк номеру |
| List_Pick-up | city street |
для ускорения по местоположению |
Шардирование позволит распределить нагрузку на базу данных, избегая узких мест и повышения отказоустойчивости:
- MongoDB [23]:
- Шардирование по товарам (Product, Comment): Шардирование по product_id. Это позволит распределить нагрузку, так как данные товаров (включая продавцов и отзывы) часто запрашиваются вместе.
- Шардирование заказов (Order_Item): Шардирование по profile_id, чтобы распределить нагрузку между пользователями. История заказов обычно запрашивается индивидуально.
- Репликация: Для MongoDB имеет смысл настроить мастер-репликацию для обработки запросов. Все операции записи, удаления, обновления, попадают в мастер (primary), а затем записываются в специальную коллекцию oplog, откуда асинхронно попадают на реплики — repl.1 и repl.2 (secondary). Таким образом происходит дублирование данных. Зачем это нужно?
- Избыточность обеспечивает безопасность данных
- Мастер и реплики могут располагаться в разных дата центрах
- Реплики могут использоваться для более эффективного чтения данных
2) Redis [24]:
- Elasticsearch [25]:
- Шардирование: Elasticsearch поддерживает внутреннее шардирование, которое можно настроить на уровне конфигурации. Рекомендуется шардировать по ключевым полям поиска (например, по title).

- MongoDB: Для работы с MongoDB в Go часто используют следующие библиотеки:
- Go MongoDB Driver: Официальный драйвер MongoDB для Golang.
- Mgo: Это неофициальная библиотека, которую также часто используют, хотя развитие остановилось в 2018 году.
- Redis: Для интеграции с Redis в Go можно использовать следующие библиотеки:
- go-redis: Самая популярная библиотека для работы с Redis в Go. Поддерживает основные команды Redis, работу с кластерами и транзакциями.
- Elasticsearch: Для работы с Elasticsearch в Go можно использовать клиентскую библиотеку, разработанную самими разработчиками Elasticsearch:
- Elastic Go Client: Официальный клиент для работы с Elasticsearch, поддерживает все основные функции Elasticsearch.
- AWS S3: Для работы с AWS S3 можно использовать официальный SDK от AWS для Go:
- AWS SDK for Go: Поддерживает работу с S3 и другими сервисами AWS.
- MongoDB [26]:
- Использование mongodump для регулярного создания бэкапов базы данных. Бэкапы сохраняются на удаленный сервер или в облачное хранилище (например, S3). Будем производить резервное копирование всех баз данных с сжатием в один архив(.gz)
mongodump --gzip --archive=/tmp/backup/mybackup.gz
- Redis [27]:
- Redis поддерживает сохранение снимков данных через RDB (Redis Database Backup) и AOF (Append Only File). RDB можно использовать для периодических полных бэкапов, а AOF для сохранения журнала операций.
- Elasticsearch [28]:
- Использование встроенной системы снапшотов Elastic для регулярных бэкапов данных в удаленное хранилище (например, S3).
- AWS S3: Файлы на S3 защищены встроенной системой версионирования и высокой доступностью. Рекомендуется использовать Glacier для долгосрочного хранения архивных данных.
Давайте разработаем алгоритм для поиска товара на маркетплейсе Ozon, аналогичный тому, который описан для Wildberries, но с возможными дополнениями и уточнениями для улучшения результатов поиска.
На этом этапе осуществляется поиск всех потенциально релевантных товаров по запросу пользователя. Используем технологии как ElasticSearch для быстрого и точного поиска.
Вначале тело каждого запроса обрабатывается. Из него достаются ключевые слова, по которым в дальнейшем будет происходить обращение в кэш и ElasticSearch.
Перед тем как попасть в главный поиск по ключевым словам и метрикам, все запросы обращаются в Redis. Для быстрого ответа, если в кэше есть подходящее для нас значение.
ElasticSearch не обладает встроенным механизмом индексации. Одним из ключевых вызовов является обеспечение трансляции обновлений к поисковому индексу в режиме реального времени. Такие элементы, как цены, ассортимент, наличие товаров на складах и обзоры часто меняются, создавая таким образом массивный приток обновленных записей. Чтобы применить эти обновления в ES, используется инструмент App Indexer. Когда объём индекса достигает определённого предела, App Indexer инициирует процесс его дистрибуции по ES кластеру, используя протокол Peer2Peer. Использование P2P гарантирует, что сетевой канал не будет перегружен, что позволит другим важным бизнес-сервисам работать без сбоев.
- Все товары индексируются в ElasticSearch (таблица Elastic_Search) по ключевым полям: title, description и category.
- Преобразование поискового запроса в JSON-формат и отправка его в ElasticSearch.
- ElasticSearch осуществляет поиск по точным и частичным совпадениям, а также по синонимам и родственным терминам через механизмы, такие как Synonym Filter.
- Возвращает неупорядоченный список товаров, подходящих под запрос.
- ElasticSearch использует BM25 для оценки релевантности каждого товара по тексту запроса.
- Учёт предпочтений пользователя и его истории покупок (таблица Order_Item) для предлагаемой персонализации результатов.
Добавим в нашу схему кластер ClickHouse, в котором будут храниться метрики пользователя:
- какие поисковые запросы он делал за последнее время
- какие страницы товаров посещал
- какие товары откладывал в козину
- какие товары заказывал
На основе этих данных обучается модель StatisticML. В данную модель передаются данные, которые были получены из ElasticSearch. А на выходе получаем полностью упорядоченный по релевантности список товаров.
Алгоритм поиска товаров на маркетплейсе Ozon основан на комбинации текстового и семантического поиска с использованием ElasticSearch, а также последующего ранжирования с учетом релевантности и персонализации.
| Технология | Область применения | Обоснование |
|---|---|---|
| Golang | Бэкенд | Современный высокопроизводительный язык программирования, который подходит для создания микросервисов для крупномасштабных приложений. Golang предлагает первоклассную поддержку параллелизма через свои goroutines и каналы. Язык разработан с учётом простоты, что обеспечивает лёгкость понимания и сопровождения кода. |
| Typescript | Фронтенд | TypeScript эффективен, если у проекта масштабная кодовая база, он сложный и требующий многочисленной команды разработчиков. Статическая типизация в TypeScript позволяет обнаруживать ошибки на ранних этапах разработки. |
| Kotlin | Мобильное приложение Android | Является статически типизированным языком программирования, работающим поверх JVM. В нём многие общепринятые ошибки, такие как null-pointer exceptions, устранены на уровне компиляции, что делает код более безопасным. Kotlin также поддерживает функциональное программирование и обладает мощным механизмом типов. |
| Swift | Мобильное приложение iOS | Является мощным и интуитивно понятным языком программирования от Apple, который предлагает современные функции, безопасность и производительность. Он объединяет простоту синтаксиса и доступность, что делает его идеальным для новичков, и предлагает глубокие функциональные возможности, которые привлекают профессиональных разработчиков. |
| Python | Машинное обучение | Благодаря интуитивно понятному синтаксису и гибкости, он идеально подходит для работы с данными и создания сложных моделей машинного обучения. Богатый набор библиотек, таких как NumPy, Pandas, Scikit-learn и TensorFlow, делает процесс подготовки данных, построения и тестирования моделей более эффективным и удобным. |
| Технология | Область применения | Обоснование |
|---|---|---|
| Redis | Кэширование | Высокопроизводительная, распределённая, в оперативной памяти, хранилище структурированных данных, обладающее расширенным набором возможностей. Он поддерживает разные типы структур данных, таких как строки, списки, множества, отображения и т.д., позволяя разработчикам быть гибкими в хранении и обработке данных. Redis предлагает возможность репликации, ведения журнала транзакций, автоматической вставки и удаления по ключу TTL (Time To Live) и поддерживает богатые атомарные операции. Кроме того, Redis отличается высокой производительностью и минимальной задержкой. |
| MongoDB | Основная база данных | Полноценная NoSQL база данных, сочетающая в себе масштабируемость, гибкость и производительность при работе с большими объемами данных. MongoDB представляет данные в виде гибких документов типа BSON (похожие на JSON). Имеет возможности индексации, шардирования и репликации данных. MongoDB идеально подходит для ситуаций, когда необходимо обрабатывать большие объемы неструктурированных данных, а также для быстрого развития и итерации ваших продуктов благодаря гибкой схеме документов. |
| ElasticSearch | Поисковый движок | Распределенная система поиска и анализа данных в реальном времени. Она обеспечивает масштабируемость, скорость и тонкую настройку поисковых запросов. Elasticsearch позволяет индексировать большие объемы данных и анализировать их в любой требуемой структуре благодаря базовой модели, основанной на JSON-документах. Быстрый и мощный поиск, поддержка многоязычности, геопространственный поиск и возможность применения множества фильтров органично дополняют широкий функционал Elasticsearch. |
| Clickhouse | OLAP-хранилище | Высокопроизводительная столбцово-ориентированная СУБД для аналитических запросов в режиме реального времени. Благодаря уникальной архитектуре, ClickHouse может обрабатывать большие объемы данных на порядки быстрее традиционных систем, предлагая миллионы вставок в секунду и обеспечивая моментальные отчеты с агрегациями. ClickHouse поддерживает SQL-синтаксис и широкий спектр функций, включая JOINы, подзапросы в секции FROM и IN-операторах. Также осуществляет сжатие данных, управление репликацией для обеспечения отказоустойчивости, а также параллелизм и распределенные запросы. |
| AWS S3 | Хранилище файлов и резервное копирование | Облачное хранилище для долговременного хранения и резервного копирования данных. Предлагает высокий уровень доступности и надежности, автоматическую репликацию и интеграцию с другими сервисами AWS. |
| InfluxDB | Хранилище логов и временных рядов | СУБД для временных рядов, используемая для хранения и анализа метрик и логов. Оптимизирована для обработки данных в реальном времени, позволяет анализировать тенденции и обнаруживать аномалии. |
| Технология | Область применения | Обоснование |
|---|---|---|
| React | Фронтенд | Библиотека для построения пользовательских интерфейсов с высокими требованиями к скорости и отзывчивости. Подходит для SPA, поддерживает компоненты, переиспользование кода и эффективный рендеринг благодаря Virtual DOM, что повышает производительность и гибкость в разработке. |
| PyTorch | Обучение и разметка моделей | Открытая библиотека машинного обучения, разработанная Facebook, которая предоставляет гибкий и интуитивный интерфейс для проектирования и обучения нейронных сетей. Один из основных плюсов PyTorch - динамический граф вычислений, который позволяет легко изменять и оптимизировать модели "на лету", что особенно важно при научных исследованиях |
| NLTK, TextBlob | Обработка текста (NLP) | NLTK (Natural Language Toolkit) и TextBlob - это две ключевые библиотеки Python для обработки текста, неотъемлемые для машинного обучения. NLTK включает в себя много функций для анализа текстов, таких как токенизация, стемминг, тегирование частей речи и синтаксический анализ. Он также предлагает большие корпусы текстов и лексических ресурсов |
| Pandas | Работа с данными пользователей | Библиотека Python, предоставляющая средства для манипулирования и анализа данных. Ее особенности включают гибкие структуры данных (DataFrame и Series), которые позволяют эффективно работать с различными типами данных, включая пропущенные. Библиотека поддерживает разнообразные операции над данными: фильтрацию, группировку, сортировку, соединение и многие другие. Pandas также предоставляет инструменты для чтения и записи данных в различных форматах (CSV, Excel, SQL и др.) и интегрируется с библиотеками для визуализации данных, такими как Matplotlib |
| Go-image | Обработка изображений | Библиотека Golang, предназначенная для работы с изображениями. Golang поддерживает широкий спектр форматов изображений и обеспечивает мощный набор функций для манипуляций с изображениями, таких как различные операции обрезки, поворота, изменения размеров, фильтрации и цветовой коррекции. Библиотека позволяет также выполнять более сложные задачи, такие как добавление текста на изображения, получение и установка отдельных пикселей и рисование простых форм. |
| Numpy | Математические вычисления | Используются для линейной алгебры, вычисления расстояний и обработки массивов данных, что важно для векторного поиска и обработки текстовых запросов. |
| Технология | Область применения | Обоснование |
|---|---|---|
| Prometheus | Сбор метрик | Высокоэффективная открытая система мониторинга и алертинга, специально разработанная для обработки метрик временных рядов. Она предлагает мощный и гибкий механизм запросов на основе своего языка PromQL, позволяющего пользователям агрегировать и отображать уникальные паттерны данных. Он также интегрируется с большинством популярных систем визуализации данных, таких как Grafana, предоставляя детальные визуальные отчеты. |
| Grafana | Визуализация метрик, мониторинг | Mощный инструмент для визуализации и анализа метрик, который поддерживает широкий спектр источников данных, включая, но не ограничиваясь, системами мониторинга Prometheus, InfluxDB и Elasticsearch. Он предлагает гибкую и богатую систему настройки графиков, панелей и алертов, что позволяет каждому пользователю создавать уникальные и персонализированные картины данных. |
| Docker | Среда выполнения контейнеров | Инструмент для создания, развертывания и управления контейнерами, которые позволяют упаковать приложение вместе со всеми его зависимостями в стандартизированную единицу для разработки. Docker обеспечивает изоляцию приложения, что упрощает тестирование и снижает конфликты среды. Он обладает высокой мобильностью, упрощает процесс поставки, сокращает время развертывания и обеспечивает непрерывную интеграцию/развертывание. |
| Kubernetes | Оркестрация и развертывание контейнеров | Мощная и гибкая открытая система для автоматизации развертывания, масштабирования и управления контейнеризированными приложениями. Он предлагает обширный набор функций для оркестрации, включая self-healing, автоматическое масштабирование, управление секретами и конфигурациями, обновления с минимальной остановкой и многопользовательские возможности. Kubernetes может успешно работать как в облаке, так и на премиссах, экономя ресурсы и упрощая операции. |
| Nginx | Балансировщик нагрузки уровня L7 | Бесплатный веб-сервер, который обеспечивает высокую производительность, стабильность, богатые возможности и низкое потребление ресурсов. Он функционирует и как обратный прокси, и как почтовый прокси, балансировщик нагрузки, и может обслужить статические файлы, поддерживать SSL и TLS, а также многое другое. Благодаря асинхронной архитектуре сервера, Nginx способен поддерживать огромное количество одновременных подключений |
| Apache Kafka | Брокер сообщений | Масштабируемая и гибкая система обработки потоковых данных в реальном времени, идеально подходящая для работы с большими объемами информации. Kafka обеспечивает надежное хранение и обмен сообщениями между приложениями с высокой пропускной способностью и низкой задержкой, основываясь на модели публикации/подписки. Система обладает пропускной способностью в миллионы сообщений в секунду, с отказоустойчивостью и долговечным хранением данных. |
| Vault | Хранилище секретов | Безопасное, надежное и гибкое решение для централизованного управления секретами и привилегиями доступа, включая пароли, API-ключи, токены, сертификаты и другие средства идентификации. Vault обеспечивает шифрование данных "в покое" и "в движении", поддерживает гибкие политики доступа и уровни контроля над секретами. Vault также предлагает службы динамического предоставления учетных данных. |
| GitHab | Система контроля версий, CI/CD | Ведущий веб-сервис для хостинга и коллаборации в разработке программного обеспечения. Он предлагает инструменты для хранения, версионирования и совместной работы над кодом, с использованием системы контроля версий Git. Удобные функции, такие как pull request, issue tracking и встроенная функциональность CI/CD. |
| Linkerd | Сервисная mesh-сеть | Открытый сервисный меш, предназначенный для обеспечения отказоустойчивости и надёжности приложений при использовании микросервисной архитектуры. Он предоставляет возможность управления трафиком, шифрования передачи данных, сбора метрик и обработки ошибок на сетевом уровне, без необходимости включения этих функций в само приложение. |
| CDN Cloudflare | Доставка статического контента | Глобально установленная сеть, которая обеспечивает быструю доставку веб-контента посетителям сайта, используя ближайший к ним сервер. Cloudflare улучшает производительность веб-сайтов, уменьшает временные задержки загрузки страниц и снижает нагрузку на исходный сервер. Кроме того, он обеспечивает ряд функций безопасности, включая защиту от DDoS-атак, фильтрацию спама и защиту от SQL-инъекций |
| Технология | Область применения | Обоснование |
|---|---|---|
| BM25 | Ранжирование в поиске | Алгоритм ранжирования, используемый в системах поиска информации для упорядочивания документов по их релевантности поисковому запросу. Основными преимуществами BM25 являются его способность адаптироваться к различным длинам документов и его учет частоты встречаемости терминов |
| XGBoost | Персонализация и ранжирование | Алгоритм машинного обучения, основанный на градиентном бустинге деревьев решений. Он имеет ряд ключевых преимуществ: высокая производительность, точность, скорость и эффективность. |
| Компонент | Способ обеспечения надежности |
|---|---|
| Nginx | Для обеспечения отказоустойчивости и минимизации сбоев, Nginx можно развернуть в виде 2 экземпляров (паттерн Active-Passive). В случае отказа одного узла, другой инстанс Nginx подхватит обслуживание трафика. Отправить сигнал SIGQUIT в основной процесс Nginx. Этот сигнал приведёт к "мягкому" завершению работы - никакие новые запросы не будут приняты, но все текущие запросы будут обработаны до конца. Команда: nginx -s quit После того как все активные соединения завершатся, основной процесс Nginx остановится. |
| MongoDB | Для MongoDB имеет смысл настроить мастер-репликацию для обработки запросов. Все операции записи, удаления, обновления, попадают в мастер (primary), а затем записываются в специальную коллекцию oplog, откуда асинхронно попадают на реплики. Использование MongoDump для регулярного создания бэкапов базы данных. Бэкапы сохраняются на удаленный сервер или в облачное хранилище (например, S3). Будем производить резервное копирование всех баз данных с сжатием в один архив(.gz) mongodump --gzip --archive=/tmp/backup/mybackup.gz Graceful Shutdown [29]2. Используйте команду use admin db.shutdownServer() Системы с использованием systemd: sudo systemctl stop mongod Системы с использованием SysV Init: sudo service mongod stop |
| Redis | Redis поддерживает репликацию master-slave и может использовать Redis Sentinel для автоматического обнаружения сбоев. Sentinel также управляет failover-процессом, что позволяет переключаться на резервный инстанс Redis при отказе master Redis поддерживает сохранение снимков данных через RDB (Redis Database Backup) и AOF (Append Only File). RDB можно использовать для периодических полных бэкапов, а AOF для сохранения журнала операций. Это не гарантирует полное сохранение всех данных, но обеспечивает высокую производительность. Если полетит база с горячими данными (а именно для этого и нужен redis), то master MongoDB поляжет под кучей запросов. Поэтому если даже redis'у станет плохо, то мы сможем восстановить данные путём резервирования Graceful Shutdown [30]1. Персистентность на диск: если включено RDB или AOF, Redis убедится, что данные были полностью записаны на диск. В случае с AOF, Redis перезапишет AOF файл, чтобы минимизировать размер файла и упростить его последующую загрузку. Завершение клиентских соединений: Redis отключит все клиентские соединения перед полной остановкой. Можно использовать следующую команду: redis-cli shutdown |
| ElasticSearch | ElasticSearch позволяет создавать несколько копий ваших данных, называемых реплицируемыми сегментами, которые могут быть распределены по разным узлам. По умолчанию Elasticsearch создает одну реплику для каждого основного сегмента. Использование встроенной системы снапшотов Elastic для регулярных бэкапов данных в удаленное хранилище (например, S3). Graceful Shutdown [31]curl -XPUT localhost:9200/_cluster/settings -d '{"transient" :{"cluster.routing.allocation.exclude._ip" : "10.0.0.1"} }';echo |
| AWS S3 | CloudFront origin [32] |
| ClickHouse | Репликация работает в рамках одного шарда на уровне таблиц, которые были созданы используя семейства движков ReplicatedMergeTree. На каждом шарде, репликация работает независимо от других шардов. Graceful Shutdown [33]sudo systemctl stop clickhouse-server Эта команда приказывает следить за активными чтениями и записями и завершить их перед выключением сервера. Однако, прежде чем остановить сервер, ClickHouse ожидает завершения задач на чтение или запись в течение максимум 10 минут по умолчанию 2. Если по каким-то причинам не удается остановить службу, можно отправить сигнал SIGTERM на процесс ClickHouse ```kill -SIGTERM `pidof clickhouse-server```` Этот сигнал будет корректно обработан ClickHouse и процесс остановится после завершения всех активных задач. |
| InfluxDB | Master-Master [34]sudo systemctl stop influxdb |
| Kafka | Kafka развернута в кластере с несколькими брокерами, что обеспечивает устойчивость при сбоях отдельных узлов Каждый топик может иметь несколько реплик, что позволяет восстановить сообщения при сбое одного брокера. В случае недоступности ClickHouse или InfluxDB, Kafka продолжит накапливать данные в топиках и передаст их после восстановления компонентов. Graceful Shutdown [35]systemctl stop confluent-kafka Так же можно использовать сценарий инициализации для управления брокером Apache Kafka: /etc/init.d/kafka stop |
| Kubernetes | Kubernetes поддерживает авто-восстановление подов при сбоях, перезапуская сервисы на доступных узлах. Horizontal Pod Autoscaling обеспечивает автоматическое масштабирование в зависимости от нагрузки. Системы хранения Kubernetes, такие как ETCD, поддерживают регулярные резервные копии, что позволяет восстановить конфигурации при сбоях. Graceful Shutdown [36]2. После ожидания определенного периода времени, который называется termination grace period (по умолчанию, это 30 секунд), Kubernetes отправит сигнал SIGKILL, убивая контейнер, не дожидаясь окончания обслуживания всех текущих соединений. 3.Если контейнер не отвечает после периода grace period, Kubernetes использует сигнал SIGKILL для немедленного прекращения работы контейнера. |
| DNS | DNS с циклическим обслуживанием. Для её реализации все данные исходного сервера копируют на несколько серверов и ставят их IP-адреса в соответствие одному имени хоста. Тогда DNS будет обрабатывать все IP-адреса последовательно. |
| Service Discovery | Так как Service Discovery это по большей части stateless сервер, то для отказоустойчивости можно развернуть несколько одинаковых микросервисов в Kubernetes, каждый из который будет опрашивать все сервисы. Тогда при отказе одного из микросервисов, остальные разделят нагрузку упавшего микросервиса между собой. |
| Services GOlang | Graceful Shutdown [37]2. Передать сигнал о завершении работы нескольким горутинам 3. Дожидаемся выхода всех запущенных горутин 4. Завершаем работу сервиса |
В случае отказа части системы, сервисы могут продолжать работать с ограниченным функционалом, обеспечивая минимальную работоспособность:
- Резервный поиск - при отказе основного поискового движка (ElasticSearch), система переключается на резервный механизм поиска, использующий другие базы данных (MongoDB). Это обеспечивает возможность пользователям продолжать искать товары с минимальными ограничениями по функционалу и точности.
- Упрощенные рекомендации - при недоступности основного сервиса рекомендаций система отображает базовые варианты: популярные товары или последние добавленные. Это позволяет сохранять минимальный уровень персонализации и поддерживать интерес пользователей даже при сбоях.
- Минимизация данных на странице товара - если недоступны некоторые вспомогательные сервисы (например, сервис комментариев), страница товара загружается с основными данными, такими как описание, цена, наличие, базовые характеристики. Визуально пользователи не замечают отсутствия части контента, что обеспечивает положительный опыт взаимодействия.
Повторные попытки (Retry) - на уровне API Gateway и клиента могут быть настроены повторные попытки запросов, что уменьшает влияние краткосрочных сбоев. Если основной запрос не прошел, то отправляем еще максимум 2 retry запроса, иначе есть риск положить систему под нагрузкой. Если все же запросы не проходят возвращаем тыкву.
- Мониторинг - использование инструментов, таких как Prometheus, Grafana, и InfluxDB, для сбора и визуализации метрик, отслеживания состояния системы и мониторинга производительности.
- Алертинг - настройка уведомлений и алертов позволяет оперативно реагировать на возникающие проблемы. Также важно использовать логирование с уникальными request id для трассировки запросов и диагностики проблем.
- Профилирование и тестирование - регулярное профилирование системы помогает выявлять узкие места и улучшать производительность. Проводятся регулярные тренировки, например, отключение одного из ЦОД, чтобы убедиться в способности системы справиться с возможными сбоями.
- Kafka - использование этой технологии для обеспечения согласованности данных и координации транзакций между микросервисами в распределенной среде.
- CQRS и Backend for Frontend - изоляция логики и разделение операций чтения и записи помогает улучшить производительность и снизить нагрузку на базу данных.
Стандарт отказоустойчивости датацентров выберем TIER III. TIER III датацентры гарантируют 99,982% доступность, что означает менее 1,6 часов простоя в течение года. Хотя уровень TIER IV может предложить еще большую отказоустойчивость, он также влечет за собой значительно большие затраты. TIER III предлагает хороший баланс между отказоустойчивостью и стоимостью
Ссылка на схему: https://boardmix.com/app/share/CAE.CNvJQCABKhAX5eV3HmdNcBJ_RObnTwYZMAZAAQ/yAB7TV?elementNodeGuid=6:290
На официально сайте nginx видно, что сервер с 16 CPU видерживает 77 427 HTTP RPS
Данные:
- Пиковое значение по RPS для всего трафика: 19505 RPS
- Пиковое значение сетевого трафика: 2.5 Гбит/с Расчет по RPS: 1 сервер Nginx с 16 CPU поддерживает 77 427 RPS. Для расчета количества серверов по RPS:
19 505RPS / 77 427RPS = 0.25 серверов
Округляем до 1 серверa. Расчет по сетевому трафику: 1 сервер может обрабатывать до 40 Гбит/с. Для сетевого трафика:
2.5Гбит/с / 40Гбит/с = 0.06 серверов
Округляем до 1 сервера. Таким образом, для веб-сервера Nginx потребуется 1 сервера (по RPS). При расчёте количества на один ДЦ учтём, что для каждого сервера необходимо иметь 1 резервный. С учетом 4 ДЦ получаем следующее распределение:
| Параметр | Значение |
|---|---|
| CPU | 16 |
| Network | 40 ГБит/с |
| Кол-во | 8 |
Для работы с данными нам потребуется настроить несколько баз данных:
- Redis - используется для хранения сессий (in-memory). 9 серверов (3 master + 6 replicas), с учетом 58.6 млн пользователей.
- ClickHouse - для аналитики и быстрого чтения больших данных. Подойдет кластер из 8 серверов (16 CPU, 64 GB RAM).
- ElasticSeacrh - для полнотекстового поиска по товарам и компаниям. С учетом индексации больших данных потребуется 7 серверов.
- Kafka - для обработки событий. Требуется кластер Kafka, предполагаем ~12 брокеров для обработки событий в реальном времени.
- AWS S3 - 20 серверов с дисками объемом 10 ТБ.
- InfluxDB - для InfluxDB потребуется кластер из 9 серверов (3 master + 6 реплик)
- MongoDB. 9 серверов на ДЦ (3 master + 6 replicas)
Рассчитаем количество RAM необходимое для хранения индексов:
| Сервис | Название индекса | Размер индекса (Byte) | Количество | RAM (GB) |
|---|---|---|---|---|
| Profile | id phone_number |
16 19 32 |
100 * 10^6 | 6,24 |
| Session | token profile_id last_access |
32 16 4 |
56 * 10^6 | 2,71 |
| Seller_Product | profile_id product_id |
16 16 |
400 * 10^3 250 * 10^6 |
0,00596 3,73 |
| Profile_To_Profile | profile_recipient | 16 | 50 * 10^6 | 0,74506 |
| Rating_Seller | profile_id | 16 | 50 * 10^6 | 0,74506 |
| Comment | profile_id product_id |
16 16 |
22 * 10^6 250 * 10^6 |
0,32783 3,73 |
| Product | id | 16 | 250 * 10^6 | 3,73 |
| Rating_Product | product_id | 16 | 250 * 10^6 | 3,73 |
| Shopping_Cart | profile_id | 16 | 911 * 10^6 | 13,57 |
| Order_Item | profile_id track_number |
16 64 |
100 * 10^6 80.5 * 10^6 |
1,49 4,8 |
| List_Pick-up | city street |
16 64 |
16 * 10^3 16 * 10^3 |
0,00024 0,00095 |
Всего требуемого RAM = 45.555 GB Возьмем коэффициент запаса 1.1 для бизнес логики. Тогда нам необходимо 50,11 GB
| База данных | Серверы | CPU (на сервер) | RAM (на сервер) | ROM (на сервер) | Итого серверов с резервированием | Итого серверов на все ДЦ |
|---|---|---|---|---|---|---|
| MongoDB | 9 | 64 | 64 GB | 5 TB | 18 | 72 |
| Redis | 9 | 16 | 32 GB | 20 GB | 18 | 72 |
| InfluxDB | 9 | 32 | 64 GB | 10 TB | 18 | 72 |
| ClickHouse | 8 | 16 | 64 GB | 10-20 TB | 16 | 64 |
| Elasticsearch | 7 | 16 | 64 GB | 2 TB | 14 | 56 |
| Kafka | 12 | 16 | 64 GB | 2 TB | 24 | 96 |
| AWS (S3) | 20 | 64 | 64 GB | 10 TB | 40 | 160 |
| Итого | 74 | - | - | - | 148 | 592 |
- При выборе разных конфигурации сервисов
Коэффициент запаса возьмем 1.4 (на случай отказа одного ДЦ из четырех) В зависимости от сложности сервиса, он будет занимать разное количество ресурсов. К примеру сервис Session, в котором содержится легкая бизнес логика (достать значение по id) должен пропускать много запросов, но занимать не так много RAM, а сервис Search наоборот имеет более тяжелую бизнес логику (кэш + ElasticSearch + ML), и ему требуется больше CPU и RAM Таблица на составлена с расчетом на 1000 RPS
| Уровень бизнес логики | RAM Mb | CPU |
|---|---|---|
| Легкая | 20 | 10 |
| Средняя | 100 | 20 |
| Тяжелая | 1000 | 40 |
| Сервис | RPS | Уровень бизнес логики | Коэффициент (RPS/1000) | Коэффициент с запасом 1.4 | RAM (Гб) | Network (Гб/с) | CPU |
|---|---|---|---|---|---|---|---|
| Session | 6 030 | Легкая | 6.03 | 8.442 | 0.165 | 2.5 | 85 |
| Profile | 4 | Легкая | 0.004 | 0.0056 | 0.0001 | 0.004 | 1 |
| SallerProduct | 486 | Легкая | 0.49 | 0.686 | 0.013 | 0.0056 | 7 |
| Comment | 1 944 | Легкая | 1.94 | 2.716 | 0.053 | 0.432 | 28 |
| ProxyServer Nginx&&Kafka | 19 505 | Легкая | 19.5 | 27.3 | 0.533 | 4.37 | 273 |
| ShoppingCart | 3 111 | Средняя | 3.1 | 4.34 | 0.424 | 1.832 | 87 |
| OrderItem | 738 | Средняя | 0.74 | 1.036 | 0,101 | 0.24 | 21 |
| Product | 11 668 | Средняя | 11.67 | 16.338 | 1.6 | 1.84 | 327 |
| AppIndever | 486 | Средняя | 0.49 | 0.686 | 0.067 | 0.0056 | 14 |
| Search | 1 555 | Тяжелая | 1.56 | 2.184 | 2.13 | 0.0156 | 88 |
Всего 931 CPU
- При выборе общей конфигурации сервисов
- По данным с конференции Saint HighLoad++ 2024, для сервисов на Golang среднее значение RPS на 1 CPU может составлять примерно 50 RPS [38]
- RAM считаем из расчета 100 RPS на 100 RAM
- Net в среднем 5 Mb (RAM) = 1 Mbit/s
| Сервис | RPS | CPU | RAM | Net |
|---|---|---|---|---|
| Session | 6030 | 121 | 10 Gb | 1 Gbit/s |
| Profile | 4 | 1 | 10 Mb | 1 Mbit/s |
| SallerProduct | 486 | 10 | 500 Mb | 100 Mbit/s |
| Comment | 1944 | 39 | 2 Gb | 500 Mbit/s |
| ShoppingCart | 3111 | 63 | 3 Gb | 1 Gbit/s |
| OrderItem | 738 | 15 | 700 Mb | 100 Mbit/s |
| Product | 11668 | 234 | 11 Gb | 2 Gbit/s |
| Search | 1555 | 31 | 1.5 Gb | 500 Mbit/s |
| AppIndever | 486 | 10 | 500 Mb | 100 Mbit/s |
| ProxyServer Nginx&&Kafka | 25280 | 506 | 25 Gb | 5 Gbit/s |
Всего 1030 CPU
В системе будет использоваться оркестрацией Kubernetes
Kubernetes это система оркестрации контейнеров которая автоматизирует развертывание облачных приложений упакованных в Docker-контейнеры. Вы указываете количество экземпляров сервиса, требования по распределению экземпляров по датацентрам и система следит за парков ваших сервисов переселяя их с упавших машин на другие. Общение между сервисами происходит при помощи service discovery потому что приложения постоянно переезжают между машинами меняя IP-адреса и порты.
Оркестрация позволяет повысить плотность упаковки сервисов за счет overcommitment и минимизировать количество оборудования необходимое для обеспечения отказоустойчивости. При этом механизм изоляции контейнеров друг от друга предотвращает большинство потенциальных проблем по сравнению с разветыванием неконтейнеризированных приложений.
Достоинства: самая низкая удельная стоимость ресурса Недостатки: добавление ресурсов связано с закупками и занимает месяцы Рекомендуется для крупных проектов с хорошо прогнозируемым профилем нагрузки.
При выборе общей конфигурации сервисов:
| Сервис | CPU/r | CPU/l | RAM/r | RAM/l | Cnt |
|---|---|---|---|---|---|
| Session | 8 | 16 | 8 Gb | 32 Gb | 25 |
| Profile | 8 | 8 | 4 | 16 | 2 |
| SallerProduct | 8 | 8 | 8 | 32 | 5 |
| Comment | 8 | 16 | 16 | 32 | 10 |
| ShoppingCart | 16 | 16 | 16 | 32 | 20 |
| OrderItem | 8 | 8 | 8 | 16 | 5 |
| Product | 32 | 32 | 64 | 128 | 375 |
| SearchService | 8 | 16 | 16 | 32 | 15 |
| ProxyServer Nginx&&Kafka | 32 | 32 | 32 | 32 | 790 |
| AppIndever | 8 | 8 | 8 | 32 | 5 |
- Для начала заметим что некоторый сервисы можно развернуть по парно на общих серверах (для экономии). К примеру можно собрать следующие пары:
- (OrderItem и AppIndever) - занимают 35 CPU и 0.168 Гб RAM
- (Profile, SallerProduct и Comment) - занимают 36 CPU и 0.0661 Гб RAM
- Session, ShoppingCart и Search занимает больше места, поэтому на каждый сервис выделим два сервера
- Большая нагрузка ляжет на сервисы Product и ProxyServer Nginx&&Kafka на них выделим по 6 и 5 сервера соответственно С учетом 2 реплик на каждый сервис в 4 ДЦ получаем: 19 * 2 * 4 = 152
| Название | Хостинг | Конфигурация [40] | Cores | Cnt | Покупка (руб) | Аренда (месяц руб) |
|---|---|---|---|---|---|---|
| kubenode | У себя | Платформа: 2x 3G Xeon Scalable(270W)/32D, 12x3.5/2.5 SATA/SAS/NVMe(4), 8xPCIe, 1300/1600/2100W(0/2) Процессоры: Xeon Gold 6338N 2.2/3.5 GHz, 32C/64T, 48 MB L3, DDR4-2667/6.0 TB, 11.2 GT/s UPI(3), 185 W Оперативная память: 32 GB Kingston DDR4-3200 Single Rank x4 CL22 1.2v ECC Registered DIMM, Server Premier (637 500 руб.) |
64 | 152 | 96 900 000 | 11 400 000 руб (75 000 руб на 1 сервер) |
Окупаемость за 8.5 лет
- https://pro.similarweb.com/#/digitalsuite/websiteanalysis/overview/website-performance/*/999/1m?webSource=Total&key=ozon.ru
- https://oborot.ru/news/kolichestvo-posetitelej-marketplejsov-wildberries-i-ozon-v-mesyac-sravnyalos-kuda-eshhe-hodyat-pokupateli-i209527.html
- https://adindex.ru/news/researches/2023/02/28/310879.phtml
- https://dzen.ru/a/ZkT8wKCKkBgtJMT-
- https://oborot.ru/news/oborot-sellerov-na-ozon-vyros-v-23-raza-skolko-u-marketplejsa-vyruchki-prodavcov-pokupatelej-i-zakazov-na-nachalo-2024-goda-i211081.html
- https://sberbusiness.live/publications/kak-pokupateli-ischut-tovar-na-marketpleisah-issledovanie-mediascope
- https://new-retail.ru/business/e_commerce/issledovanie_78_pokupateley_predpochitayut_izuchat_otzyvy_na_marketpleysakh/
- https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/mp_l3_vpns/configuration/xe-3s/asr903/16-12-1/b-mpls-l3-vpns-xe-16-12-asr900/b-mpls-l3-vpns-xe-16-11-asr900_chapter_0101.pdf
- https://www.cncf.io/blog/2023/03/15/linkerd-and-ingress-controllers-bringing-the-outside-world-in/
- https://www.kubecost.com/kubernetes-devops-tools/istio-envoy/
- https://linkerd.io/
- https://linkerd.io/2016/03/16/beyond-round-robin-load-balancing-for-latency/
- https://habr.com/ru/companies/ozontech/articles/558926/
- https://habr.com/ru/companies/vk/articles/347026/
- https://timeweb.cloud/tutorials/servers/kak-nastroit-balansirovku-nagruzki-s-pomoshchyu-nginx
- https://www.ibm.com/docs/en/cics-ts/6.x?topic=performance-ssl-handshake-overhead
- https://ir.ozon.com/upload/iblock/e8c/wq4m20pyvx913k169ipher3fjt4daho4/Ozon%20объявляет%20финансовые%20результаты%20за%20второй%20квартал%202024%20г..pdf
- https://www.interfax.ru/business/945968
- https://vc.ru/u/2023081-slava-gavrilenko/778277-kak-chasto-klienty-ostavlyayut-otzyvy-na-marketpleisah-ozon-wildberries
- https://betapro.ru/blog/Marketplejs-Ozon-instrumenty-poiska-tovarnoj-kategorii/#:~:text=Маркетплейсы%20позиционируют%20себя%20как%20универсальные,февраля»%2C%20«8%20марта»%20и%20др
- https://telegra.ph/Skolko-mozhet-lezhat-tovar-v-korzine-na-ozon-Vse-chto-nuzhno-znat-o-srokah-hraneniya-tovarov-na-Ozon-ot-korziny-do-punkta-vydach-08-28
- https://www.retail.ru/news/ozon-i-wildberries-uvelichili-chislo-pvz-na-23-i-67-za-god-13-dekabrya-2022-223746/
- https://habr.com/ru/articles/217393/
- https://habr.com/ru/companies/nixys/articles/805463/
- https://habr.com/ru/companies/galssoftware/articles/547000/
- https://habr.com/ru/articles/571138/
- https://habr.com/ru/articles/140893/
- https://www.geeksforgeeks.org/backup-and-restore-procedure-for-elasticsearch-data/
- https://www.delftstack.com/howto/mongodb/mongodb-shutdown/#:~:text=If%20MongoDB%20is%20running%20as,stop%20automatically.%20the%20kill%20Command
- https://www.geeksforgeeks.org/how-can-i-stop-redis-server/
- https://kb.objectrocket.com/elasticsearch/how-to-shut-down-elasticsearch
- https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/high_availability_origin_failover.html
- https://clickhouse.com/docs/ru/sql-reference/statements/system
- https://bitworks.software/2019-03-16-improving-influxdb-with-apache-kafka.html
- https://bigdataschool.ru/blog/news/kafka/kafka-graceful-shutdown.html
- https://habr.com/ru/companies/vk/articles/654471/
- https://habr.com/ru/articles/771626/
- https://highload.ru/spb/2024/abstracts/11368
- https://habr.com/ru/articles/790326/
- https://www.team.ru/server/server_intel_builder.php?model=R2000CY&platform=M50CYP2UR312










