Авито — сервис объявлений, который объединяет продавцов и покупателей. На Авито вы можете недорого купить или выгодно продать авто с пробегом или новую машину, квартиру и другую недвижимость, а также новую или б/у одежду и т.д.
Основной функционал Авито (MVP):
- Разсещение объявлений.
- Поиск объявлений.
- Просмотр объявлений.
- Текстовый чат с продавцом.
- Целевая аудитория
- Расчет нагрузки
- Логическая схема
- Физическая схема
- Технологии
- Схема проекта
- Список серверов
- Источники
Страна | Кол-во посещений за месяц |
---|---|
Россия | 363.5 млн (95%) |
Украина | 8 млн (2.1%) |
Казахстан | 0.9 млн (0.2%) |
Другие | 7.6 млн (2%) |
Всего | 380 млн |
Кол-во уникальных пользователей ~ 50 млн человек
Данные взяты за август 2022 г. с сайта https://www.similarweb.com/website/avito.ru/#traffic
Как видно из таблицы и из тематики сервиса, сервис Avito ориентирован только на российский рынок.
Рассчитаем размер хранилища для пользователя. Основное, что расходует память - объявления. Сейчас на авито размещено 121.898.958 объявлений (https://www.avito.ru/company). Допустим, у каждого объявления есть:
- Описание - 500 символов (500 байт).
- Фотографии - 5 штук. (5 * 1 Мбайт = 5 Мбайт).
- Чат, связанный с объявлением - 1000 символов (1000 байт). Размером хранения текста на фоне фотографий можно принебречь. Получаем, что в среднем 1 объявление занимает 5Мбайт. На авито 50.000.000 активных пользователей, т.е ~ 3 размщенных объявления в среднем у человека. К этому добавим место, занимаемое профилем пользователя и получаем, что хранилище пользователя ~ 20 Мбайт
Метрика | Значение |
---|---|
Месячная аудитория | 380 млн |
Дневная аудитория | 12.3 млн |
Средняя глубина просмотра сайта | 10.93 страниц |
Средняя длительность посещения | 11 минут |
Средняя кол-во объявлений пользователя | 3 объявления |
Средний объем данных пользователя | 20 Мбайт |
Действие | Кол-во (на одного человека/день) |
---|---|
Размещение объявления | 0.008 |
Поиск и просмотр объявлений | 5 |
- Хранение текстовых данных: 50 млн человек * 3 объявления * 1500 байт (округлил с запасом, сюда же можно учесть данные пользователя, оценки, отзывы) = 209 Гбайт.
- Хранение изображений: 50 млн человек * 3 объявления * 5 Мбайт = 730.000 Гбайт = 730 Тбайт.
- Пиковое потребление в течении суток: 13.3 млн посещений * 11 страниц * 5 Мбайт * 2 (коэффициент пиковой нагрузки) / 43200 (секунд в сутках) = 16.5 Гбайт/секунду.
- Суммарный суточный трафик (статика + текст): 13.3 млн посещений * 11 страниц * 1 Мбайт = 142.870 Гбайт = 143 Тбайт
- Суммарный суточный трафик (изображения): 13.3 млн посещений * 11 страниц * 4 Мбайт = 571.480 Гбайт = 571.5 Тбайт
Метрика | Значение |
---|---|
Хранение текстовых данных | 209 Гбайт |
Хранение изображений | 730 Тбайт |
Пиковое потребление в течении суток | 16.5 Гбайт/с |
Суммарный суточный трафик (статика + текст) | 143 Тбайт |
Суммарный суточный трафик (изображения) | 571.5 Тбайт |
- Поиск объявлений: 13.3 млн посещений * 3 поиска / 43200 (секунд в сутках) ~ 1000 RPS
- Просмотр объявлений: 13.3 млн посещений * 7 просмотров / 43200 (секунд в сутках) ~ 2100 RPS
- Размещение объявлений: 400000 объявлений / 43200 (секунд в сутках) ~ 10 RPS
- Отправка сообщений: 400000 объявлений * 5 чатов * 10 сообщений / 43200 (секунд в сутках) ~ 500 RPS
Метрика | RPS |
---|---|
Поиск объявлений | 1000 |
Просмотр объявлений | 2100 |
Размещение объявлений | 10 |
Просмотр чата | 700 |
Отправка сообщений | 500 |
Всего | 3500 |
315 байт/запись (изображения хранятся отдельно) * 50 млн. пользователей ~ 15 Гб
60 байт/запись * 500 категорий ~ 30 Кбайт
1500 байт/запись (изображения хранятся отдельно) * 150 млн. объявлений ~ 225 Гб
24 байт/запись * 500 млн. чатов ~ 12 Гб
120 байт/запись * 500 млн. чатов * 10 сообщений ~ 600 Гб
Анализируя размеры таблиц, шардирование имеет смысл сделать для таблиц "Объявления" и "Сообщения". Все объявления можно условно разделить на несколько крупных категорий.
Группа объявлений | Процент от общего числа |
---|---|
Товары | 40 % |
Недвижимость | 15 % |
Работа и услуги | 20 % |
Автомобили | 15 % |
Другое | 20 % |
Группы этих объявлений не пересекаются, и их вообще можно вынести в отдельные разделы сайта. Поэтому предлагаю шардировать объявления по этим группам. А каждый чат и сообщения в нем также относятся только к одной из этих категорий. Поэтому их имеет смысл шардировать аналогичным способом.
Каждая база данных будет иметь 3 реплики. В Master мы делаем запросы на вставку. Читаем из Slave баз. Такая распростроненная конфигурация позволит надежно хранить данные и иметь достаточную скорость доступа к данным.
5. Технологии
Для бэкенда предлагаю использовать использовать язык Golang и микросервисную архитектуру.
- Популярное решение для современных проектов.
- Высокая производительность (из-за того, что язык компилируемый)
- Встроенные средства параллельного программирования "горутины".
- Быстро разрабатывать код, благодаря сравнительно простому и лаконичному синтаксису.
- Легкая маштабируемость. Использование микросервисной архитектуры позволяет сравнительно легко маштабировать отдельные компоненты системы.
Общение между микросервисами на бэкенде будет осуществляться по протоколу gRPC, данные будут передаваться в формате protobuf.
Redis. Популярное и высокопроизводительное решение для хранения сессий.
- Выдерживает ~ 90000 RPS. источник
Postgres Активно развивающаяся строковая реляционная база данных. Отлично подходит для большого числа небольших запросов чтения и вставки.
- Высокая производительность в сравнении с другими реляционными OLTP БД.
S3 совместимый объектное облачное хранилище. К примеру, VK cloud. Эффективное и общепринятое хранилище для хранение медиаконтента.
- Высокая эффективность (до 5000 rps на чтение)
- Датацентры находятся в России (в непосредственной близости от пользователей) + CDN
React.js является одним из самых популярных фреймворков в последние годы. Высокая производительность, так как он основан на виртуальной модели DOM, а также высокую переиспользуемость компонентов - всё это дает преимущества в выборе при использовании в проектах типа досок объявлений.
Протокол связи между фронтендом и бэкендом - https, данные будут передаваться в формате json.
- Балансировку между nginx серверами будет обеспечивать DNS.
- Балансировку между микросервисами будет осуществлять nginx.
Общий RPS для пользовательских запросов 3500. Кроме пользовательских запросов, nginx балансирует межсервисные взаимодействия, поэтому можем говорить о 10000 RPS на сервер.
Согласно тесту производительности (8), для конфигурации сервера с 4 CPU, nginx обеспечивает производительность на отдачу статики в 19355 RPS.
Для этого сервера нужно обеспечить сетевой канал в 20 Гбит/с, так как в пике рассчетное потребление 16 Гбит/с.
Для отказоустойчивости возьмем 2 сервера.
Параметр | Значение |
---|---|
CPU | 2 ядра |
RAM | 8 ГБ |
Storage | 40 ГБ |
Network | 20 Гбит/с |
Количество | 2 |
Один сервер может выдержать до 15000 RPS (9). Расчетная нагрузка будет 3000 RPS.
Продублируем сервера каждого микросервиса для отказоустойчивости.
Параметр | Значение |
---|---|
CPU | 2 ядра |
RAM | 8 ГБ |
Storage | 40 ГБ |
Network | 1 Гбит/с |
Количество | 8 |
Один сервер может выдержать до 5000 QPS (10).
C учетом шардирования нагрузка на каждую из БД не превышает 1000 QPS.
С текущей физической схемой БД у нас:
Users: 3 реплики
Category: 3 реплики
Chart: 3 реплики
Ads: 5 шардов по 3 реплики в каждом
Message: 5 шардов по 3 реплики в каждом
Итого: 39 баз.
Так как нагрузка на базы значительно ниже нагрузки, которую может выдержать один сервер, предлагаю на одной "машине" располагать по 5 контейнеров с БД.
Получаем 6 серверов.
По сети большой нагрузки не будет, можно взять стандартный канал в 1 Гбит/с.
Максимальный размер хранилища занимают бызы Message ~120 Гбайт (уже с учетом шардирования) и Ads ~ 45 Гбайт.
Параметр | Значение |
---|---|
CPU | 4 ядра |
RAM | 8 ГБ |
Storage | 500 ГБ |
Network | 1 Гбит/с |
Количество | 6 |
Сервер с Redis может выдержать до 70000 RPS, что с запасом превышает наши требования в 3000 RPS.
При этом потребяет много оперативной памяти. Для хранения одной сессии требуется ~ 300 байт. Рассчетная месячная аудитория ~ 30 млн. человек. Получаем 8.5 Гбайт - требуемое количество RAM для хранения сессий.
Для хранения одной записи о просмотрах требуется ~ 50 байт. Рассчетная кол-во активных объявлений ~ 50 млн. Получаем 2.5 Гбайт - требуемое количество RAM для хранения записей о кол-ве просмотров объявлений.
Сессии и просмотры объявлений предлагаю хранить на одном сервере + сервер для отказоустойчивости.
Параметр | Значение |
---|---|
CPU | 2 ядра |
RAM | 16 ГБ |
Storage | 40 ГБ |
Network | 1 Гбит/с |
Количество | 2 |
8. Источники
- https://www.similarweb.com/website/avito.ru/#traffic
- https://www.avito.ru/company
- https://www.vedomosti.ru/forum/riteil22/columns/2022/04/19/918717-nasha-auditoriya-stala--bolee-vovlechennoi
- https://tass.ru/ekonomika/12595407
- https://vc.ru/services/382588-podbiraem-rossiyskie-oblachnye-servisy
- Тест производительности Redis
- https://trends.google.com/trends/explore?cat=5&date=today%205-y&q=React,Angular,Vue,Backbone,Ember
- https://www.nginx.com/blog/testing-the-performance-of-nginx-and-nginx-plus-web-servers/
- https://github.com/smallnest/go-web-framework-benchmark
- https://www.ashnik.com/fine-tuning-postgres-to-achieve-5000-queries-per-second/