Skip to content

Fedasov/Highload_Ozon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Highload_Ozon

Расчетно-пояснительная записка к курсовой работе по дисциплине "Проектирование высоконагруженных систем" Образовательный центр VK x МГТУ им.Н.Э.Баумана (ex. "Технопарк")

Содержание

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

Маркетплейс Ozon - платформа, на которой продавцы могут размещать свои товары для продажи, а покупатели — приобретать их. Маркетплейс имеет широкий ассортимент товаров и предлагают удобные условия для покупки.

Определение функционала MVP

  1. Регистрация и авторизация пользователей.
  2. Поиск товаров по ключевым словам.
  3. Просмотр информации о товарах, включая описание, характеристики, цены и отзывы.
  4. Комментарий приобретённых товарах.
  5. Добавление товара в корзину
  6. Редактирование списка в корзине товаров.
  7. Выбор пункта доставки
  8. Оформление заказа
  9. Выложить товар на продажу (продавец)
  10. Трэккинг посылок

Целевая аудитория

Аудитория сайта достаточно широкая и разнообразная, но, преобладающее большинство мужчины. [1]
Размер целевой аудитории: 58.6 млн. пользователей в месяц, 21.0 млн. пользователей в день на момент февраля 2024г. [2]
Гендерное распределение
image

Возрастное распределение
image

География аудитории иаркетплейс Ozon
image Можно сделать следующие выводы:

  • Преобладающее большинство пользователей мужчины
  • Доминирующий возраст 25-34 года
  • 95% пользователей из России

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

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

Метрика Значение
Месячная аудитория 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. Поиск товаров:
  • 1.6 запроса/день. Примерный объем одного запроса можно оценить в 10 кБ (запрос + ответ от сервера). Итого: 1.6 ∗ 10 кБ = 16 кБ
  1. Оставление отзывов:
  • 2 отзыва/день, 467.72 кБ (как рассчитано ранее). Итого: 467.72 кБ
  1. Добавление товаров в корзину:
  • 3.1 товара/день. Объем данных на один товар — 3.1 * (6.3 кБ + 7 фото * 86 кБ) = 1885.7 кБ (как уже рассчитано). Итого: 1885.7 кБ
  1. Оформление заказа:
  • 0.13 заказ в день с 3 товарами. Итого: 3 товара * 0.13 * (6.3 кБ + 7 * 86 кБ) = 237.24 кБ. Итого: 237.24 кБ
  1. Трэккинг посылок:
  • 0.5 запрос/день. Примерный объем одного запроса можно оценить в 10 кБ (запрос + ответ от сервера). Итого: 0.5 * 10 = 5 кБ
  1. Добавление товаров продавцом:
  • 0.5 товаров/день. Примерный объем одного запроса можно оценить в 0.5 товаров/день * (6.3 кБ + 7 * 86 кБ) = 304.2 кБ. Итого: 304.2 кБ
  1. Трафик на одного пользователя в день:
  • 16 кБ + 1885.7 кБ + 237.24 кБ + 5 кБ = 2143.9 кБ ≈ 2.1 МБ
  1. Открытие карточки товара:
  • 10 товаров/день и 17 отзывов для каждого товара, 73.2 кБ (как рассчитано ранее). Итого: 73.2 кБ

Сетевой трафик по видам активности (дневная аудитория 21.0 млн. пользователей):

Пиковое значение активности пользователей(соответственно 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

RPS

  • Регистрация и авторизация пользователей: 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

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

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

Будем считать, что домены по типу www.ozon.com работает на раздачу фронтенда, а бекенд распределён по поддоменам, которые будут рассмотрены далее.

  • ozon.ru
    Основной домен для российского сегмента Ozon, предоставляющий доступ к основному функционалу платформы.
    img_4.png
  • ozon.com
    Домен для международной версии Ozon, ориентированной на аудиторию за пределами России.
    img_3.png
  • ozon.kz
    Домен для казахстанского сегмента Ozon, адаптированный под особенности местного рынка.
    img_1.png
  • ozon.by
    Домен для белорусского сегмента Ozon, адаптированный под потребности белорусского рынка.
    img_2.png

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

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 расположены там же. Таким образом, при таком списке мы получим снижение латентности и улучшим доступность платформы.

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

Так как сервис находится преимущественно в рамках одной страны, то в качетсве балансировки будет использоваться роутинг. За счёт географических масштабов проекта здесь будет применяться GeoDNS В итоге, клиентский трафик заводится в 4 ЦОД через BGP Anycast. Далее посредством Equal-cost multi-path routing (ECMP) попадает на несколько LoadBalancer c защитой от DNS- и DoS-атак. ECMP роутинг может использоваться в сочетании с BGP, использования этой стратегии маршрутизации, при которой пакеты пересылаются по нескольким «лучшим путям», увеличивает пропускную способность сети.

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

Рассмотрим настоящую архитектуру Ozon [13]:

Согласно докладу разработчиков из Ozon, их система балансировки нагрузки устроена следующим образом:

  1. Уровень GeoDNS-балансировки - используется для распределения трафика между несколькими дата-центрами
  2. Уровень L4-балансировки - используется внутри каждого дата-центра для распределения трафика между серверами. Основано на использовании программных балансировщиков на базе NGINX.
  3. Уровень L7-балансировки - применяется для распределения трафика между различными сервисами внутри Ozon. Реализовано на базе программных балансировщиков NGINX. Для системы, в которой все построенно на микросервисах, такой подход более чем оправдан. В итоге получается такая схема работы:

Рассмотрим несколько балансировок [14]

  • DNS-балансировка: имеет низкую нагрузку на сеть, но не подходит из-за высокой вероятности длительных соединений и необходимости быстрой реакции на изменения в инфраструктуре
  • L4-балансировка: может использоваться для базовой балансировки, но не подходит для сложных сценариев, так как имеет ограниченные возможности по управлению сессиями, также нет поддержки сложных протоколов
  • L7-балансировка: наиболее подходящий вариант для маркетплейма Ozon. Позволяет эффективно распределять нагрузку, управлять сессиями пользователей, оптимизировать трафик и реализовать дополнительные функциональные возможности, однако из минусов есть высокая сложность настройки и потенциально более низкая производительность.

Выбранный способ балансировки

На уровне локальной балансировки будем использовать только L7 балансировку. В архитектуре не будет использоваться L4, так как в данном сценарии этот уровень избыточен. L7 балансировку будем использовать два веб-сервера Nginx для отказоустойчивости (паттерн Active-Passive).
Вывод: L7-балансировка. Для Ozon, как крупного маркетплейса с высокой нагрузкой и сложной архитектурой приложения, наиболее подходящим вариантом будет L7-балансировка. Она предоставляет необходимую гибкость, возможность учета особенностей приложения и реализации сложных сценариев маршрутизации трафика. L7-балансировщик позволяет привязывать пользователя к определенному серверу, обеспечивая более стабильное соединение и упрощая обработку контекста пользователя. Также часто используемые данные могут быть кэшированы на уровне балансировщика, что снижает нагрузку на бэкенд-серверы и ускоряет ответ. К тому же L7 балансировщики хорошо интегрируются с Kubernetes.

Методы балансировки нагрузки [15]

Популярные алгоритмы распределения трафика:
img_8.png
Выбор: Round Robin. Так как это простой и легковесный алгоритм + легко масштабируется.

  • Алгоритм Round Robin

Существует довольно много методов балансировки. Nginx по умолчанию использует алгоритм Round Robin. Он довольно прост. Допустим, у нас есть приложения 1, 2 и 3. Балансировщик нагрузки отправит первый запрос на первое приложение, потом на второе, на третье и опять на первое

1 запрос 2 запрос 3 запрос 4 запрос
img_3.png img_4.png img_6.png img_7.png


Чтобы избежать простоя серверов, можно использовать некоторый числовой приоритет. У каждого сервера появляется свой вес, который определяет, как много трафика распределяется на конкретный экземпляр приложения. Таким образом мы гарантируем, что более мощные серверы получат больше трафика.

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

Для отказоустойчивости будут применяться инструменты 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 секунд вычислительного времени.

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

normalized_database_schema.png
Вы можете перейти по ссылке чтобы подробнее изучить схему бд: 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 Тб

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

Денормализованная схема БД

denormalized_database_schema.png

Выбор БД:

Для хранения данных будем использовать 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
email
ускорить поиск пользователей по 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
для ускорения по местоположению

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

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

  1. MongoDB [23]:
  • Шардирование по товарам (Product, Comment): Шардирование по product_id. Это позволит распределить нагрузку, так как данные товаров (включая продавцов и отзывы) часто запрашиваются вместе.
  • Шардирование заказов (Order_Item): Шардирование по profile_id, чтобы распределить нагрузку между пользователями. История заказов обычно запрашивается индивидуально.
  • Репликация: Для MongoDB имеет смысл настроить мастер-репликацию для обработки запросов. Все операции записи, удаления, обновления, попадают в мастер (primary), а затем записываются в специальную коллекцию oplog, откуда асинхронно попадают на реплики — repl.1 и repl.2 (secondary). Таким образом происходит дублирование данных. Зачем это нужно?
    • Избыточность обеспечивает безопасность данных
    • Мастер и реплики могут располагаться в разных дата центрах
    • Реплики могут использоваться для более эффективного чтения данных

mongoDB_shard.jpg 2) Redis [24]:

  • Репликация: Master-slave репликация для Redis для обеспечения отказоустойчивости. redis_rep.png
  1. Elasticsearch [25]:
  • Шардирование: Elasticsearch поддерживает внутреннее шардирование, которое можно настроить на уровне конфигурации. Рекомендуется шардировать по ключевым полям поиска (например, по title). elasticsearch_shard.png

Клиентские библиотеки:

  1. MongoDB: Для работы с MongoDB в Go часто используют следующие библиотеки:
  • Go MongoDB Driver: Официальный драйвер MongoDB для Golang.
  • Mgo: Это неофициальная библиотека, которую также часто используют, хотя развитие остановилось в 2018 году.
  1. Redis: Для интеграции с Redis в Go можно использовать следующие библиотеки:
  • go-redis: Самая популярная библиотека для работы с Redis в Go. Поддерживает основные команды Redis, работу с кластерами и транзакциями.
  1. Elasticsearch: Для работы с Elasticsearch в Go можно использовать клиентскую библиотеку, разработанную самими разработчиками Elasticsearch:
  • Elastic Go Client: Официальный клиент для работы с Elasticsearch, поддерживает все основные функции Elasticsearch.
  1. AWS S3: Для работы с AWS S3 можно использовать официальный SDK от AWS для Go:
  • AWS SDK for Go: Поддерживает работу с S3 и другими сервисами AWS.

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

  1. MongoDB [26]:
  • Использование mongodump для регулярного создания бэкапов базы данных. Бэкапы сохраняются на удаленный сервер или в облачное хранилище (например, S3). Будем производить резервное копирование всех баз данных с сжатием в один архив(.gz) mongodump --gzip --archive=/tmp/backup/mybackup.gz
  1. Redis [27]:
  • Redis поддерживает сохранение снимков данных через RDB (Redis Database Backup) и AOF (Append Only File). RDB можно использовать для периодических полных бэкапов, а AOF для сохранения журнала операций.
  1. Elasticsearch [28]:
  • Использование встроенной системы снапшотов Elastic для регулярных бэкапов данных в удаленное хранилище (например, S3).
  1. AWS S3: Файлы на S3 защищены встроенной системой версионирования и высокой доступностью. Рекомендуется использовать Glacier для долгосрочного хранения архивных данных.

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

7. Алгоритмы

1. Этап Retrieval

Описание:

На этом этапе осуществляется поиск всех потенциально релевантных товаров по запросу пользователя. Используем технологии как ElasticSearch для быстрого и точного поиска.

Этапы:

1. Text Preprocessing:

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

2. Этап чтение из кэша:

Перед тем как попасть в главный поиск по ключевым словам и метрикам, все запросы обращаются в Redis. Для быстрого ответа, если в кэше есть подходящее для нас значение.

3. Этап Retrieval && Ranking в ElasticSearch:

ElasticSearch не обладает встроенным механизмом индексации. Одним из ключевых вызовов является обеспечение трансляции обновлений к поисковому индексу в режиме реального времени. Такие элементы, как цены, ассортимент, наличие товаров на складах и обзоры часто меняются, создавая таким образом массивный приток обновленных записей. Чтобы применить эти обновления в ES, используется инструмент App Indexer. Когда объём индекса достигает определённого предела, App Indexer инициирует процесс его дистрибуции по ES кластеру, используя протокол Peer2Peer. Использование P2P гарантирует, что сетевой канал не будет перегружен, что позволит другим важным бизнес-сервисам работать без сбоев.

  • Все товары индексируются в ElasticSearch (таблица Elastic_Search) по ключевым полям: title, description и category.
  • Преобразование поискового запроса в JSON-формат и отправка его в ElasticSearch.
  • ElasticSearch осуществляет поиск по точным и частичным совпадениям, а также по синонимам и родственным терминам через механизмы, такие как Synonym Filter.
  • Возвращает неупорядоченный список товаров, подходящих под запрос.
  • ElasticSearch использует BM25 для оценки релевантности каждого товара по тексту запроса.
  • Учёт предпочтений пользователя и его истории покупок (таблица Order_Item) для предлагаемой персонализации результатов.

4. Ranking по статистике пользователя

Добавим в нашу схему кластер ClickHouse, в котором будут храниться метрики пользователя:

  • какие поисковые запросы он делал за последнее время
  • какие страницы товаров посещал
  • какие товары откладывал в козину
  • какие товары заказывал

На основе этих данных обучается модель StatisticML. В данную модель передаются данные, которые были получены из ElasticSearch. А на выходе получаем полностью упорядоченный по релевантности список товаров.

Shema_Search.png

Резюме

Алгоритм поиска товаров на маркетплейсе Ozon основан на комбинации текстового и семантического поиска с использованием ElasticSearch, а также последующего ранжирования с учетом релевантности и персонализации.

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

Языки

Технология Область применения Обоснование
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 Персонализация и ранжирование Алгоритм машинного обучения, основанный на градиентном бустинге деревьев решений. Он имеет ряд ключевых преимуществ: высокая производительность, точность, скорость и эффективность.

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

Компонент Способ обеспечения надежности
Nginx

Active-Passive

Для обеспечения отказоустойчивости и минимизации сбоев, Nginx можно развернуть в виде 2 экземпляров (паттерн Active-Passive). В случае отказа одного узла, другой инстанс Nginx подхватит обслуживание трафика.

Graceful Shutdown

Отправить сигнал SIGQUIT в основной процесс Nginx. Этот сигнал приведёт к "мягкому" завершению работы - никакие новые запросы не будут приняты, но все текущие запросы будут обработаны до конца.
Команда: nginx -s quit
После того как все активные соединения завершатся, основной процесс Nginx остановится.
MongoDB

Master-Slave

Для MongoDB имеет смысл настроить мастер-репликацию для обработки запросов. Все операции записи, удаления, обновления, попадают в мастер (primary), а затем записываются в специальную коллекцию oplog, откуда асинхронно попадают на реплики.

MongoDump

Использование MongoDump для регулярного создания бэкапов базы данных. Бэкапы сохраняются на удаленный сервер или в облачное хранилище (например, S3). Будем производить резервное копирование всех баз данных с сжатием в один архив(.gz) mongodump --gzip --archive=/tmp/backup/mybackup.gz

Graceful Shutdown [29]

1. Используйте mongo shell или другую MongoDB client library
2. Используйте команду use admin db.shutdownServer()
Системы с использованием systemd: sudo systemctl stop mongod
Системы с использованием SysV Init: sudo service mongod stop
Redis

Master-Slave && Sentinel

Redis поддерживает репликацию master-slave и может использовать Redis Sentinel для автоматического обнаружения сбоев. Sentinel также управляет failover-процессом, что позволяет переключаться на резервный инстанс Redis при отказе master

RDB && AOF

Redis поддерживает сохранение снимков данных через RDB (Redis Database Backup) и AOF (Append Only File). RDB можно использовать для периодических полных бэкапов, а AOF для сохранения журнала операций. Это не гарантирует полное сохранение всех данных, но обеспечивает высокую производительность. Если полетит база с горячими данными (а именно для этого и нужен redis), то master MongoDB поляжет под кучей запросов. Поэтому если даже redis'у станет плохо, то мы сможем восстановить данные путём резервирования

Graceful Shutdown [30]

При вызове команды SHUTDOWN, Redis позаботится о следующих вещах перед тем, как полностью остановиться:
1. Персистентность на диск: если включено RDB или AOF, Redis убедится, что данные были полностью записаны на диск. В случае с AOF, Redis перезапишет AOF файл, чтобы минимизировать размер файла и упростить его последующую загрузку.
Завершение клиентских соединений: Redis отключит все клиентские соединения перед полной остановкой.
Можно использовать следующую команду: redis-cli shutdown
ElasticSearch

Master-Master

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

Backup

