Как лучше спроектировать апи с большой нагрузкой?

Необходимо разработать высоконагруженное апи, к которому будут почти нон-стопом обращаться партнерские сервисы. Методы апи будут в основном производить записи в бд: партнер вызвал метод апи -> апи сделало проверки -> апи добавило запись в бд -> вернуло true/false партнеру.

Стек: node.js/express.js/pm2

На что можно обратить внимание при проектировании апи? Какие есть потенциальные узкие горлышки? Интересуют советы как по коду, так и по девопсу. Сейчас мыли такие:
1. Будет 1 серв, на котором будет запущено несколько инстансов апи. Запросы между ними будет распределять балансировщик pm2. Так мы увеличим шанс бесперебойной работы, если 1 инстанс упадет
2. В редисе буду кешировать проверки, чтобы лишний раз не грузить бд
3. В редисе буду помечать выполненные операции, чтобы сразу скипать повторные запросы
4. Писать все данные не в основную бд (бд платформы), а во временную бд апи и раз в N минут/часов сгружать данные в основную бд

Может есть что-то еще, что будет очень полезным? Или может какие-то из моих идей бессмысленные?

Абстрактный пример работы апи:
1. в запросе принимать id юзера, id поста
2. проверять, есть ли в бд есть запись с id юзера и id поста
3. если записи нет, то добавлять в бд
4. прочие инсерты и апдейты в бд, по типу "начислить баллов пользователю (обновить баланс и добавить запись в таблицу user_points_changes)"
и все это в рамках одной транзакции с блокировками строк
  • Вопрос задан
  • 4366 просмотров
Решения вопроса 2
alexey-m-ukolov
@alexey-m-ukolov Куратор тега Веб-разработка
Писать все данные не в основную бд (бд платформы), а во временную бд апи и раз в N минут/часов сгружать данные в основную бд
Гораздо проще использовать нормальный сервер очередей. Вдобавок, данные будут быстрее попадать в БД не вися в отстойнике.
Ответ написан
@rPman
Ты не сообщил самое главное - как будут читаться собираемые данные. Будут ли они считываться и тем более фильтроваться в процессе записи, можно ли вводить запаздывание при чтении данных (например до 'некоторых' данных в прошлом).

Если ничего этого нет, то ничего между базой данных и бакэндом ставить не нужно... таблицы, в которые складываются данные должны быть без индексов, можно ввести искусственное партицирование, например таблица без индексов - последние не обработанные данные, вторая таблица - данные с индексами в которых будет проводиться поиск и анализ, для размазывания нагрузки использовать штатную репликацию базы данных, разные ноды - разные задачи. Кстати один из способов партицирования - писать данные блоками, каждый блок в свою новую таблицу, количество таблиц сравнимо с количеством нод, обрабатывающих их данные (таким образом можно отключить даже транзакции, ведь пока обрабатывается таблица, данные пусть пишутся в следующую, управление таблицами вести тут же на таблицах но уже с транзакциями)

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

Кстати, собственно сбор оперативных данных не обязательно делать в ОДНОЙ физической базе, это могут быть разные БД, а вот последующий анализ уже делать следующим сервисом (так же может быть несколько нод), собирающим данные из разных первичных источников в какой то единый или еще в какой то форме... именно подготовка данных к последующему их использованию и есть вопрос реализации.

Настоятельно не советую городить зоопарк из разных баз данных типа редис и sql-db.. когда sql база используется без индексов (и тем более без транзакций) на последовательную запись у нее нет конкурентов (ну только что совсем низкоуровневым программированием заняться)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы