Как оптимизировать сервер с большим количеством запросом?
Всем добрый день. Я хочу написать свое приложение, по типу секундомера, с сохранением этих данных в бд. И тут встает вопрос, как оптимизировать относительно большое количество запросов исходящих даже от одного пользователя?
То есть, условно, в минуту замер времени может уходить на сервер от 10 раз + к замеру можно давать штрафы - т.е. мутации. Каждый замер времени это новая строка в таблице или новый документ. Как мне не положить сервер с базой, если, условная 1000 человек может генерировать от 10 000 запросов в минуту.
Деление на микросервисы это то что я планирую внедрить, но больше идей именно правильной оптимизации нет. Может для этого стоит выбрать NoSQL базу вместо реляционной или наоборот? Стоит ли для этих целей разворачивать websocket соединение. Может нужно подключать брокер, по типу кафки? Или есть еще какие то верные решения этой задачи. Подскажите пожалуйста начинающему.
Как понял схема данных следующая:
- Есть замер времени - отедльный объект со своим ID
- У каждого замера времени есть список штампов - конкретного времени
- Эти штампы создают пользователи - отправляют запросы
Для данного кейса мне видится такое решение:
- Используем Redis в качестве БД
- Для ID замеров используем snowflake
- Тип данных Redis для замеров - list (список)
- В каждом списке храним эти штампы - строка или unix timestamp (неважно)
Таким образом, на каждый запрос просто добавляем новый элемент в этот список.
Redis хорошо выдерживает высокую нагрузку + его можно масштабировать.
Благодаря snowflake можно горизонтально мастшабировать свои сервисы.
Также, ты указал websocket - здесь как хочешь. Но в .NET есть реализация Redis которая использует мультиплексирование - здесь он будет уместен.
А какую роль выполняет этот snowflake?
Почему просто GUID не использовать? На разных сервисах он точно не совпадёт (т.к. генерируется на основе hwid). А на одном если даже и совпадёт(?), то делать повтор.
Ну или составной ключ (машина+автоинкремент)
Интересная задача, и если прям про высокую нагрузку говорить, то действительно лучше использовать in-memory базу типа Redis как предлагали выше. Для безопасности можно ее периодически копировать в обычную базу на диске.
2йвариант, если хочется меньше заморачиваться - выбрать облачную бд, которую просто масштабируешь под свои нагрузки и не пытаешься вникнуть, как это сделано. Потипу DTU-based бд в Azure.
Ну а само веб приложение - горизонтальное масштабирование, т.е. много экзепляров приложения + балансер нагрузки, которые лезут все в одну и туже базу.
10000 запросов в минуту - это 167 запросов в секунду. Округлим до 200. Т.е. на один запрос дается 5мс.
Простейший sqlite, с файлом на ssd, делает begin;insert;commit; в таблицу без ключей за 0мс.
Если предположить, что СУБД чуть посерьезней чем sqlite, а web сервер многопоточный, то 10000 запросов в минуту он должен проглотить не заметив.
А в общем случае, если предполагается усиленная запись в БД, то таблицу лучше делать без ключей.
10000 в минуту - это не так много, когда доживете до такого, просто запускайте второй сервер на другом поддомене, или перед серверами ставите перенаправлялку, которая новых клиентов гонит на второй сервер
А если использовать long polling? Ну, чтобы каждый раз не отрабатывать новый запрос, вместо этого не отвечать сразу, а дописывать в один запрос новые данные. Получится всего 1 запрос в {время_таймаута_сервера} секунд.