Использование встроенной системы снапшотов Elastic для регулярных бэкапов данных в удаленное хранилище (например, S3).

Graceful Shutdown [31]

Если узел запущен из терминала, просто необходимо нажать CTRL + C, чтобы завершить работу ElasticSearch. В другом случае можно исключить узел из списка выдаваемых узлов с помощью URL: curl -XPUT localhost:9200/_cluster/settings -d '{"transient" :{"cluster.routing.allocation.exclude._ip" : "10.0.0.1"} }';echo
AWS S3

CloudFront origin [32]

Можно настроить CloudFront с автоматическим переключением на резервный источник для сценариев, требующих высокой доступности. Необходимо создать группу источников с двумя источниками: основным и резервным. Если основной источник недоступен или возвращает определенные коды состояния HTTP-ответа, указывающие на сбой, CloudFront автоматически переключается на резервный источник

Glacier

Файлы на S3 защищены встроенной системой версионирования и высокой доступностью. Рекомендуется использовать Glacier для долгосрочного хранения архивных данных.
ClickHouse

ReplicatedMergeTree

Репликация работает в рамках одного шарда на уровне таблиц, которые были созданы используя семейства движков ReplicatedMergeTree. На каждом шарде, репликация работает независимо от других шардов.

Graceful Shutdown [33]

1. В первую очередь, вы можете попробовать остановить службу ClickHouse при помощи системного менеджера служб sudo systemctl stop clickhouse-server Эта команда приказывает следить за активными чтениями и записями и завершить их перед выключением сервера. Однако, прежде чем остановить сервер, ClickHouse ожидает завершения задач на чтение или запись в течение максимум 10 минут по умолчанию
2. Если по каким-то причинам не удается остановить службу, можно отправить сигнал SIGTERM на процесс ClickHouse ```kill -SIGTERM `pidof clickhouse-server```` Этот сигнал будет корректно обработан ClickHouse и процесс остановится после завершения всех активных задач.
InfluxDB

Master-Master [34]

Масштабирование основывается на шардинге данных, который выполняется с помощью разбиения всего множества данных на непересекающиеся группы и применение к ключевым полям алгоритма хэширования, который отображает все множество ключей объектов в множество партиций Kafka. В этой архитектуре мы создаем топик Kafka с набором партиций, количество которых отражает ожидания по производительности – по одной партиции на каждый шард InfluxDB. Каждый шард может быть отказоустойчивым – тогда он состоит из двух серверов InfluxDB, которые реплицируют друг друга.

Graceful Shutdown

Корректно завершить работу можно с использованием системного сервиса systemctl или вручную, отправив сигнал процессу influxd, который управляет InfluxDB sudo systemctl stop influxdb
Kafka

Кластеризация

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

Репликация

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

Graceful Shutdown [35]

Graceful Shutdown в контексте Apache Kafka означает, что Kafka брокер завершает свою работу таким образом, что нет потери сообщений или прерывания обслуживания. Можно использовать следующей команду для Graceful Shutdown брокера Apache Kafka systemctl stop confluent-kafka
Так же можно использовать сценарий инициализации для управления брокером Apache Kafka: /etc/init.d/kafka stop
Kubernetes

Graceful Degradation

Kubernetes поддерживает авто-восстановление подов при сбоях, перезапуская сервисы на доступных узлах. Horizontal Pod Autoscaling обеспечивает автоматическое масштабирование в зависимости от нагрузки. Системы хранения Kubernetes, такие как ETCD, поддерживают регулярные резервные копии, что позволяет восстановить конфигурации при сбоях.

Graceful Shutdown [36]

1. Kubernetes отправляет сигнал SIGTERM в контейнеры в поде. При получении сигнала SIGTERM, приложения должны прекратить принимать новые соединения и завершить обслуживание уже существующих соединений.
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]

1. Завязываем все горутины на одном канале
2. Передать сигнал о завершении работы нескольким горутинам
3. Дожидаемся выхода всех запущенных горутин
4. Завершаем работу сервиса

Graceful Degradation

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

  • Резервный поиск - при отказе основного поискового движка (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 предлагает хороший баланс между отказоустойчивостью и стоимостью

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

Shema_project.png

Ссылка на схему: https://boardmix.com/app/share/CAE.CNvJQCABKhAX5eV3HmdNcBJ_RObnTwYZMAZAAQ/yAB7TV?elementNodeGuid=6:290

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

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

Веб-серверы (Nginx)

На официально сайте 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
email
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

Целевая пиковая нагрузка cервиса с коэффициентом запаса 4 и значение ресурсов

  1. При выборе разных конфигурации сервисов

Коэффициент запаса возьмем 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

  1. При выборе общей конфигурации сервисов
  • По данным с конференции 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 лет

Список источников

  1. https://pro.similarweb.com/#/digitalsuite/websiteanalysis/overview/website-performance/*/999/1m?webSource=Total&key=ozon.ru
  2. https://oborot.ru/news/kolichestvo-posetitelej-marketplejsov-wildberries-i-ozon-v-mesyac-sravnyalos-kuda-eshhe-hodyat-pokupateli-i209527.html
  3. https://adindex.ru/news/researches/2023/02/28/310879.phtml
  4. https://dzen.ru/a/ZkT8wKCKkBgtJMT-
  5. 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
  6. https://sberbusiness.live/publications/kak-pokupateli-ischut-tovar-na-marketpleisah-issledovanie-mediascope
  7. https://new-retail.ru/business/e_commerce/issledovanie_78_pokupateley_predpochitayut_izuchat_otzyvy_na_marketpleysakh/
  8. 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
  9. https://www.cncf.io/blog/2023/03/15/linkerd-and-ingress-controllers-bringing-the-outside-world-in/
  10. https://www.kubecost.com/kubernetes-devops-tools/istio-envoy/
  11. https://linkerd.io/
  12. https://linkerd.io/2016/03/16/beyond-round-robin-load-balancing-for-latency/
  13. https://habr.com/ru/companies/ozontech/articles/558926/
  14. https://habr.com/ru/companies/vk/articles/347026/
  15. https://timeweb.cloud/tutorials/servers/kak-nastroit-balansirovku-nagruzki-s-pomoshchyu-nginx
  16. https://www.ibm.com/docs/en/cics-ts/6.x?topic=performance-ssl-handshake-overhead
  17. https://ir.ozon.com/upload/iblock/e8c/wq4m20pyvx913k169ipher3fjt4daho4/Ozon%20объявляет%20финансовые%20результаты%20за%20второй%20квартал%202024%20г..pdf
  18. https://www.interfax.ru/business/945968
  19. https://vc.ru/u/2023081-slava-gavrilenko/778277-kak-chasto-klienty-ostavlyayut-otzyvy-na-marketpleisah-ozon-wildberries
  20. https://betapro.ru/blog/Marketplejs-Ozon-instrumenty-poiska-tovarnoj-kategorii/#:~:text=Маркетплейсы%20позиционируют%20себя%20как%20универсальные,февраля»%2C%20«8%20марта»%20и%20др
  21. 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
  22. https://www.retail.ru/news/ozon-i-wildberries-uvelichili-chislo-pvz-na-23-i-67-za-god-13-dekabrya-2022-223746/
  23. https://habr.com/ru/articles/217393/
  24. https://habr.com/ru/companies/nixys/articles/805463/
  25. https://habr.com/ru/companies/galssoftware/articles/547000/
  26. https://habr.com/ru/articles/571138/
  27. https://habr.com/ru/articles/140893/
  28. https://www.geeksforgeeks.org/backup-and-restore-procedure-for-elasticsearch-data/
  29. https://www.delftstack.com/howto/mongodb/mongodb-shutdown/#:~:text=If%20MongoDB%20is%20running%20as,stop%20automatically.%20the%20kill%20Command
  30. https://www.geeksforgeeks.org/how-can-i-stop-redis-server/
  31. https://kb.objectrocket.com/elasticsearch/how-to-shut-down-elasticsearch
  32. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/high_availability_origin_failover.html
  33. https://clickhouse.com/docs/ru/sql-reference/statements/system
  34. https://bitworks.software/2019-03-16-improving-influxdb-with-apache-kafka.html
  35. https://bigdataschool.ru/blog/news/kafka/kafka-graceful-shutdown.html
  36. https://habr.com/ru/companies/vk/articles/654471/
  37. https://habr.com/ru/articles/771626/
  38. https://highload.ru/spb/2024/abstracts/11368
  39. https://habr.com/ru/articles/790326/
  40. https://www.team.ru/server/server_intel_builder.php?model=R2000CY&platform=M50CYP2UR312

About

Highload Ozon

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors